Skip to content

Commit 5853c32

Browse files
committed
Send it
1 parent 1780667 commit 5853c32

File tree

19 files changed

+1444
-1
lines changed

19 files changed

+1444
-1
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"typescript.tsc.autoDetect": "off",
44
"typescript.preferences.quoteStyle": "single",
55
"editor.codeActionsOnSave": {
6-
"source.fixAll.eslint": true
6+
"source.fixAll.eslint": "explicit"
77
},
88
"vbaLanguageServer.trace.server": "verbose"
99
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
// Represents a project
3+
"markdoc": {
4+
"global": {},
5+
"LexerMarkdown": {
6+
"global": {
7+
"mTokens": "VariableDeclarationsElement",
8+
"Tokenize": "SubDeclarationElement",
9+
"TokenFactory": "FunctionDeclarationElement",
10+
"Tokens": "PropertyDeclarationElement"
11+
},
12+
"Tokens": {
13+
"get": {},
14+
"set": { // no need to distinguish let here.
15+
"var": "VariableDeclarationsElement"
16+
}
17+
}
18+
}
19+
},
20+
// Similar to a project, available for anything.
21+
// This probably needs to legit be a json resource.
22+
"excelVbaObjectModel": {
23+
"Range": {
24+
"functions": {
25+
"SpecialCells": {
26+
"doc": "Returns a **Range** object that represents all the cells that match the specified type and value.",
27+
"args": {
28+
"Type": "XlCellType",
29+
"[Value]": "Variant"
30+
},
31+
"returns": "Excel.Range"
32+
}
33+
}
34+
}
35+
},
36+
"vbaObjectModel": {
37+
"Collection": {
38+
"subs": {
39+
"Add": {
40+
"doc": "Adds a member to a **Collection** object.",
41+
"args": {
42+
"Item": "Variant",
43+
"[Key]": "String",
44+
"[Before]": "Long",
45+
"[After]": "Long"
46+
}
47+
}
48+
}
49+
}
50+
}
51+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
/**
3+
* A data class representing a method, function, or variable.
4+
*/
5+
class VbaSymbol {
6+
scope: string;
7+
name: string;
8+
9+
constructor(scope: string, name: string, ) {
10+
this.scope = scope;
11+
this.name = name;
12+
}
13+
}
14+
15+
class VbaReference extends VbaSymbol {
16+
declaration: VbaSymbol;
17+
18+
constructor(scope: string, name: string, declaration: VbaSymbol) {
19+
super(scope, name);
20+
this.declaration = declaration;
21+
}
22+
}

0 commit comments

Comments
 (0)