brighterscript 1.0.0-alpha.13 → 1.0.0-alpha.14
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.
- package/CHANGELOG.md +46 -2
- package/dist/Cache.d.ts +3 -3
- package/dist/Cache.js +10 -6
- package/dist/Cache.js.map +1 -1
- package/dist/LanguageServer.d.ts +1 -6
- package/dist/LanguageServer.js +0 -9
- package/dist/LanguageServer.js.map +1 -1
- package/dist/PluginInterface.d.ts +3 -3
- package/dist/PluginInterface.js +3 -0
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +30 -16
- package/dist/Program.js +106 -43
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js +3 -3
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +15 -6
- package/dist/Scope.js +39 -25
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +1 -1
- package/dist/astUtils/reflection.spec.js +6 -6
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +8 -8
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.js +5 -2
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +8 -0
- package/dist/bscPlugin/semanticTokens/{SemanticTokensProcessor.js → BrsFileSemanticTokensProcessor.js} +12 -14
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/{SemanticTokensProcessor.spec.d.ts → BrsFileSemanticTokensProcessor.spec.d.ts} +0 -0
- package/dist/bscPlugin/semanticTokens/{SemanticTokensProcessor.spec.js → BrsFileSemanticTokensProcessor.spec.js} +2 -2
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +389 -238
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +17 -11
- package/dist/files/BrsFile.js +160 -91
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +442 -109
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +6 -5
- package/dist/files/XmlFile.js +13 -8
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +57 -55
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +8 -6
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +46 -10
- package/dist/lexer/Lexer.js +1 -2
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +462 -462
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/parser/Expression.d.ts +1 -1
- package/dist/parser/Expression.js +10 -10
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +33 -32
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +17 -5
- package/dist/parser/Parser.js +403 -288
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +157 -35
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGTypes.spec.js +9 -9
- package/dist/parser/SGTypes.spec.js.map +1 -1
- package/dist/parser/Statement.d.ts +3 -3
- package/dist/parser/Statement.js +8 -8
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +3 -3
- package/dist/parser/tests/Parser.spec.js +4 -4
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +40 -40
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +22 -21
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +100 -99
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +25 -25
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +21 -21
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +91 -91
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +102 -102
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +15 -15
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +22 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +11 -11
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +171 -171
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +50 -50
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +25 -25
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +16 -16
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +26 -26
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +27 -27
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +3 -2
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +25 -25
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +7 -7
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +6 -6
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/Declaration.spec.js +20 -20
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +121 -120
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +9 -8
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +22 -22
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +12 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +7 -7
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +71 -70
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +17 -17
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +33 -33
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +53 -53
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +7 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.js +7 -7
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/types/ArrayType.d.ts +8 -5
- package/dist/types/ArrayType.js +45 -9
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +62 -3
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +1 -1
- package/dist/types/CustomType.d.ts +1 -1
- package/dist/types/CustomType.js +4 -2
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +5 -5
- package/dist/types/FunctionType.js +11 -11
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/LazyType.d.ts +1 -2
- package/dist/types/LazyType.js +1 -5
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/helpers.js +1 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +15 -9
- package/dist/util.js +93 -50
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js +17 -24
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +2 -1
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +0 -7
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -18
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
package/dist/files/BrsFile.js
CHANGED
|
@@ -6,8 +6,11 @@ const vscode_languageserver_1 = require("vscode-languageserver");
|
|
|
6
6
|
const chalk_1 = require("chalk");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const Token_1 = require("../lexer/Token");
|
|
10
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
11
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
12
|
+
const Parser_1 = require("../parser/Parser");
|
|
13
|
+
const DynamicType_1 = require("../types/DynamicType");
|
|
11
14
|
const util_1 = require("../util");
|
|
12
15
|
const BrsTranspileState_1 = require("../parser/BrsTranspileState");
|
|
13
16
|
const Preprocessor_1 = require("../preprocessor/Preprocessor");
|
|
@@ -19,8 +22,6 @@ const CommentFlagProcessor_1 = require("../CommentFlagProcessor");
|
|
|
19
22
|
const BscType_1 = require("../types/BscType");
|
|
20
23
|
const UninitializedType_1 = require("../types/UninitializedType");
|
|
21
24
|
const InvalidType_1 = require("../types/InvalidType");
|
|
22
|
-
const globalCallables_1 = require("../globalCallables");
|
|
23
|
-
const DynamicType_1 = require("../types/DynamicType");
|
|
24
25
|
/**
|
|
25
26
|
* Holds all details about this file within the scope of the whole program
|
|
26
27
|
*/
|
|
@@ -41,9 +42,10 @@ class BrsFile {
|
|
|
41
42
|
/**
|
|
42
43
|
* The parseMode used for the parser for this file
|
|
43
44
|
*/
|
|
44
|
-
this.parseMode =
|
|
45
|
+
this.parseMode = Parser_1.ParseMode.BrightScript;
|
|
45
46
|
/**
|
|
46
47
|
* Indicates whether this file needs to be validated.
|
|
48
|
+
* Files are only ever validated a single time
|
|
47
49
|
*/
|
|
48
50
|
this.isValidated = false;
|
|
49
51
|
this.diagnostics = [];
|
|
@@ -64,7 +66,7 @@ class BrsFile {
|
|
|
64
66
|
//all BrighterScript files need to be transpiled
|
|
65
67
|
if ((_a = this.extension) === null || _a === void 0 ? void 0 : _a.endsWith('.bs')) {
|
|
66
68
|
this.needsTranspiled = true;
|
|
67
|
-
this.parseMode =
|
|
69
|
+
this.parseMode = Parser_1.ParseMode.BrighterScript;
|
|
68
70
|
}
|
|
69
71
|
this.isTypedef = this.extension === '.d.bs';
|
|
70
72
|
if (!this.isTypedef) {
|
|
@@ -135,11 +137,13 @@ class BrsFile {
|
|
|
135
137
|
this.diagnostics = [];
|
|
136
138
|
//if we have a typedef file, skip parsing this file
|
|
137
139
|
if (this.hasTypedef) {
|
|
140
|
+
//skip validation since the typedef is shadowing this file
|
|
141
|
+
this.isValidated = true;
|
|
138
142
|
return;
|
|
139
143
|
}
|
|
140
144
|
//tokenize the input file
|
|
141
145
|
let lexer = this.program.logger.time(Logger_1.LogLevel.debug, ['lexer.lex', chalk_1.default.green(this.srcPath)], () => {
|
|
142
|
-
return
|
|
146
|
+
return Lexer_1.Lexer.scan(fileContents, {
|
|
143
147
|
includeWhitespace: false
|
|
144
148
|
});
|
|
145
149
|
});
|
|
@@ -162,7 +166,7 @@ class BrsFile {
|
|
|
162
166
|
//if the preprocessor generated tokens, use them.
|
|
163
167
|
let tokens = preprocessor.processedTokens.length > 0 ? preprocessor.processedTokens : lexer.tokens;
|
|
164
168
|
this.program.logger.time(Logger_1.LogLevel.debug, ['parser.parse', chalk_1.default.green(this.srcPath)], () => {
|
|
165
|
-
this._parser =
|
|
169
|
+
this._parser = Parser_1.Parser.parse(tokens, {
|
|
166
170
|
mode: this.parseMode,
|
|
167
171
|
logger: this.program.logger
|
|
168
172
|
});
|
|
@@ -173,20 +177,39 @@ class BrsFile {
|
|
|
173
177
|
this.findCallables();
|
|
174
178
|
//find all places where a sub/function is being called
|
|
175
179
|
this.findFunctionCalls();
|
|
176
|
-
|
|
180
|
+
//register all import statements for use in the rest of the program
|
|
181
|
+
this.registerImports();
|
|
177
182
|
//attach this file to every diagnostic
|
|
178
183
|
for (let diagnostic of this.diagnostics) {
|
|
179
184
|
diagnostic.file = this;
|
|
180
185
|
}
|
|
181
186
|
}
|
|
182
187
|
catch (e) {
|
|
183
|
-
this._parser = new
|
|
188
|
+
this._parser = new Parser_1.Parser();
|
|
184
189
|
this.diagnostics.push(Object.assign({ file: this, range: util_1.util.createRange(0, 0, 0, Number.MAX_VALUE) }, DiagnosticMessages_1.DiagnosticMessages.genericParserMessage('Critical error parsing file: ' + JSON.stringify((0, serialize_error_1.serializeError)(e)))));
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
registerImports() {
|
|
193
|
+
var _a, _b, _c, _d;
|
|
194
|
+
for (const statement of (_c = (_b = (_a = this.parser) === null || _a === void 0 ? void 0 : _a.references) === null || _b === void 0 ? void 0 : _b.importStatements) !== null && _c !== void 0 ? _c : []) {
|
|
195
|
+
//register import statements
|
|
196
|
+
if ((0, reflection_1.isImportStatement)(statement) && statement.filePathToken) {
|
|
197
|
+
this.ownScriptImports.push({
|
|
198
|
+
filePathRange: statement.filePathToken.range,
|
|
199
|
+
pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, statement.filePath),
|
|
200
|
+
sourceFile: this,
|
|
201
|
+
text: (_d = statement.filePathToken) === null || _d === void 0 ? void 0 : _d.text
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
validate() {
|
|
207
|
+
//only validate the file if it was actually parsed (skip files containing typedefs)
|
|
208
|
+
if (!this.hasTypedef) {
|
|
209
|
+
this.validateImportStatements();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
validateImportStatements() {
|
|
190
213
|
let topOfFileIncludeStatements = [];
|
|
191
214
|
for (let stmt of this.ast.statements) {
|
|
192
215
|
//skip comments
|
|
@@ -207,15 +230,6 @@ class BrsFile {
|
|
|
207
230
|
...this._parser.references.importStatements
|
|
208
231
|
];
|
|
209
232
|
for (let result of statements) {
|
|
210
|
-
//register import statements
|
|
211
|
-
if ((0, reflection_1.isImportStatement)(result) && result.filePathToken) {
|
|
212
|
-
this.ownScriptImports.push({
|
|
213
|
-
filePathRange: result.filePathToken.range,
|
|
214
|
-
pkgPath: util_1.util.getPkgPathFromTarget(this.pkgPath, result.filePath),
|
|
215
|
-
sourceFile: this,
|
|
216
|
-
text: (_a = result.filePathToken) === null || _a === void 0 ? void 0 : _a.text
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
233
|
//if this statement is not one of the top-of-file statements,
|
|
220
234
|
//then add a diagnostic explaining that it is invalid
|
|
221
235
|
if (!topOfFileIncludeStatements.includes(result)) {
|
|
@@ -273,7 +287,7 @@ class BrsFile {
|
|
|
273
287
|
const processor = new CommentFlagProcessor_1.CommentFlagProcessor(this, ['rem', `'`], DiagnosticMessages_1.diagnosticCodes, [DiagnosticMessages_1.DiagnosticCodeMap.unknownDiagnosticCode]);
|
|
274
288
|
this.commentFlags = [];
|
|
275
289
|
for (let token of tokens) {
|
|
276
|
-
if (token.kind ===
|
|
290
|
+
if (token.kind === TokenKind_1.TokenKind.Comment) {
|
|
277
291
|
processor.tryAdd(token.text, token.range);
|
|
278
292
|
}
|
|
279
293
|
}
|
|
@@ -325,7 +339,7 @@ class BrsFile {
|
|
|
325
339
|
let args = [];
|
|
326
340
|
//TODO convert if stmts to use instanceof instead
|
|
327
341
|
for (let arg of expression.args) {
|
|
328
|
-
let inferredType = (0,
|
|
342
|
+
let inferredType = (0, Parser_1.getBscTypeFromExpression)(arg, func);
|
|
329
343
|
let argText = '';
|
|
330
344
|
// Get the text to display for the arg
|
|
331
345
|
if (arg.token) {
|
|
@@ -333,7 +347,7 @@ class BrsFile {
|
|
|
333
347
|
//is a function call being passed into argument
|
|
334
348
|
}
|
|
335
349
|
else if (arg.name) {
|
|
336
|
-
if ((0,
|
|
350
|
+
if ((0, Token_1.isToken)(arg.name)) {
|
|
337
351
|
argText = arg.name.text;
|
|
338
352
|
}
|
|
339
353
|
}
|
|
@@ -404,10 +418,10 @@ class BrsFile {
|
|
|
404
418
|
//if cursor is within a comment, disable completions
|
|
405
419
|
let currentToken = this.parser.getTokenAt(position);
|
|
406
420
|
const tokenKind = currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind;
|
|
407
|
-
if (tokenKind ===
|
|
421
|
+
if (tokenKind === TokenKind_1.TokenKind.Comment) {
|
|
408
422
|
return [];
|
|
409
423
|
}
|
|
410
|
-
else if (tokenKind ===
|
|
424
|
+
else if (tokenKind === TokenKind_1.TokenKind.StringLiteral || tokenKind === TokenKind_1.TokenKind.TemplateStringQuasi) {
|
|
411
425
|
const match = /^("?)(pkg|libpkg):/.exec(currentToken.text);
|
|
412
426
|
if (match) {
|
|
413
427
|
const [, openingQuote, fileProtocol] = match;
|
|
@@ -439,7 +453,7 @@ class BrsFile {
|
|
|
439
453
|
let functionExpression = this.getFunctionExpressionAtPosition(position);
|
|
440
454
|
if (!functionExpression) {
|
|
441
455
|
//we aren't in any function scope, so return the keyword completions and namespaces
|
|
442
|
-
if (this.parser.getTokenBefore(currentToken,
|
|
456
|
+
if (this.parser.getTokenBefore(currentToken, TokenKind_1.TokenKind.New)) {
|
|
443
457
|
// there's a new keyword, so only class types are viable here
|
|
444
458
|
return [...this.getGlobalClassStatementCompletions(currentToken, this.parseMode)];
|
|
445
459
|
}
|
|
@@ -448,17 +462,17 @@ class BrsFile {
|
|
|
448
462
|
}
|
|
449
463
|
}
|
|
450
464
|
const classNameCompletions = this.getGlobalClassStatementCompletions(currentToken, this.parseMode);
|
|
451
|
-
const newToken = this.parser.getTokenBefore(currentToken,
|
|
465
|
+
const newToken = this.parser.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
|
|
452
466
|
if (newToken) {
|
|
453
467
|
//we are after a new keyword; so we can only be namespaces or classes at this point
|
|
454
468
|
result.push(...classNameCompletions);
|
|
455
469
|
result.push(...namespaceCompletions);
|
|
456
470
|
return result;
|
|
457
471
|
}
|
|
458
|
-
if (this.parser.tokenFollows(currentToken,
|
|
472
|
+
if (this.parser.tokenFollows(currentToken, TokenKind_1.TokenKind.Goto)) {
|
|
459
473
|
return this.getLabelCompletion(functionExpression);
|
|
460
474
|
}
|
|
461
|
-
if (this.parser.isPositionNextToTokenKind(position,
|
|
475
|
+
if (this.parser.isPositionNextToTokenKind(position, TokenKind_1.TokenKind.Dot)) {
|
|
462
476
|
if (namespaceCompletions.length > 0) {
|
|
463
477
|
//if we matched a namespace, after a dot, it can't be anything else but something from our namespace completions
|
|
464
478
|
return namespaceCompletions;
|
|
@@ -514,7 +528,7 @@ class BrsFile {
|
|
|
514
528
|
// kind: isFunctionType(foundType) ? CompletionItemKind.Function : CompletionItemKind.Variable
|
|
515
529
|
});
|
|
516
530
|
}
|
|
517
|
-
if (this.parseMode ===
|
|
531
|
+
if (this.parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
518
532
|
//include the first part of namespaces
|
|
519
533
|
let namespaces = scope.getAllNamespaceStatements();
|
|
520
534
|
for (let stmt of namespaces) {
|
|
@@ -552,7 +566,7 @@ class BrsFile {
|
|
|
552
566
|
let classStatement = this.getClassFromToken(currentToken, functionExpression, scope);
|
|
553
567
|
let results = new Map();
|
|
554
568
|
if (classStatement) {
|
|
555
|
-
let classes = scope.getClassHierarchy(classStatement.item.getName(
|
|
569
|
+
let classes = scope.getClassHierarchy(classStatement.item.getName(Parser_1.ParseMode.BrighterScript).toLowerCase());
|
|
556
570
|
for (let cs of classes) {
|
|
557
571
|
for (let member of [...(_b = (_a = cs === null || cs === void 0 ? void 0 : cs.item) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : [], ...(_d = (_c = cs === null || cs === void 0 ? void 0 : cs.item) === null || _c === void 0 ? void 0 : _c.methods) !== null && _d !== void 0 ? _d : []]) {
|
|
558
572
|
if (!results.has(member.name.text.toLowerCase())) {
|
|
@@ -602,7 +616,7 @@ class BrsFile {
|
|
|
602
616
|
let startsWithNamespace = '';
|
|
603
617
|
let namespaceContainer;
|
|
604
618
|
let tokenChain = [...originalTokenChain];
|
|
605
|
-
while (tokenChain[0] && tokenChain[0].usage ===
|
|
619
|
+
while (tokenChain[0] && tokenChain[0].usage === Parser_1.TokenUsage.Direct) {
|
|
606
620
|
const namespaceNameToCheck = `${startsWithNamespace}${startsWithNamespace.length > 0 ? '.' : ''}${tokenChain[0].token.text}`.toLowerCase();
|
|
607
621
|
const foundNamespace = scope.namespaceLookup.get(namespaceNameToCheck);
|
|
608
622
|
if (foundNamespace) {
|
|
@@ -633,7 +647,7 @@ class BrsFile {
|
|
|
633
647
|
let useExpandedTextOnly = false;
|
|
634
648
|
if (containingClass.name === currentToken) {
|
|
635
649
|
symbolType = containingClass.getCustomType();
|
|
636
|
-
expandedText = `class ${containingClass.getName(
|
|
650
|
+
expandedText = `class ${containingClass.getName(Parser_1.ParseMode.BrighterScript)}`;
|
|
637
651
|
useExpandedTextOnly = true;
|
|
638
652
|
currentClassRef = containingClass;
|
|
639
653
|
}
|
|
@@ -652,13 +666,13 @@ class BrsFile {
|
|
|
652
666
|
// check if this is a method declaration
|
|
653
667
|
currentClassRef = containingClass;
|
|
654
668
|
symbolType = containingClass === null || containingClass === void 0 ? void 0 : containingClass.memberTable.getSymbolType(currentTokenLower, true, { file: this, scope: scope });
|
|
655
|
-
expandedText = [containingClass.getName(
|
|
669
|
+
expandedText = [containingClass.getName(Parser_1.ParseMode.BrighterScript), currentToken.text].join('.');
|
|
656
670
|
}
|
|
657
671
|
else if (!func) {
|
|
658
672
|
// check if this is a field declaration
|
|
659
673
|
currentClassRef = containingClass;
|
|
660
674
|
symbolType = containingClass === null || containingClass === void 0 ? void 0 : containingClass.memberTable.getSymbolType(currentTokenLower, true, { file: this, scope: scope });
|
|
661
|
-
expandedText = [containingClass.getName(
|
|
675
|
+
expandedText = [containingClass.getName(Parser_1.ParseMode.BrighterScript), currentToken.text].join('.');
|
|
662
676
|
}
|
|
663
677
|
if (symbolType) {
|
|
664
678
|
return { type: symbolType, expandedTokenText: expandedText, symbolContainer: currentClassRef, useExpandedTextOnly: useExpandedTextOnly };
|
|
@@ -690,7 +704,7 @@ class BrsFile {
|
|
|
690
704
|
*/
|
|
691
705
|
getSymbolTypeFromToken(currentToken, functionExpression, scope) {
|
|
692
706
|
var _a, _b, _c, _d, _e;
|
|
693
|
-
if (!scope) {
|
|
707
|
+
if (!scope || !currentToken) {
|
|
694
708
|
return undefined;
|
|
695
709
|
}
|
|
696
710
|
const cachedSymbolData = scope.symbolCache.get(currentToken);
|
|
@@ -720,13 +734,14 @@ class BrsFile {
|
|
|
720
734
|
const typeContext = { file: this, scope: scope, position: (_c = tokenChain[0]) === null || _c === void 0 ? void 0 : _c.token.range.start };
|
|
721
735
|
for (const tokenChainMember of tokenChain) {
|
|
722
736
|
const token = tokenChainMember === null || tokenChainMember === void 0 ? void 0 : tokenChainMember.token;
|
|
737
|
+
const tokenUsage = tokenChainMember === null || tokenChainMember === void 0 ? void 0 : tokenChainMember.usage;
|
|
723
738
|
const tokenLowerText = token.text.toLowerCase();
|
|
724
739
|
if (tokenLowerText === 'super' && (0, reflection_1.isClassStatement)(symbolContainer) && tokenFoundCount === 0) {
|
|
725
740
|
/// Special cases for first item in chain inside a class
|
|
726
741
|
symbolContainer = scope === null || scope === void 0 ? void 0 : scope.getParentClass(symbolContainer);
|
|
727
742
|
currentSymbolTable = (_d = symbolContainer) === null || _d === void 0 ? void 0 : _d.memberTable;
|
|
728
743
|
if (symbolContainer && currentSymbolTable) {
|
|
729
|
-
tokenText.push(symbolContainer.getName(
|
|
744
|
+
tokenText.push(symbolContainer.getName(Parser_1.ParseMode.BrighterScript));
|
|
730
745
|
tokenFoundCount++;
|
|
731
746
|
continue;
|
|
732
747
|
}
|
|
@@ -738,7 +753,7 @@ class BrsFile {
|
|
|
738
753
|
symbolType = currentSymbolTable.getSymbolType(tokenLowerText, true, typeContext);
|
|
739
754
|
if (tokenFoundCount === 0 && !symbolType) {
|
|
740
755
|
//check for global callable
|
|
741
|
-
symbolType = (_e =
|
|
756
|
+
symbolType = (_e = scope.getGlobalCallableByName(tokenLowerText)) === null || _e === void 0 ? void 0 : _e.type;
|
|
742
757
|
}
|
|
743
758
|
if (symbolType) {
|
|
744
759
|
// found this symbol, and it's valid. increase found counter
|
|
@@ -750,10 +765,13 @@ class BrsFile {
|
|
|
750
765
|
// the next symbol to check will be the return value of this function
|
|
751
766
|
symbolType = (0, BscType_1.getTypeFromContext)(symbolType.returnType, typeContext);
|
|
752
767
|
if (tokenFoundCount < tokenChain.length) {
|
|
753
|
-
// We
|
|
768
|
+
// We still have more tokens, but remember the last known reference
|
|
754
769
|
symbolTypeBeforeReference = symbolType;
|
|
755
770
|
}
|
|
756
771
|
}
|
|
772
|
+
if ((0, reflection_1.isArrayType)(symbolType) && tokenUsage === Parser_1.TokenUsage.ArrayReference) {
|
|
773
|
+
symbolType = (0, BscType_1.getTypeFromContext)(symbolType.getDefaultType(typeContext), typeContext);
|
|
774
|
+
}
|
|
757
775
|
if (symbolType === null || symbolType === void 0 ? void 0 : symbolType.memberTable) {
|
|
758
776
|
if ((0, reflection_1.isCustomType)(symbolType)) {
|
|
759
777
|
// we're currently looking at a customType, that has it's own symbol table
|
|
@@ -783,9 +801,12 @@ class BrsFile {
|
|
|
783
801
|
tokenText.push(token.text);
|
|
784
802
|
break;
|
|
785
803
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
804
|
+
}
|
|
805
|
+
if (tokenText.length > 2) {
|
|
806
|
+
// TokenText is used for hovers. We only need the last two tokens for a hover
|
|
807
|
+
// So in a long chain (e.g. klass.getData()[0].anotherKlass.property), the hover
|
|
808
|
+
// for the last token should just be "AnotherKlass.property", not the whole chain
|
|
809
|
+
tokenText = tokenText.slice(-2);
|
|
789
810
|
}
|
|
790
811
|
let expandedTokenText = tokenText.join('.');
|
|
791
812
|
let backUpReturnType;
|
|
@@ -827,11 +848,11 @@ class BrsFile {
|
|
|
827
848
|
}
|
|
828
849
|
getGlobalClassStatementCompletions(currentToken, parseMode) {
|
|
829
850
|
var _a;
|
|
830
|
-
if (parseMode ===
|
|
851
|
+
if (parseMode === Parser_1.ParseMode.BrightScript) {
|
|
831
852
|
return [];
|
|
832
853
|
}
|
|
833
854
|
let results = new Map();
|
|
834
|
-
let completionName = (_a = this.getPartialVariableName(currentToken, [
|
|
855
|
+
let completionName = (_a = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New])) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
835
856
|
if (completionName === null || completionName === void 0 ? void 0 : completionName.includes('.')) {
|
|
836
857
|
return [];
|
|
837
858
|
}
|
|
@@ -853,17 +874,17 @@ class BrsFile {
|
|
|
853
874
|
}
|
|
854
875
|
getNamespaceCompletions(currentToken, parseMode, scope) {
|
|
855
876
|
//BrightScript does not support namespaces, so return an empty list in that case
|
|
856
|
-
if (parseMode ===
|
|
877
|
+
if (parseMode === Parser_1.ParseMode.BrightScript) {
|
|
857
878
|
return [];
|
|
858
879
|
}
|
|
859
|
-
let completionName = this.getPartialVariableName(currentToken, [
|
|
880
|
+
let completionName = this.getPartialVariableName(currentToken, [TokenKind_1.TokenKind.New]);
|
|
860
881
|
if (!completionName) {
|
|
861
882
|
return [];
|
|
862
883
|
}
|
|
863
884
|
//remove any trailing identifer and then any trailing dot, to give us the
|
|
864
885
|
//name of its immediate parent namespace
|
|
865
886
|
let closestParentNamespaceName = completionName.replace(/\.([a-z0-9_]*)?$/gi, '');
|
|
866
|
-
let newToken = this.parser.getTokenBefore(currentToken,
|
|
887
|
+
let newToken = this.parser.getTokenBefore(currentToken, TokenKind_1.TokenKind.New);
|
|
867
888
|
let result = new Map();
|
|
868
889
|
for (let [, namespace] of scope.namespaceLookup) {
|
|
869
890
|
//completionName = "NameA."
|
|
@@ -912,11 +933,11 @@ class BrsFile {
|
|
|
912
933
|
return undefined;
|
|
913
934
|
}
|
|
914
935
|
let location;
|
|
915
|
-
const nameParts = this.getPartialVariableName(token, [
|
|
936
|
+
const nameParts = this.getPartialVariableName(token, [TokenKind_1.TokenKind.New]).split('.');
|
|
916
937
|
const endName = nameParts[nameParts.length - 1].toLowerCase();
|
|
917
938
|
const namespaceName = nameParts.slice(0, -1).join('.').toLowerCase();
|
|
918
939
|
const statementHandler = (statement) => {
|
|
919
|
-
if (!location && statement.getName(
|
|
940
|
+
if (!location && statement.getName(Parser_1.ParseMode.BrighterScript).toLowerCase() === namespaceName) {
|
|
920
941
|
const namespaceItemStatementHandler = (statement) => {
|
|
921
942
|
if (!location && statement.name.text.toLowerCase() === endName) {
|
|
922
943
|
const uri = util_1.util.pathToUri(file.srcPath);
|
|
@@ -942,7 +963,7 @@ class BrsFile {
|
|
|
942
963
|
* Given a current token, walk
|
|
943
964
|
*/
|
|
944
965
|
getPartialVariableName(currentToken, excludeTokens = null) {
|
|
945
|
-
let identifierAndDotKinds = [
|
|
966
|
+
let identifierAndDotKinds = [TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedLocalIdentifiers, TokenKind_1.TokenKind.Dot];
|
|
946
967
|
//consume tokens backwards until we find something other than a dot or an identifier
|
|
947
968
|
let tokens = [];
|
|
948
969
|
const parser = this.parser;
|
|
@@ -1073,7 +1094,7 @@ class BrsFile {
|
|
|
1073
1094
|
else {
|
|
1074
1095
|
return;
|
|
1075
1096
|
}
|
|
1076
|
-
const name = (0, reflection_1.isClassFieldStatement)(statement) ? statement.name.text : statement.getName(
|
|
1097
|
+
const name = (0, reflection_1.isClassFieldStatement)(statement) ? statement.name.text : statement.getName(Parser_1.ParseMode.BrighterScript);
|
|
1077
1098
|
return vscode_languageserver_1.DocumentSymbol.create(name, '', symbolKind, statement.range, statement.range, children);
|
|
1078
1099
|
}
|
|
1079
1100
|
/**
|
|
@@ -1107,9 +1128,9 @@ class BrsFile {
|
|
|
1107
1128
|
else {
|
|
1108
1129
|
return symbols;
|
|
1109
1130
|
}
|
|
1110
|
-
const name = statement.getName(
|
|
1131
|
+
const name = statement.getName(Parser_1.ParseMode.BrighterScript);
|
|
1111
1132
|
const uri = util_1.util.pathToUri(this.srcPath);
|
|
1112
|
-
const symbol = vscode_languageserver_1.SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement === null || containerStatement === void 0 ? void 0 : containerStatement.getName(
|
|
1133
|
+
const symbol = vscode_languageserver_1.SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement === null || containerStatement === void 0 ? void 0 : containerStatement.getName(Parser_1.ParseMode.BrighterScript));
|
|
1113
1134
|
symbols.push(symbol);
|
|
1114
1135
|
return symbols;
|
|
1115
1136
|
}
|
|
@@ -1123,8 +1144,8 @@ class BrsFile {
|
|
|
1123
1144
|
const token = this.parser.getTokenAt(position);
|
|
1124
1145
|
// While certain other tokens are allowed as local variables (AllowedLocalIdentifiers: https://github.com/rokucommunity/brighterscript/blob/master/src/lexer/TokenKind.ts#L418), these are converted by the parser to TokenKind.Identifier by the time we retrieve the token using getTokenAt
|
|
1125
1146
|
let definitionTokenTypes = [
|
|
1126
|
-
|
|
1127
|
-
|
|
1147
|
+
TokenKind_1.TokenKind.Identifier,
|
|
1148
|
+
TokenKind_1.TokenKind.StringLiteral
|
|
1128
1149
|
];
|
|
1129
1150
|
//throw out invalid tokens and the wrong kind of tokens
|
|
1130
1151
|
if (!token || !definitionTokenTypes.includes(token.kind)) {
|
|
@@ -1132,7 +1153,7 @@ class BrsFile {
|
|
|
1132
1153
|
}
|
|
1133
1154
|
let textToSearchFor = token.text.toLowerCase();
|
|
1134
1155
|
const previousToken = this.parser.getTokenAt({ line: token.range.start.line, character: token.range.start.character });
|
|
1135
|
-
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) ===
|
|
1156
|
+
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Callfunc) {
|
|
1136
1157
|
for (const scope of this.program.getScopes()) {
|
|
1137
1158
|
//to only get functions defined in interface methods
|
|
1138
1159
|
const callable = scope.getAllCallables().find((c) => c.callable.name.toLowerCase() === textToSearchFor); // eslint-disable-line @typescript-eslint/no-loop-func
|
|
@@ -1142,7 +1163,7 @@ class BrsFile {
|
|
|
1142
1163
|
}
|
|
1143
1164
|
return results;
|
|
1144
1165
|
}
|
|
1145
|
-
let classToken = this.parser.getTokenBefore(token,
|
|
1166
|
+
let classToken = this.parser.getTokenBefore(token, TokenKind_1.TokenKind.Class);
|
|
1146
1167
|
if (classToken) {
|
|
1147
1168
|
let cs = this.parser.references.classStatements.find((cs) => cs.classKeyword.range === classToken.range);
|
|
1148
1169
|
if (cs === null || cs === void 0 ? void 0 : cs.parentClassName) {
|
|
@@ -1154,7 +1175,7 @@ class BrsFile {
|
|
|
1154
1175
|
}
|
|
1155
1176
|
return results;
|
|
1156
1177
|
}
|
|
1157
|
-
if (token.kind ===
|
|
1178
|
+
if (token.kind === TokenKind_1.TokenKind.StringLiteral) {
|
|
1158
1179
|
// We need to strip off the quotes but only if present
|
|
1159
1180
|
const startIndex = textToSearchFor.startsWith('"') ? 1 : 0;
|
|
1160
1181
|
let endIndex = textToSearchFor.length;
|
|
@@ -1173,7 +1194,7 @@ class BrsFile {
|
|
|
1173
1194
|
results.push(vscode_languageserver_1.Location.create(uri, symbol.range));
|
|
1174
1195
|
}
|
|
1175
1196
|
}
|
|
1176
|
-
if (this.parser.tokenFollows(token,
|
|
1197
|
+
if (this.parser.tokenFollows(token, TokenKind_1.TokenKind.Goto)) {
|
|
1177
1198
|
for (const label of func.labelStatements) {
|
|
1178
1199
|
if (label.tokens.identifier.text.toLocaleLowerCase() === textToSearchFor) {
|
|
1179
1200
|
const uri = util_1.util.pathToUri(this.srcPath);
|
|
@@ -1189,7 +1210,7 @@ class BrsFile {
|
|
|
1189
1210
|
continue;
|
|
1190
1211
|
}
|
|
1191
1212
|
filesSearched.add(file);
|
|
1192
|
-
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) ===
|
|
1213
|
+
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind) === TokenKind_1.TokenKind.Dot && file.parseMode === Parser_1.ParseMode.BrighterScript) {
|
|
1193
1214
|
results.push(...this.getClassMemberDefinitions(textToSearchFor, file));
|
|
1194
1215
|
const namespaceDefinition = this.getNamespaceDefinitions(token, file);
|
|
1195
1216
|
if (namespaceDefinition) {
|
|
@@ -1234,14 +1255,15 @@ class BrsFile {
|
|
|
1234
1255
|
}
|
|
1235
1256
|
getHover(position) {
|
|
1236
1257
|
var _a, _b, _c;
|
|
1258
|
+
const fence = (code) => util_1.util.mdFence(code, 'brightscript');
|
|
1237
1259
|
//get the token at the position
|
|
1238
1260
|
let token = this.parser.getTokenAt(position);
|
|
1239
1261
|
let hoverTokenTypes = [
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1262
|
+
TokenKind_1.TokenKind.Identifier,
|
|
1263
|
+
TokenKind_1.TokenKind.Function,
|
|
1264
|
+
TokenKind_1.TokenKind.EndFunction,
|
|
1265
|
+
TokenKind_1.TokenKind.Sub,
|
|
1266
|
+
TokenKind_1.TokenKind.EndSub
|
|
1245
1267
|
];
|
|
1246
1268
|
//throw out invalid tokens and the wrong kind of tokens
|
|
1247
1269
|
if (!token || !hoverTokenTypes.includes(token.kind)) {
|
|
@@ -1262,48 +1284,95 @@ class BrsFile {
|
|
|
1262
1284
|
}
|
|
1263
1285
|
}
|
|
1264
1286
|
}
|
|
1265
|
-
const typeTexts =
|
|
1266
|
-
|
|
1287
|
+
const typeTexts = new Set();
|
|
1288
|
+
const fileScopes = this.program.getScopesForFile(this).sort((a, b) => { var _a; return (_a = a.dependencyGraphKey) === null || _a === void 0 ? void 0 : _a.localeCompare(b.dependencyGraphKey); });
|
|
1289
|
+
const callables = [];
|
|
1290
|
+
for (const scope of fileScopes) {
|
|
1267
1291
|
scope.linkSymbolTable();
|
|
1292
|
+
const typeContext = { file: this, scope: scope, position: position };
|
|
1268
1293
|
const typeTextPair = this.getSymbolTypeFromToken(token, func, scope);
|
|
1269
1294
|
if (typeTextPair) {
|
|
1270
1295
|
let scopeTypeText = '';
|
|
1271
1296
|
if ((0, reflection_1.isFunctionType)(typeTextPair.type)) {
|
|
1272
|
-
scopeTypeText = (_b = typeTextPair.type) === null || _b === void 0 ? void 0 : _b.toString();
|
|
1297
|
+
scopeTypeText = (_b = typeTextPair.type) === null || _b === void 0 ? void 0 : _b.toString(typeContext);
|
|
1298
|
+
//keep unique references to the callables for this function
|
|
1299
|
+
if (!typeTexts.has(scopeTypeText)) {
|
|
1300
|
+
callables.push(scope.getCallableByName(lowerTokenText));
|
|
1301
|
+
}
|
|
1273
1302
|
}
|
|
1274
1303
|
else if (typeTextPair.useExpandedTextOnly) {
|
|
1275
1304
|
scopeTypeText = typeTextPair.expandedTokenText;
|
|
1276
1305
|
}
|
|
1277
1306
|
else {
|
|
1278
|
-
scopeTypeText = `${typeTextPair.expandedTokenText} as ${(_c = typeTextPair.type) === null || _c === void 0 ? void 0 : _c.toString()}`;
|
|
1307
|
+
scopeTypeText = `${typeTextPair.expandedTokenText} as ${(_c = typeTextPair.type) === null || _c === void 0 ? void 0 : _c.toString(typeContext)}`;
|
|
1279
1308
|
}
|
|
1280
|
-
if (scopeTypeText
|
|
1281
|
-
typeTexts.
|
|
1309
|
+
if (scopeTypeText) {
|
|
1310
|
+
typeTexts.add(scopeTypeText);
|
|
1282
1311
|
}
|
|
1283
1312
|
}
|
|
1284
1313
|
scope.unlinkSymbolTable();
|
|
1285
1314
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1315
|
+
if (callables.length === typeTexts.size) {
|
|
1316
|
+
//this is a function in all scopes, so build the function hover
|
|
1317
|
+
return {
|
|
1318
|
+
range: token.range,
|
|
1319
|
+
contents: this.getCallableDocumentation([...typeTexts], callables)
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1322
|
+
else if ((typeTexts === null || typeTexts === void 0 ? void 0 : typeTexts.size) > 0) {
|
|
1323
|
+
const typeText = [...typeTexts].join(' | ');
|
|
1288
1324
|
return {
|
|
1289
1325
|
range: token.range,
|
|
1290
|
-
contents: typeText
|
|
1326
|
+
contents: fence(typeText)
|
|
1291
1327
|
};
|
|
1292
1328
|
}
|
|
1293
1329
|
}
|
|
1294
|
-
//look through all callables in relevant scopes
|
|
1295
|
-
{
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1330
|
+
// //look through all callables in relevant scopes
|
|
1331
|
+
// {
|
|
1332
|
+
// let scopes = this.program.getScopesForFile(this);
|
|
1333
|
+
// for (let scope of scopes) {
|
|
1334
|
+
// let callable = scope.getCallableByName(lowerTokenText);
|
|
1335
|
+
// if (callable) {
|
|
1336
|
+
// return {
|
|
1337
|
+
// range: token.range,
|
|
1338
|
+
// contents: this.getCallableDocumentation(callables)
|
|
1339
|
+
// };
|
|
1340
|
+
// }
|
|
1341
|
+
// }
|
|
1342
|
+
// }
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Build a hover documentation for a callable.
|
|
1346
|
+
*/
|
|
1347
|
+
getCallableDocumentation(typeTexts, callables) {
|
|
1348
|
+
var _a;
|
|
1349
|
+
const callable = callables[0];
|
|
1350
|
+
const typeText = typeTexts[0];
|
|
1351
|
+
const comments = [];
|
|
1352
|
+
const tokens = callable === null || callable === void 0 ? void 0 : callable.file.parser.tokens;
|
|
1353
|
+
const idx = tokens === null || tokens === void 0 ? void 0 : tokens.indexOf((_a = callable.functionStatement) === null || _a === void 0 ? void 0 : _a.func.functionType);
|
|
1354
|
+
for (let i = idx - 1; i >= 0; i--) {
|
|
1355
|
+
const token = tokens[i];
|
|
1356
|
+
//skip whitespace and newline chars
|
|
1357
|
+
if (token.kind === TokenKind_1.TokenKind.Comment) {
|
|
1358
|
+
comments.push(token);
|
|
1359
|
+
}
|
|
1360
|
+
else if (token.kind === TokenKind_1.TokenKind.Newline || token.kind === TokenKind_1.TokenKind.Whitespace) {
|
|
1361
|
+
//skip these tokens
|
|
1362
|
+
continue;
|
|
1363
|
+
//any other token means there are no more comments
|
|
1364
|
+
}
|
|
1365
|
+
else {
|
|
1366
|
+
break;
|
|
1305
1367
|
}
|
|
1306
1368
|
}
|
|
1369
|
+
//message indicating if there are variations. example: (+3 variations) if there are 4 unique function signatures
|
|
1370
|
+
const multiText = callables.length > 1 ? ` (+${callables.length - 1} variations)` : '';
|
|
1371
|
+
let result = util_1.util.mdFence(typeText + multiText, 'brightscript');
|
|
1372
|
+
if (comments.length > 0) {
|
|
1373
|
+
result += '\n***\n' + comments.reverse().map(x => x.text.replace(/^('|rem)/i, '')).join('\n');
|
|
1374
|
+
}
|
|
1375
|
+
return result;
|
|
1307
1376
|
}
|
|
1308
1377
|
getSignatureHelpForNamespaceMethods(callableName, dottedGetText, scope) {
|
|
1309
1378
|
var _a;
|
|
@@ -1351,12 +1420,12 @@ class BrsFile {
|
|
|
1351
1420
|
}
|
|
1352
1421
|
}
|
|
1353
1422
|
const kind = currentToken.kind;
|
|
1354
|
-
if (kind ===
|
|
1423
|
+
if (kind === TokenKind_1.TokenKind.Comment) {
|
|
1355
1424
|
// Strip off common leading characters to make it easier to read
|
|
1356
1425
|
const commentText = currentToken.text.replace(/^[' *\/]+/, '');
|
|
1357
1426
|
functionComments.unshift(commentText);
|
|
1358
1427
|
}
|
|
1359
|
-
else if (kind ===
|
|
1428
|
+
else if (kind === TokenKind_1.TokenKind.Newline) {
|
|
1360
1429
|
if (functionComments.length === 0) {
|
|
1361
1430
|
continue;
|
|
1362
1431
|
}
|
|
@@ -1416,7 +1485,7 @@ class BrsFile {
|
|
|
1416
1485
|
const classConstructor = this.getClassMethod(classStatement, 'new');
|
|
1417
1486
|
let sigHelp = classConstructor ? this.getSignatureHelpForStatement(classConstructor) : undefined;
|
|
1418
1487
|
if (sigHelp) {
|
|
1419
|
-
sigHelp.key = classStatement.getName(
|
|
1488
|
+
sigHelp.key = classStatement.getName(Parser_1.ParseMode.BrighterScript);
|
|
1420
1489
|
sigHelp.signature.label = sigHelp.signature.label.replace(/(function|sub) new/, sigHelp.key);
|
|
1421
1490
|
}
|
|
1422
1491
|
return sigHelp;
|
|
@@ -1493,7 +1562,7 @@ exports.BrsFile = BrsFile;
|
|
|
1493
1562
|
* List of completions for all valid keywords/reserved words.
|
|
1494
1563
|
* Build this list once because it won't change for the lifetime of this process
|
|
1495
1564
|
*/
|
|
1496
|
-
exports.KeywordCompletions = Object.keys(
|
|
1565
|
+
exports.KeywordCompletions = Object.keys(TokenKind_1.Keywords)
|
|
1497
1566
|
//remove any keywords with whitespace
|
|
1498
1567
|
.filter(x => !x.includes(' '))
|
|
1499
1568
|
//create completions
|