naider 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,17 @@
1
+ const EXPRESSION_TYPES = new Set([
2
+ 'Number', 'String', 'InterpolatedString', 'Bool', 'Null', 'Array', 'Object',
3
+ 'Identifier', 'Binary', 'Unary', 'Call', 'MemberAccess', 'Ternary', 'Await',
4
+ 'ArrowFunction', 'Spread', 'New', 'IndexAccess',
5
+ ]);
6
+
1
7
  export class TypeChecker {
2
8
  constructor() {
3
9
  this.scopes = [new Map()];
4
10
  this.errors = [];
5
11
  this.warnings = [];
12
+ this.errorKeys = new Set();
13
+ this.warningKeys = new Set();
14
+ this.visitedStatements = new WeakSet();
6
15
  this.functions = new Map();
7
16
  this.returnTypes = [];
8
17
  }
@@ -22,11 +31,19 @@ export class TypeChecker {
22
31
  }
23
32
 
24
33
  error(msg, line) {
25
- this.errors.push({ message: msg, line: line || 0, severity: 'error' });
34
+ const diagnostic = { message: msg, line: line || 0, severity: 'error' };
35
+ const key = `${diagnostic.line}:${diagnostic.message}`;
36
+ if (this.errorKeys.has(key)) return;
37
+ this.errorKeys.add(key);
38
+ this.errors.push(diagnostic);
26
39
  }
27
40
 
28
41
  warn(msg, line) {
29
- this.warnings.push({ message: msg, line: line || 0, severity: 'warning' });
42
+ const diagnostic = { message: msg, line: line || 0, severity: 'warning' };
43
+ const key = `${diagnostic.line}:${diagnostic.message}`;
44
+ if (this.warningKeys.has(key)) return;
45
+ this.warningKeys.add(key);
46
+ this.warnings.push(diagnostic);
30
47
  }
31
48
 
32
49
  check(ast) {
@@ -52,7 +69,10 @@ export class TypeChecker {
52
69
  }
53
70
 
54
71
  visitStatement(node) {
72
+ if (this.visitedStatements.has(node)) return;
73
+ this.visitedStatements.add(node);
55
74
  const line = node._line || 0;
75
+ this.checkExpressions(node);
56
76
  switch (node.type) {
57
77
  case 'TypedVar': return this.visitTypedVar(node, line);
58
78
  case 'Function': return this.visitFunction(node, line);
@@ -63,11 +83,59 @@ export class TypeChecker {
63
83
  case 'For': return this.visitFor(node, line);
64
84
  case 'While': return this.visitWhile(node, line);
65
85
  case 'Try': return this.visitTry(node, line);
66
- case 'Server': return this.visitBlock(node.body, line);
67
- default: return;
86
+ case 'Server': return this.visitServer(node, line);
87
+ default: return this.visitNestedStatements(node);
68
88
  }
69
89
  }
70
90
 
91
+ checkExpressions(node) {
92
+ const seen = new WeakSet();
93
+ const visit = value => {
94
+ if (Array.isArray(value)) {
95
+ if (seen.has(value)) return;
96
+ seen.add(value);
97
+ for (const item of value) visit(item);
98
+ return;
99
+ }
100
+ if (!value || typeof value !== 'object') return;
101
+ if (seen.has(value)) return;
102
+ seen.add(value);
103
+
104
+ if (typeof value.type === 'string') {
105
+ if (!EXPRESSION_TYPES.has(value.type)) return;
106
+ this.inferType(value);
107
+ for (const [key, child] of Object.entries(value)) {
108
+ if (key !== 'type' && key !== '_line') visit(child);
109
+ }
110
+ return;
111
+ }
112
+
113
+ for (const child of Object.values(value)) visit(child);
114
+ };
115
+
116
+ for (const [key, value] of Object.entries(node)) {
117
+ if (key !== 'type' && key !== '_line') visit(value);
118
+ }
119
+ }
120
+
121
+ visitNestedStatements(value, seen = new WeakSet()) {
122
+ if (Array.isArray(value)) {
123
+ if (seen.has(value)) return;
124
+ seen.add(value);
125
+ for (const item of value) this.visitNestedStatements(item, seen);
126
+ return;
127
+ }
128
+ if (!value || typeof value !== 'object') return;
129
+ if (seen.has(value)) return;
130
+ seen.add(value);
131
+ if (typeof value.type === 'string') {
132
+ if (EXPRESSION_TYPES.has(value.type)) return;
133
+ this.visitStatement(value);
134
+ return;
135
+ }
136
+ for (const child of Object.values(value)) this.visitNestedStatements(child, seen);
137
+ }
138
+
71
139
  visitBlock(body, _line) {
72
140
  if (!body) return;
73
141
  this.pushScope();
@@ -99,6 +167,7 @@ export class TypeChecker {
99
167
  this.pushScope();
100
168
  for (const p of node.params) {
101
169
  this.setType(p.name, p.type || 'any');
170
+ if (p.defaultValue) this.inferType(p.defaultValue);
102
171
  }
103
172
  this.returnTypes.push(node.returnType || 'any');
104
173
  for (const stmt of node.body) {
@@ -188,6 +257,19 @@ export class TypeChecker {
188
257
  }
189
258
  }
190
259
 
260
+ visitServer(node, line) {
261
+ for (const route of node.routes || []) {
262
+ this.pushScope();
263
+ for (const param of route.params || []) {
264
+ this.setType(typeof param === 'string' ? param : param.name, 'any');
265
+ }
266
+ this.visitBlock(route.body, line);
267
+ this.popScope();
268
+ }
269
+ this.visitNestedStatements(node.middleware || []);
270
+ this.visitNestedStatements(node.body || []);
271
+ }
272
+
191
273
  inferType(node) {
192
274
  if (!node) return 'any';
193
275
  switch (node.type) {
@@ -197,7 +279,7 @@ export class TypeChecker {
197
279
  }
198
280
  case 'String': return 'str';
199
281
  case 'InterpolatedString': return 'str';
200
- case 'Boolean': return 'bool';
282
+ case 'Bool': return 'bool';
201
283
  case 'Null': return 'any';
202
284
  case 'Array': return 'list';
203
285
  case 'Object': return 'map';
@@ -24,7 +24,7 @@ Syntax highlighting and language support for **NAIDE** (`.naide`) files.
24
24
  cd vscode-naide
25
25
  npm install -g @vscode/vsce
26
26
  vsce package
27
- code --install-extension naide-lang-2.0.0.vsix
27
+ code --install-extension naide-lang-2.0.1.vsix
28
28
  ```
29
29
 
30
30
  ### Manual
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "naide-lang",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "naide-lang",
9
- "version": "2.0.0",
9
+ "version": "2.0.1",
10
10
  "dependencies": {
11
11
  "vscode-languageclient": "^9.0.0"
12
12
  },
@@ -2,7 +2,7 @@
2
2
  "name": "naide-lang",
3
3
  "displayName": "NAIDE Language",
4
4
  "description": "Syntax highlighting, diagnostics, and autocomplete for NAIDE (.naide)",
5
- "version": "2.0.0",
5
+ "version": "2.0.1",
6
6
  "publisher": "irxk",
7
7
  "engines": { "vscode": "^1.75.0" },
8
8
  "categories": ["Programming Languages"],