1+ import { BaseDeclaration } from '../elements/memory/base' ;
2+
3+
4+ export class ScopeManager {
5+ language = "" ;
6+
7+
8+ /**
9+ * Initialises the VBA scopes at the language and application level.
10+ * @returns A scope with language and application initialised.
11+ */
12+ initialiseScope ( ) : Scope {
13+ return new VbaScope ( ) ;
14+ }
15+ }
16+
17+
18+ /**
19+ * A scope represents a region of code that has a scope.
20+ * This can be a module or a method.
21+ */
22+ class Scope {
23+ namespace : string ;
24+ parent : Scope | undefined ;
25+
26+ constructor ( namespace : string , parent : Scope | undefined ) {
27+ this . namespace = namespace ;
28+ this . parent = parent ;
29+ }
30+ }
31+
32+ class VbaScope extends Scope {
33+ globals : Map < string , string > = new Map ( ) ;
34+
35+ constructor ( ) {
36+ super ( "vba" , undefined ) ;
37+ }
38+ }
39+
40+ export class ScopeTable {
41+ // Items listed by their fully qualified name.
42+ definitions : Map < string , ScopeTableItem [ ] > = new Map ( ) ;
43+
44+ findDefinition ( identifier :string , context : string )
45+ : ScopeTableItem | undefined {
46+
47+ // Check fqns
48+ if ( this . definitions . has ( identifier ) ) {
49+ return this . definitions . get ( identifier ) [ 0 ] ;
50+ }
51+
52+ // Check the project scope.
53+ let result = this . findDef ( identifier , context ) ;
54+ if ( result ) { return result ; }
55+
56+ // Check the application scope.
57+ result = this . findDef ( identifier , 'Application' ) ;
58+ if ( result ) { return result ; }
59+
60+ // Check the language scope.
61+ result = this . findDef ( identifier , 'Vba' ) ;
62+ if ( result ) { return result ; }
63+ }
64+
65+ private findDef ( identifier :string , context : string )
66+ : ScopeTableItem | undefined {
67+ const names = context . split ( '.' ) ;
68+ while ( names ) {
69+ const checkDef = `${ names . join ( '.' ) } .${ identifier } ` ;
70+ if ( this . definitions . has ( checkDef ) ) {
71+ return this . definitions . get ( checkDef ) [ 0 ] ;
72+ }
73+ names . pop ( ) ;
74+ }
75+ }
76+ }
77+
78+
79+ export interface ScopeTableItem {
80+ //namespace: string
81+ docstring : string
82+ reference : ScopeItem
83+ returnsAs : any
84+ }
85+
86+ interface ScopeItem {
87+ args : string [ ]
88+ kwargs : Map < string , string >
89+ }
90+
91+ /**
92+ *
93+ * global
94+ * module
95+ * method
96+ * language
97+ * application
98+ */
99+
100+
101+ /**
102+ * When passed an identifier, need to find it.
103+ * There are a number of top level namespaces and
104+ * each may be the object itself.
105+ *
106+ myProject.myModule.mySub.foo
107+ myProject.myModule.foo
108+ myProject.foo
109+ myProject.foo
110+ Application.foo
111+ Vba.foo
112+
113+ Could be passed any part of the chain.
114+ e.g., myModule.a
115+
116+ Therefore the resolver needs to first understand the context
117+ of the highest level calling object.
118+
119+ It also needs to understand the context from where it's being called.
120+ e.g., finding `foo` from myFunc scope, the resolver must recursively
121+ walk up the scope tree to find a definition for foo:
122+ - myProject.myModule.myFunc
123+ - myProject.myModule
124+ - myProject.otherModules (public definitions only)
125+ - myProject
126+ - app
127+ - lang
128+ */
0 commit comments