2018-10-19 04:07:57 +03:00
|
|
|
|
data EdgeLabel = Lexical | Import
|
|
|
|
|
data EdgeLabel = Lexical | Import | Public
|
|
|
|
|
|
|
|
|
|
-- module A
|
|
|
|
|
-- Scope 1
|
|
|
|
|
function foo() {} -- Declaration
|
|
|
|
|
function b() {} -- Declaration
|
|
|
|
|
export b; -- Create a new scope 2, move declaration b from scope 1 to 2, and make a public edge from scope 1 to 2.
|
|
|
|
|
|
|
|
|
|
-- module 2
|
|
|
|
|
-- Scope 2
|
|
|
|
|
import A; -- Lookup A for associated scope, construct a Public edge to A's scope.
|
|
|
|
|
importEverything A; -- Lookup A for associated scope, construct a Import edge to A's scope.
|
|
|
|
|
|
|
|
|
|
foo
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
|
Import
|
|
|
|
|
1 -->--- 2
|
|
|
|
|
Lexical
|
|
|
|
|
--<---
|
|
|
|
|
Public
|
|
|
|
|
----- 3
|
|
|
|
|
|
|
|
|
|
P∗ ·I(_,_)∗
|
|
|
|
|
P* I(_,_)*
|
|
|
|
|
P* . I(_R,_) . I(_TR,_)*
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
import foo from bar; -- construct a new scope
|
|
|
|
|
|
|
|
|
|
Public -> * -> Public -> *
|
|
|
|
|
-> Import -> *
|
|
|
|
|
|
|
|
|
|
Import -> * -> Public -> *
|
|
|
|
|
-> Import -> *
|
|
|
|
|
|
|
|
|
|
Import -> * -> Public -> *
|
|
|
|
|
-> Import -> *
|
|
|
|
|
|
|
|
|
|
Public . Public
|
|
|
|
|
Public . Public
|
|
|
|
|
. Private
|
|
|
|
|
|
|
|
|
|
-- TypeScript
|
|
|
|
|
|
|
|
|
|
-- Script
|
|
|
|
|
x = 2
|
|
|
|
|
function foo() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-- Module A
|
|
|
|
|
-- Scope 1
|
|
|
|
|
function foo () {} -- declare foo() {}
|
|
|
|
|
function bar() {} -- declare bar() {}
|
|
|
|
|
export { bar }; -- scope 2 Import Scope 1, add a reference to bar
|
|
|
|
|
function baz() {} -- declare baz in scope 2
|
|
|
|
|
|
|
|
|
|
import A; -- Create a Public edge to Scope 1
|
|
|
|
|
module A { -- Scope 1
|
|
|
|
|
function foo () {} -- declare foo -- Scope 2 to scope 1
|
2018-10-20 00:51:42 +03:00
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
function bar() {} -- declare bar -- Scope 3 to Scope 2
|
|
|
|
|
export { foo, bar }; -- Lookup the declaration and create a public edge to scope 2
|
|
|
|
|
function baz() {} -- declare baz in scope 2
|
|
|
|
|
|
|
|
|
|
export { foo } -- create scope 3 add a public edge from scope 1 to 3, add a reference path to foo
|
|
|
|
|
|
2018-10-20 00:51:42 +03:00
|
|
|
|
function lol() {} -- Insert declaration into current scope, create new scope, create edge from new to current
|
|
|
|
|
function lol'() {} -- Insert declaration into current scope, create new scope, create edge from new to current
|
|
|
|
|
lol'()
|
|
|
|
|
function lol''() {}
|
|
|
|
|
* -> Public -> (lol'', (reference to lol')) -> Private -> lol' -> Public -> lol
|
2018-10-19 04:07:57 +03:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-20 00:51:42 +03:00
|
|
|
|
lol'
|
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
import A (foo) ; -- Create a new scope with an Import edge to scope 5
|
|
|
|
|
|
|
|
|
|
(Import | Public)* . Public
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import A (bar, foo); Ghost scope -> Scope 1
|
|
|
|
|
|
|
|
|
|
baz
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isWellFormedPath :: [EdgeLabel] -> Bool
|
|
|
|
|
isWellFormedPath =
|
|
|
|
|
Lexical* . Import*
|
|
|
|
|
Lexical* . Import* . Public
|
|
|
|
|
Lexical* . (Public* | Protected*) Private
|
|
|
|
|
Lexical* . Protected . Import* . Public
|
|
|
|
|
|
|
|
|
|
Lexical* . Protected . Protected -> *
|
|
|
|
|
Lexical* . Protected . Import -> *
|
|
|
|
|
|
|
|
|
|
Lexical* . Import*
|
|
|
|
|
Lexical* . Import*
|
|
|
|
|
Lexical* . Import
|
|
|
|
|
Lexical* . (Public* | Import*)
|
|
|
|
|
|
|
|
|
|
-- Class
|
|
|
|
|
|
2018-10-30 01:08:56 +03:00
|
|
|
|
predicate :: [EdgeLabel] -> Bool -> [EdgeLabel] -> Bool
|
|
|
|
|
predicate =
|
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
class A { -- Scope 1
|
|
|
|
|
public a = 2; -- declare a in scope 1, make a new scope with a public edge to 1
|
2018-10-30 01:08:56 +03:00
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
private b = 3; -- declare b in scope 2, make a new scope with a private edge to 2
|
|
|
|
|
protected c = 4; -- declare c in scope 3, make a new scope with a protected edge to 3
|
|
|
|
|
private d = 3; -- declare b in scope 2, make a new scope with a private edge to 2
|
2018-10-30 01:08:56 +03:00
|
|
|
|
|
|
|
|
|
function e () {
|
|
|
|
|
this.f();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function f () {
|
|
|
|
|
if (true) e();
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-30 01:08:56 +03:00
|
|
|
|
a
|
|
|
|
|
|
|
|
|
|
|
Public
|
|
|
|
|
|
|
|
|
|
|
b
|
|
|
|
|
|
|
|
|
|
|
Private
|
|
|
|
|
|
|
|
|
|
|
c
|
|
|
|
|
|
|
|
|
|
|
Protected
|
|
|
|
|
|
|
|
|
|
|
d
|
|
|
|
|
|
|
|
|
|
|
Private
|
|
|
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
|
|
|
Public
|
|
|
|
|
|
|
|
|
|
|
a
|
|
|
|
|
|
|
|
|
|
|
Private
|
|
|
|
|
|
|
|
|
|
|
b
|
|
|
|
|
|
|
|
|
|
|
Protected
|
|
|
|
|
|
|
|
|
|
|
c
|
|
|
|
|
|
|
|
|
|
|
Private
|
|
|
|
|
|
|
|
|
|
|
d
|
|
|
|
|
|
2018-10-19 04:07:57 +03:00
|
|
|
|
|
|
|
|
|
instance Evaluatable Class where
|
|
|
|
|
eval = do
|
|
|
|
|
...
|
|
|
|
|
withPredicate publicOrProtectedThroughSuperclassesOrAnythingLocal . locally (eval body)
|
|
|
|
|
|
|
|
|
|
class B < A {
|
2018-10-30 01:08:56 +03:00
|
|
|
|
public c;
|
|
|
|
|
private c;
|
|
|
|
|
protected c;
|
2018-10-19 04:07:57 +03:00
|
|
|
|
|
|
|
|
|
class C < D { -- C has a Lexical edge to B and an import edge to D
|
|
|
|
|
withPredicate publicOrProtectedThroughSuperclassesOrAnythingLocal . locally (eval body)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bar() {
|
|
|
|
|
var x = c; lookupDeclaration id (Declaration c) currentScope;
|
|
|
|
|
return c; -- lookupDeclaration id (Declaration name) currentScope
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-20 00:51:42 +03:00
|
|
|
|
-- Inheritance edge predicate
|
2018-10-30 01:08:56 +03:00
|
|
|
|
-- Lexical* . (Private | Protected | Public)* .
|
|
|
|
|
((Private | Protected | Public) | (Import . (Protected | Private | Public)* . (Protected | Public))*)
|
2018-10-20 00:51:42 +03:00
|
|
|
|
-- Instance edge predicate
|
|
|
|
|
-- Import . (Protected | Private)* . Public
|
2018-10-19 04:07:57 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x = new A(); -- Create a scope for x with an import edge to scope 4
|
2018-10-20 00:51:42 +03:00
|
|
|
|
x.c
|
2018-10-19 04:07:57 +03:00
|
|
|
|
|
|
|
|
|
y = new B();
|
|
|
|
|
y.a -- lookupDeclaration onlyLookForPublicThingsThroughSuperclasses (Declaration name) associatedScopeOfY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Scope 1
|
|
|
|
|
package p; -- Declare p with span 1 with associated scope 2
|
|
|
|
|
class C{} -- declare in scope 2 with span 2
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
package p; -- declare p with span 3 with associated scope 3 in scope 1
|
|
|
|
|
class D{}; -- declare in scope 3 with span 4
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
import p;
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package p;
|
|
|
|
|
|
|
|
|
|
import r.*;
|
|
|
|
|
import q.E;
|
|
|
|
|
|
|
|
|
|
public class C {}
|
|
|
|
|
|
|
|
|
|
class D {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
package q;
|
|
|
|
|
|
|
|
|
|
import p.*;
|
|
|
|
|
|
|
|
|
|
C
|
|
|
|
|
|
|
|
|
|
--
|
2018-10-20 00:51:42 +03:00
|
|
|
|
|
|
|
|
|
-- module ModuleWithBar
|
|
|
|
|
-- function bar() {} * Lexical
|
|
|
|
|
|
2018-10-30 01:08:56 +03:00
|
|
|
|
bar
|
|
|
|
|
|
|
|
|
|
|
Lexical
|
|
|
|
|
|
|
|
|
|
|
Import
|
|
|
|
|
*
|
|
|
|
|
|
2018-10-20 00:51:42 +03:00
|
|
|
|
-- module B
|
|
|
|
|
-- import ModuleWithBar * Import
|
|
|
|
|
-- function foo() {} * Lexical
|
|
|
|
|
-- function bar() {} * Lexical
|
|
|
|
|
-- export { foo as bar } * Export -> (Scope (reference to foo) (declaration bar with associated scope foo)) -> :point_up:
|
|
|
|
|
|
|
|
|
|
-- bar -- (Lexical | Export)* . Lexical
|
|
|
|
|
|
|
|
|
|
-- module ModuleWithBar
|
|
|
|
|
-- function bar() {} * Lexical
|
|
|
|
|
|
|
|
|
|
-- module B
|
|
|
|
|
-- import ModuleWithBar * Import
|
|
|
|
|
-- function foo() {} * Lexical
|
|
|
|
|
-- export { foo, bar } * Export
|
|
|
|
|
|
|
|
|
|
-- bar -- (Lexical | Export | Import)* . Lexical
|
|
|
|
|
-- -- ((Lexical | Export)* . Lexical) | (Lexical | Export)* . (Import . (Lexical | Export)* . Lexical)*
|
|
|
|
|
|
|
|
|
|
-- module ModuleWithBaz
|
|
|
|
|
-- function baz() {} * Lexical
|
|
|
|
|
-- export { baz } * Export -> :point_up:
|
|
|
|
|
|
|
|
|
|
-- module B
|
|
|
|
|
-- import ModuleWithBar * Import
|
|
|
|
|
-- function foo() {} * Lexical
|
|
|
|
|
-- export { foo as bar, baz } * Export
|
|
|
|
|
|
|
|
|
|
-- internalLookup = (Lexical | Export)* . Lexical
|
|
|
|
|
-- externalLookup = (Lexical | Export)* . Import . ((Lexical | Export)* . Export)*
|
|
|
|
|
-- Module A
|
|
|
|
|
-- import B * Import
|
|
|
|
|
-- baz -- (internalLookup | externalLookup)
|
|
|
|
|
|
|
|
|
|
-- module ModuleWithBaz
|
|
|
|
|
-- function baz() {} * Lexical
|
|
|
|
|
-- export { baz }
|
|
|
|
|
|
|
|
|
|
-- module B
|
|
|
|
|
-- import ModuleWithBaz * Import
|
|
|
|
|
-- function foo() {} * Lexical
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Module A
|
|
|
|
|
-- import B * Import
|
|
|
|
|
-- baz -- internalLookup | externalLookup
|
|
|
|
|
|
|
|
|
|
-- -- (Lexical | Import | Export)* . Export . Lexical
|
|
|
|
|
-- -- Import . Lexical
|
|
|
|
|
|
|
|
|
|
-- -- Lexical* . Protected
|