brighterscript 1.0.0-alpha.13 → 1.0.0-alpha.16
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 +87 -2
- package/dist/Cache.d.ts +3 -8
- package/dist/Cache.js +9 -14
- package/dist/Cache.js.map +1 -1
- package/dist/DependencyGraph.js +5 -4
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +21 -1
- package/dist/DiagnosticMessages.js +21 -1
- package/dist/DiagnosticMessages.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 +108 -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 +29 -15
- package/dist/Scope.js +68 -28
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +1 -1
- package/dist/XmlScope.d.ts +3 -3
- package/dist/astUtils/AstEditor.d.ts +6 -0
- package/dist/astUtils/AstEditor.js +10 -0
- package/dist/astUtils/AstEditor.js.map +1 -1
- package/dist/astUtils/AstEditor.spec.js +37 -0
- package/dist/astUtils/AstEditor.spec.js.map +1 -1
- package/dist/astUtils/creators.d.ts +8 -4
- package/dist/astUtils/creators.js +87 -6
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +5 -1
- package/dist/astUtils/reflection.js +15 -3
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +11 -10
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +3 -1
- package/dist/astUtils/visitors.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.d.ts +4 -1
- package/dist/bscPlugin/BscPlugin.js +21 -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 +9 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +97 -0
- 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} +30 -2
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +36 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +94 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/diagnosticUtils.js +3 -3
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +382 -232
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +26 -12
- package/dist/files/BrsFile.js +268 -119
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +570 -168
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +11 -10
- package/dist/files/XmlFile.js +16 -11
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +60 -58
- 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 +63 -35
- package/dist/lexer/Lexer.js +1 -2
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +470 -462
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +2 -0
- package/dist/lexer/TokenKind.js +5 -0
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/Expression.d.ts +18 -16
- package/dist/parser/Expression.js +57 -48
- 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 +28 -7
- package/dist/parser/Parser.js +508 -296
- 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 +80 -20
- package/dist/parser/Statement.js +257 -92
- 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/Enum.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +774 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +46 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +37 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- 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 +7 -6
- package/dist/types/FunctionType.js +21 -18
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/FunctionType.spec.js +6 -0
- package/dist/types/FunctionType.spec.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/UniversalFunctionType.d.ts +9 -0
- package/dist/types/UniversalFunctionType.js +25 -0
- package/dist/types/UniversalFunctionType.js.map +1 -0
- package/dist/types/helpers.js +1 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +26 -10
- package/dist/util.js +145 -61
- 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 +3 -3
- 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 +0 -63
- 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
|
@@ -12,7 +12,8 @@ const IntegerType_1 = require("../types/IntegerType");
|
|
|
12
12
|
const StringType_1 = require("../types/StringType");
|
|
13
13
|
const BrsFile_1 = require("./BrsFile");
|
|
14
14
|
const source_map_1 = require("source-map");
|
|
15
|
-
const
|
|
15
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
16
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
16
17
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
17
18
|
const util_1 = require("../util");
|
|
18
19
|
const PluginInterface_1 = require("../PluginInterface");
|
|
@@ -20,6 +21,9 @@ const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
|
20
21
|
const Parser_1 = require("../parser/Parser");
|
|
21
22
|
const Logger_1 = require("../Logger");
|
|
22
23
|
const VoidType_1 = require("../types/VoidType");
|
|
24
|
+
const FloatType_1 = require("../types/FloatType");
|
|
25
|
+
const ObjectType_1 = require("../types/ObjectType");
|
|
26
|
+
const ArrayType_1 = require("../types/ArrayType");
|
|
23
27
|
let sinon = sinonImport.createSandbox();
|
|
24
28
|
describe('BrsFile', () => {
|
|
25
29
|
let rootDir = (0, util_1.standardizePath) `${process.cwd()}/.tmp/rootDir`;
|
|
@@ -37,24 +41,22 @@ describe('BrsFile', () => {
|
|
|
37
41
|
program.dispose();
|
|
38
42
|
});
|
|
39
43
|
it('supports the third parameter in CreateObject', () => {
|
|
40
|
-
var _a;
|
|
41
44
|
program.setFile('source/main.brs', `
|
|
42
45
|
sub main()
|
|
43
46
|
regexp = CreateObject("roRegex", "[a-z]+", "i")
|
|
44
47
|
end sub
|
|
45
48
|
`);
|
|
46
49
|
program.validate();
|
|
47
|
-
(0,
|
|
50
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
48
51
|
});
|
|
49
52
|
it('supports the 6 params in CreateObject for roRegion', () => {
|
|
50
|
-
var _a;
|
|
51
53
|
program.setFile('source/main.brs', `
|
|
52
54
|
sub createRegion(bitmap as object)
|
|
53
55
|
region = CreateObject("roRegion", bitmap, 20, 40, 100, 200)
|
|
54
56
|
end sub
|
|
55
57
|
`);
|
|
56
58
|
program.validate();
|
|
57
|
-
(0,
|
|
59
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
58
60
|
});
|
|
59
61
|
it('sets needsTranspiled to true for .bs files', () => {
|
|
60
62
|
//BrightScript
|
|
@@ -69,8 +71,7 @@ describe('BrsFile', () => {
|
|
|
69
71
|
range: undefined
|
|
70
72
|
}];
|
|
71
73
|
file.addDiagnostics(expected);
|
|
72
|
-
|
|
73
|
-
(0, chai_1.expect)(actual).deep.equal(expected);
|
|
74
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, expected);
|
|
74
75
|
});
|
|
75
76
|
describe('getPartialVariableName', () => {
|
|
76
77
|
let entry = {
|
|
@@ -157,6 +158,76 @@ describe('BrsFile', () => {
|
|
|
157
158
|
(0, chai_1.expect)(names).to.includes('Main');
|
|
158
159
|
(0, chai_1.expect)(names).to.includes('SayHello');
|
|
159
160
|
});
|
|
161
|
+
it('includes every type of item at base level', () => {
|
|
162
|
+
program.setFile('source/main.bs', `
|
|
163
|
+
sub main()
|
|
164
|
+
print
|
|
165
|
+
end sub
|
|
166
|
+
sub speak()
|
|
167
|
+
end sub
|
|
168
|
+
namespace stuff
|
|
169
|
+
end namespace
|
|
170
|
+
class Person
|
|
171
|
+
end class
|
|
172
|
+
enum Direction
|
|
173
|
+
end enum
|
|
174
|
+
`);
|
|
175
|
+
(0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 26)), [{
|
|
176
|
+
label: 'main',
|
|
177
|
+
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
178
|
+
}, {
|
|
179
|
+
label: 'speak',
|
|
180
|
+
kind: vscode_languageserver_1.CompletionItemKind.Function
|
|
181
|
+
}, {
|
|
182
|
+
label: 'stuff',
|
|
183
|
+
kind: vscode_languageserver_1.CompletionItemKind.Module
|
|
184
|
+
}, {
|
|
185
|
+
label: 'Person',
|
|
186
|
+
kind: vscode_languageserver_1.CompletionItemKind.Class
|
|
187
|
+
}, {
|
|
188
|
+
label: 'Direction',
|
|
189
|
+
kind: vscode_languageserver_1.CompletionItemKind.Enum
|
|
190
|
+
}]);
|
|
191
|
+
});
|
|
192
|
+
describe('namespaces', () => {
|
|
193
|
+
it('gets full namespace completions at any point through the leading identifier', () => {
|
|
194
|
+
program.setFile('source/main.bs', `
|
|
195
|
+
sub main()
|
|
196
|
+
foo.bar
|
|
197
|
+
end sub
|
|
198
|
+
|
|
199
|
+
namespace foo.bar
|
|
200
|
+
end namespace
|
|
201
|
+
|
|
202
|
+
class Person
|
|
203
|
+
end class
|
|
204
|
+
`);
|
|
205
|
+
const result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 24)).map(x => x.label);
|
|
206
|
+
(0, chai_1.expect)(result).includes('main');
|
|
207
|
+
(0, chai_1.expect)(result).includes('foo');
|
|
208
|
+
(0, chai_1.expect)(result).includes('Person');
|
|
209
|
+
});
|
|
210
|
+
it('gets namespace completions', () => {
|
|
211
|
+
program.setFile('source/main.bs', `
|
|
212
|
+
namespace foo.bar
|
|
213
|
+
function sayHello()
|
|
214
|
+
end function
|
|
215
|
+
end namespace
|
|
216
|
+
|
|
217
|
+
sub Main()
|
|
218
|
+
print "hello"
|
|
219
|
+
foo.ba
|
|
220
|
+
foo.bar.
|
|
221
|
+
end sub
|
|
222
|
+
`);
|
|
223
|
+
let result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 30));
|
|
224
|
+
let names = result.map(x => x.label);
|
|
225
|
+
(0, chai_1.expect)(names).to.includes('bar');
|
|
226
|
+
result = program.getCompletions(`${rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(9, 32));
|
|
227
|
+
names = result.map(x => x.label);
|
|
228
|
+
(0, chai_1.expect)(names).to.includes('sayHello');
|
|
229
|
+
});
|
|
230
|
+
});
|
|
160
231
|
it('always includes `m`', () => {
|
|
161
232
|
//eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
162
233
|
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
@@ -182,7 +253,7 @@ describe('BrsFile', () => {
|
|
|
182
253
|
|
|
183
254
|
end sub
|
|
184
255
|
`);
|
|
185
|
-
let keywords = Object.keys(
|
|
256
|
+
let keywords = Object.keys(TokenKind_1.Keywords).filter(x => !x.includes(' '));
|
|
186
257
|
//inside the function
|
|
187
258
|
let result = program.getCompletions(`${rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
|
|
188
259
|
let names = result.map(x => x.label);
|
|
@@ -285,7 +356,6 @@ describe('BrsFile', () => {
|
|
|
285
356
|
describe('comment flags', () => {
|
|
286
357
|
describe('bs:disable-next-line', () => {
|
|
287
358
|
it('disables critical diagnostic issues', () => {
|
|
288
|
-
var _a, _b;
|
|
289
359
|
program.setFile('source/main.brs', `
|
|
290
360
|
sub main()
|
|
291
361
|
Dim requestData
|
|
@@ -293,19 +363,18 @@ describe('BrsFile', () => {
|
|
|
293
363
|
`);
|
|
294
364
|
//should have an error
|
|
295
365
|
program.validate();
|
|
296
|
-
(0,
|
|
366
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(program);
|
|
297
367
|
program.setFile('source/main.brs', `
|
|
298
368
|
sub main()
|
|
299
369
|
'bs:disable-next-line
|
|
300
370
|
Dim requestData
|
|
301
371
|
end sub
|
|
302
372
|
`);
|
|
303
|
-
//should have an error
|
|
373
|
+
//should not have an error
|
|
304
374
|
program.validate();
|
|
305
|
-
(0,
|
|
375
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
306
376
|
});
|
|
307
377
|
it('works with leading whitespace', () => {
|
|
308
|
-
var _a;
|
|
309
378
|
program.setFile('source/main.brs', `
|
|
310
379
|
sub main()
|
|
311
380
|
' bs:disable-next-line
|
|
@@ -314,10 +383,9 @@ describe('BrsFile', () => {
|
|
|
314
383
|
`);
|
|
315
384
|
//should have an error
|
|
316
385
|
program.validate();
|
|
317
|
-
(0,
|
|
386
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
318
387
|
});
|
|
319
388
|
it('works for all', () => {
|
|
320
|
-
var _a;
|
|
321
389
|
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
322
390
|
sub Main()
|
|
323
391
|
'bs:disable-next-line
|
|
@@ -332,10 +400,9 @@ describe('BrsFile', () => {
|
|
|
332
400
|
});
|
|
333
401
|
program.validate();
|
|
334
402
|
//the "unterminated string" error should be filtered out
|
|
335
|
-
(0,
|
|
403
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
336
404
|
});
|
|
337
405
|
it('works for specific codes', () => {
|
|
338
|
-
var _a;
|
|
339
406
|
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
340
407
|
sub Main()
|
|
341
408
|
'bs:disable-next-line: 1083, 1001
|
|
@@ -349,18 +416,17 @@ describe('BrsFile', () => {
|
|
|
349
416
|
affectedRange: util_1.default.createRange(3, 0, 3, Number.MAX_SAFE_INTEGER)
|
|
350
417
|
});
|
|
351
418
|
//the "unterminated string" error should be filtered out
|
|
352
|
-
(0,
|
|
419
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
353
420
|
});
|
|
354
421
|
it('recognizes non-numeric codes', () => {
|
|
355
|
-
var _a;
|
|
356
422
|
let file = program.setFile('source/main.brs', `
|
|
357
423
|
sub Main()
|
|
358
424
|
'bs:disable-next-line: LINT9999
|
|
359
425
|
name = "bob
|
|
360
426
|
end sub
|
|
361
|
-
|
|
427
|
+
`);
|
|
362
428
|
(0, chai_1.expect)(file.commentFlags[0]).to.exist;
|
|
363
|
-
(0,
|
|
429
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(program);
|
|
364
430
|
});
|
|
365
431
|
it('supports disabling non-numeric error codes', () => {
|
|
366
432
|
const program = new Program_1.Program({});
|
|
@@ -368,34 +434,29 @@ describe('BrsFile', () => {
|
|
|
368
434
|
sub main()
|
|
369
435
|
something = true 'bs:disable-line: LINT1005
|
|
370
436
|
end sub
|
|
371
|
-
|
|
437
|
+
`);
|
|
372
438
|
file.addDiagnostics([{
|
|
373
439
|
code: 'LINT1005',
|
|
374
440
|
file: file,
|
|
375
441
|
message: 'Something is not right',
|
|
376
442
|
range: util_1.default.createRange(2, 16, 2, 26)
|
|
377
443
|
}]);
|
|
378
|
-
|
|
444
|
+
const scope = program.getScopesForFile(file)[0];
|
|
445
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(scope);
|
|
379
446
|
});
|
|
380
447
|
it('adds diagnostics for unknown numeric diagnostic codes', () => {
|
|
381
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
448
|
+
program.setFile({ src: `${rootDir} / source / main.brs`, dest: 'source/main.brs' }, `
|
|
382
449
|
sub main()
|
|
383
450
|
print "hi" 'bs:disable-line: 123456 999999 aaaab
|
|
384
451
|
end sub
|
|
385
|
-
|
|
452
|
+
`);
|
|
386
453
|
program.validate();
|
|
387
|
-
(0,
|
|
388
|
-
(0, chai_1.expect)(program.getDiagnostics()[0]).to.deep.include({
|
|
389
|
-
range: vscode_languageserver_1.Range.create(2, 53, 2, 59)
|
|
390
|
-
});
|
|
391
|
-
(0, chai_1.expect)(program.getDiagnostics()[1]).to.deep.include({
|
|
392
|
-
range: vscode_languageserver_1.Range.create(2, 60, 2, 66)
|
|
393
|
-
});
|
|
454
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(123456)), { range: vscode_languageserver_1.Range.create(2, 53, 2, 59) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(999999)), { range: vscode_languageserver_1.Range.create(2, 60, 2, 66) })]);
|
|
394
455
|
});
|
|
395
456
|
});
|
|
396
457
|
describe('bs:disable-line', () => {
|
|
397
458
|
it('works for all', () => {
|
|
398
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
459
|
+
let file = program.setFile({ src: `${rootDir} / source / main.brs`, dest: 'source/main.brs' }, `
|
|
399
460
|
sub Main()
|
|
400
461
|
z::;;%%%%%% 'bs:disable-line
|
|
401
462
|
end sub
|
|
@@ -408,10 +469,10 @@ describe('BrsFile', () => {
|
|
|
408
469
|
});
|
|
409
470
|
program.validate();
|
|
410
471
|
//the "unterminated string" error should be filtered out
|
|
411
|
-
(0,
|
|
472
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
412
473
|
});
|
|
413
474
|
it('works for specific codes', () => {
|
|
414
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
475
|
+
program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
415
476
|
sub main()
|
|
416
477
|
'should not have any errors
|
|
417
478
|
DoSomething(1) 'bs:disable-line:1002
|
|
@@ -422,23 +483,22 @@ describe('BrsFile', () => {
|
|
|
422
483
|
end sub
|
|
423
484
|
`);
|
|
424
485
|
program.validate();
|
|
425
|
-
(0,
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
});
|
|
486
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [{
|
|
487
|
+
range: vscode_languageserver_1.Range.create(5, 24, 5, 35)
|
|
488
|
+
}]);
|
|
429
489
|
});
|
|
430
490
|
it('handles the erraneous `stop` keyword', () => {
|
|
431
491
|
//the current version of BRS causes parse errors after the `parse` keyword, showing error in comments
|
|
432
492
|
//the program should ignore all diagnostics found in brs:* comment lines EXCEPT
|
|
433
493
|
//for the diagnostics about using unknown error codes
|
|
434
|
-
program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
494
|
+
program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
435
495
|
sub main()
|
|
436
496
|
stop 'bs:disable-line
|
|
437
497
|
print "need a valid line to fix stop error"
|
|
438
498
|
end sub
|
|
439
|
-
|
|
499
|
+
`);
|
|
440
500
|
program.validate();
|
|
441
|
-
(0,
|
|
501
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
442
502
|
});
|
|
443
503
|
});
|
|
444
504
|
});
|
|
@@ -446,9 +506,9 @@ describe('BrsFile', () => {
|
|
|
446
506
|
it('supports iife in assignment', () => {
|
|
447
507
|
program.setFile('source/main.brs', `
|
|
448
508
|
sub main()
|
|
449
|
-
|
|
509
|
+
result = sub()
|
|
450
510
|
end sub()
|
|
451
|
-
|
|
511
|
+
result = (sub()
|
|
452
512
|
end sub)()
|
|
453
513
|
end sub
|
|
454
514
|
`);
|
|
@@ -467,26 +527,26 @@ describe('BrsFile', () => {
|
|
|
467
527
|
testParseMode('source/main.spec.bs', Parser_1.ParseMode.BrighterScript);
|
|
468
528
|
});
|
|
469
529
|
it('supports labels and goto statements', () => {
|
|
470
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
530
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
471
531
|
sub Main()
|
|
472
532
|
'multiple goto statements on one line
|
|
473
|
-
goto myLabel
|
|
533
|
+
goto myLabel: goto myLabel
|
|
474
534
|
myLabel:
|
|
475
535
|
end sub
|
|
476
536
|
`);
|
|
477
|
-
(0,
|
|
537
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
478
538
|
});
|
|
479
539
|
it('supports empty print statements', () => {
|
|
480
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
540
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
481
541
|
sub main()
|
|
482
|
-
|
|
542
|
+
print
|
|
483
543
|
end sub
|
|
484
544
|
`);
|
|
485
|
-
(0,
|
|
545
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
486
546
|
});
|
|
487
547
|
describe('conditional compile', () => {
|
|
488
548
|
it('works for upper case keywords', () => {
|
|
489
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
549
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
490
550
|
sub main()
|
|
491
551
|
#CONST someFlag = true
|
|
492
552
|
#IF someFlag
|
|
@@ -498,10 +558,10 @@ describe('BrsFile', () => {
|
|
|
498
558
|
#ENDIF
|
|
499
559
|
end sub
|
|
500
560
|
`);
|
|
501
|
-
(0,
|
|
561
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
502
562
|
});
|
|
503
563
|
it('supports single-word #elseif and #endif', () => {
|
|
504
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
564
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
505
565
|
sub main()
|
|
506
566
|
#const someFlag = true
|
|
507
567
|
#if someFlag
|
|
@@ -511,10 +571,10 @@ describe('BrsFile', () => {
|
|
|
511
571
|
#endif
|
|
512
572
|
end sub
|
|
513
573
|
`);
|
|
514
|
-
(0,
|
|
574
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
515
575
|
});
|
|
516
576
|
it('supports multi-word #else if and #end if', () => {
|
|
517
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
577
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
518
578
|
sub main()
|
|
519
579
|
#const someFlag = true
|
|
520
580
|
#if someFlag
|
|
@@ -524,84 +584,93 @@ describe('BrsFile', () => {
|
|
|
524
584
|
#end if
|
|
525
585
|
end sub
|
|
526
586
|
`);
|
|
527
|
-
(0,
|
|
587
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
528
588
|
});
|
|
529
589
|
it('does not choke on invalid code inside a false conditional compile', () => {
|
|
530
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
590
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
531
591
|
sub main()
|
|
532
592
|
#if false
|
|
533
|
-
non-commented code here should not cause parse errors
|
|
593
|
+
non - commented code here should not cause parse errors
|
|
534
594
|
#end if
|
|
535
595
|
end sub
|
|
536
596
|
`);
|
|
537
|
-
(0,
|
|
597
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
538
598
|
});
|
|
539
599
|
it('detects syntax error in #if', () => {
|
|
540
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
600
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
541
601
|
sub main()
|
|
542
602
|
#if true1
|
|
543
603
|
print "true"
|
|
544
604
|
#end if
|
|
545
605
|
end sub
|
|
546
606
|
`);
|
|
547
|
-
(0,
|
|
607
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
608
|
+
DiagnosticMessages_1.DiagnosticMessages.referencedConstDoesNotExist()
|
|
609
|
+
]);
|
|
548
610
|
});
|
|
549
611
|
it('detects syntax error in #const', () => {
|
|
550
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
612
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
551
613
|
sub main()
|
|
552
614
|
#if %
|
|
553
615
|
print "true"
|
|
554
616
|
#end if
|
|
555
617
|
end sub
|
|
556
618
|
`);
|
|
557
|
-
(0,
|
|
619
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
620
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedCharacter('%'),
|
|
621
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashIfValue()
|
|
622
|
+
]);
|
|
558
623
|
});
|
|
559
624
|
it('detects #const name using reserved word', () => {
|
|
560
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
625
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
561
626
|
sub main()
|
|
562
627
|
#const function = true
|
|
563
628
|
end sub
|
|
564
629
|
`);
|
|
565
|
-
(0,
|
|
630
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
631
|
+
DiagnosticMessages_1.DiagnosticMessages.constNameCannotBeReservedWord(),
|
|
632
|
+
DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('#const')
|
|
633
|
+
]);
|
|
566
634
|
});
|
|
567
635
|
it('detects syntax error in #const', () => {
|
|
568
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
636
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
569
637
|
sub main()
|
|
570
638
|
#const someConst = 123
|
|
571
639
|
end sub
|
|
572
640
|
`);
|
|
573
|
-
(0,
|
|
641
|
+
(0, testHelpers_spec_1.expectDiagnostics)(file, [
|
|
642
|
+
DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue()
|
|
643
|
+
]);
|
|
574
644
|
});
|
|
575
645
|
});
|
|
576
646
|
it('supports stop statement', () => {
|
|
577
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
647
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
578
648
|
sub main()
|
|
579
|
-
|
|
649
|
+
stop
|
|
580
650
|
end sub
|
|
581
651
|
`);
|
|
582
|
-
(0,
|
|
652
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
583
653
|
});
|
|
584
654
|
it('supports single-line if statements', () => {
|
|
585
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
655
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
586
656
|
sub main()
|
|
587
657
|
if 1 < 2: return true: end if
|
|
588
658
|
if 1 < 2: return true
|
|
589
659
|
end if
|
|
590
660
|
if false : print "true" : end if
|
|
591
661
|
if true: print "8 worked": else if true: print "not run": else: print "not run": end if
|
|
592
|
-
if true then
|
|
662
|
+
if true then: test = sub() : print "yes" : end sub: end if
|
|
593
663
|
end sub
|
|
594
664
|
`);
|
|
595
|
-
(0,
|
|
665
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
596
666
|
});
|
|
597
667
|
it('supports line_num as global variable', () => {
|
|
598
|
-
var _a;
|
|
599
668
|
file.parse(`
|
|
600
669
|
sub Main()
|
|
601
670
|
print LINE_NUM
|
|
602
671
|
end sub
|
|
603
672
|
`);
|
|
604
|
-
(0,
|
|
673
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
605
674
|
});
|
|
606
675
|
it('supports many keywords as object property names', () => {
|
|
607
676
|
file.parse(`
|
|
@@ -667,7 +736,7 @@ describe('BrsFile', () => {
|
|
|
667
736
|
person.new = true
|
|
668
737
|
end sub
|
|
669
738
|
`);
|
|
670
|
-
(0,
|
|
739
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
671
740
|
});
|
|
672
741
|
it('does not error on numeric literal type designators', () => {
|
|
673
742
|
file.parse(`
|
|
@@ -675,13 +744,13 @@ describe('BrsFile', () => {
|
|
|
675
744
|
print &he2
|
|
676
745
|
print 1.2E+2
|
|
677
746
|
print 2!
|
|
678
|
-
print 12D-12
|
|
747
|
+
print 12D - 12
|
|
679
748
|
print 2.3#
|
|
680
749
|
print &hFEDCBA9876543210&
|
|
681
750
|
print 9876543210&
|
|
682
751
|
end sub
|
|
683
752
|
`);
|
|
684
|
-
(0,
|
|
753
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
685
754
|
});
|
|
686
755
|
it('does not error when encountering sub with return type', () => {
|
|
687
756
|
file.parse(`
|
|
@@ -689,7 +758,7 @@ describe('BrsFile', () => {
|
|
|
689
758
|
return
|
|
690
759
|
end sub
|
|
691
760
|
`);
|
|
692
|
-
(0,
|
|
761
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
693
762
|
});
|
|
694
763
|
it('does not lose function statements when mismatched end sub', () => {
|
|
695
764
|
file.parse(`
|
|
@@ -724,7 +793,7 @@ describe('BrsFile', () => {
|
|
|
724
793
|
foo.bar = true and false or 3 > 4
|
|
725
794
|
end sub
|
|
726
795
|
`);
|
|
727
|
-
(0,
|
|
796
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
728
797
|
});
|
|
729
798
|
it('does not error with boolean in RHS of set statement', () => {
|
|
730
799
|
file.parse(`
|
|
@@ -737,57 +806,57 @@ describe('BrsFile', () => {
|
|
|
737
806
|
m.isTrue = m.isTrue = m.isTrue
|
|
738
807
|
end sub
|
|
739
808
|
`);
|
|
740
|
-
(0,
|
|
809
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
741
810
|
});
|
|
742
811
|
it('supports variable names ending with type designators', () => {
|
|
743
812
|
file.parse(`
|
|
744
813
|
sub main()
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
814
|
+
name$ = "bob"
|
|
815
|
+
age% = 1
|
|
816
|
+
height! = 5.5
|
|
817
|
+
salary# = 9.87654321
|
|
818
|
+
someHex& = 13
|
|
750
819
|
end sub
|
|
751
820
|
`);
|
|
752
|
-
(0,
|
|
821
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
753
822
|
});
|
|
754
823
|
it('supports multiple spaces between two-word keywords', () => {
|
|
755
824
|
file.parse(`
|
|
756
825
|
sub main()
|
|
757
826
|
if true then
|
|
758
827
|
print "true"
|
|
759
|
-
else
|
|
828
|
+
else if true then
|
|
760
829
|
print "also true"
|
|
761
830
|
end if
|
|
762
831
|
end sub
|
|
763
832
|
`);
|
|
764
|
-
(0,
|
|
833
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
765
834
|
});
|
|
766
835
|
it('does not error with `stop` as object key', () => {
|
|
767
836
|
file.parse(`
|
|
768
837
|
function GetObject()
|
|
769
838
|
obj = {
|
|
770
|
-
|
|
839
|
+
stop: function () as void
|
|
771
840
|
|
|
772
|
-
|
|
841
|
+
end function
|
|
773
842
|
}
|
|
774
843
|
return obj
|
|
775
844
|
end function
|
|
776
845
|
`);
|
|
777
|
-
(0,
|
|
846
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
778
847
|
});
|
|
779
848
|
it('does not error with `run` as object key', () => {
|
|
780
849
|
file.parse(`
|
|
781
850
|
function GetObject()
|
|
782
851
|
obj = {
|
|
783
|
-
run: function() as void
|
|
852
|
+
run: function () as void
|
|
784
853
|
|
|
785
854
|
end function
|
|
786
|
-
|
|
855
|
+
}
|
|
787
856
|
return obj
|
|
788
857
|
end function
|
|
789
858
|
`);
|
|
790
|
-
(0,
|
|
859
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
791
860
|
});
|
|
792
861
|
it('supports assignment operators', () => {
|
|
793
862
|
file.parse(`
|
|
@@ -804,28 +873,28 @@ describe('BrsFile', () => {
|
|
|
804
873
|
print x
|
|
805
874
|
end function
|
|
806
875
|
`);
|
|
807
|
-
(0,
|
|
876
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
808
877
|
});
|
|
809
878
|
it('supports `then` as object property', () => {
|
|
810
879
|
file.parse(`
|
|
811
880
|
function Main()
|
|
812
881
|
promise = {
|
|
813
882
|
then: sub()
|
|
814
|
-
|
|
883
|
+
end sub
|
|
815
884
|
}
|
|
816
885
|
promise.then()
|
|
817
886
|
end function
|
|
818
887
|
`);
|
|
819
|
-
(0,
|
|
888
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
820
889
|
});
|
|
821
890
|
it('supports function as parameter type', () => {
|
|
822
891
|
file.parse(`
|
|
823
892
|
sub Main()
|
|
824
|
-
doWork = function(callback as function)
|
|
893
|
+
doWork = function (callback as function)
|
|
825
894
|
end function
|
|
826
895
|
end sub
|
|
827
896
|
`);
|
|
828
|
-
(0,
|
|
897
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
829
898
|
});
|
|
830
899
|
it('supports increment operator', () => {
|
|
831
900
|
file.parse(`
|
|
@@ -834,8 +903,7 @@ describe('BrsFile', () => {
|
|
|
834
903
|
x++
|
|
835
904
|
end function
|
|
836
905
|
`);
|
|
837
|
-
|
|
838
|
-
(0, chai_1.expect)(file.getDiagnostics()).to.be.lengthOf(0);
|
|
906
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
839
907
|
});
|
|
840
908
|
it('supports decrement operator', () => {
|
|
841
909
|
file.parse(`
|
|
@@ -844,8 +912,7 @@ describe('BrsFile', () => {
|
|
|
844
912
|
x--
|
|
845
913
|
end function
|
|
846
914
|
`);
|
|
847
|
-
|
|
848
|
-
(0, chai_1.expect)(file.getDiagnostics()).to.be.lengthOf(0);
|
|
915
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
849
916
|
});
|
|
850
917
|
it('supports writing numbers with decimal but no trailing digit', () => {
|
|
851
918
|
file.parse(`
|
|
@@ -854,7 +921,7 @@ describe('BrsFile', () => {
|
|
|
854
921
|
print x
|
|
855
922
|
end function
|
|
856
923
|
`);
|
|
857
|
-
(0,
|
|
924
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
858
925
|
});
|
|
859
926
|
it('supports assignment operators against object properties', () => {
|
|
860
927
|
file.parse(`
|
|
@@ -876,7 +943,7 @@ describe('BrsFile', () => {
|
|
|
876
943
|
print m.age
|
|
877
944
|
end function
|
|
878
945
|
`);
|
|
879
|
-
(0,
|
|
946
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
880
947
|
});
|
|
881
948
|
//skipped until `brs` supports this
|
|
882
949
|
it('supports bitshift assignment operators', () => {
|
|
@@ -888,7 +955,7 @@ describe('BrsFile', () => {
|
|
|
888
955
|
print x
|
|
889
956
|
end function
|
|
890
957
|
`);
|
|
891
|
-
(0,
|
|
958
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
892
959
|
});
|
|
893
960
|
//skipped until `brs` supports this
|
|
894
961
|
it('supports bitshift assignment operators on objects', () => {
|
|
@@ -900,7 +967,7 @@ describe('BrsFile', () => {
|
|
|
900
967
|
print m.x
|
|
901
968
|
end function
|
|
902
969
|
`);
|
|
903
|
-
(0,
|
|
970
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
904
971
|
});
|
|
905
972
|
it('supports leading and trailing periods for numeric literals', () => {
|
|
906
973
|
file.parse(`
|
|
@@ -911,7 +978,7 @@ describe('BrsFile', () => {
|
|
|
911
978
|
print pointOne
|
|
912
979
|
end function
|
|
913
980
|
`);
|
|
914
|
-
(0,
|
|
981
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
915
982
|
});
|
|
916
983
|
it('supports bitshift assignment operators on object properties accessed by array syntax', () => {
|
|
917
984
|
file.parse(`
|
|
@@ -922,7 +989,7 @@ describe('BrsFile', () => {
|
|
|
922
989
|
print m.x
|
|
923
990
|
end function
|
|
924
991
|
`);
|
|
925
|
-
(0,
|
|
992
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
926
993
|
});
|
|
927
994
|
it('supports weird period AA accessor', () => {
|
|
928
995
|
file.parse(`
|
|
@@ -931,51 +998,55 @@ describe('BrsFile', () => {
|
|
|
931
998
|
print m.["_uuid"]
|
|
932
999
|
end function
|
|
933
1000
|
`);
|
|
934
|
-
(0,
|
|
1001
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
935
1002
|
});
|
|
936
1003
|
it('adds error for library statements NOT at top of file', () => {
|
|
937
|
-
|
|
1004
|
+
program.setFile('source/file.brs', ``);
|
|
1005
|
+
program.setFile('source/main.bs', `
|
|
938
1006
|
sub main()
|
|
939
1007
|
end sub
|
|
940
1008
|
import "file.brs"
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1009
|
+
`);
|
|
1010
|
+
program.validate();
|
|
1011
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1012
|
+
DiagnosticMessages_1.DiagnosticMessages.importStatementMustBeDeclaredAtTopOfFile()
|
|
944
1013
|
]);
|
|
945
1014
|
});
|
|
946
1015
|
it('supports library imports', () => {
|
|
947
|
-
|
|
1016
|
+
program.setFile('source/main.brs', `
|
|
948
1017
|
Library "v30/bslCore.brs"
|
|
949
1018
|
`);
|
|
950
|
-
(0,
|
|
1019
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
951
1020
|
});
|
|
952
1021
|
it('adds error for library statements NOT at top of file', () => {
|
|
953
|
-
|
|
1022
|
+
program.setFile('source/main.brs', `
|
|
954
1023
|
sub main()
|
|
955
1024
|
end sub
|
|
956
1025
|
Library "v30/bslCore.brs"
|
|
957
1026
|
`);
|
|
958
|
-
|
|
959
|
-
|
|
1027
|
+
program.validate();
|
|
1028
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1029
|
+
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()
|
|
960
1030
|
]);
|
|
961
1031
|
});
|
|
962
1032
|
it('adds error for library statements inside of function body', () => {
|
|
963
|
-
|
|
1033
|
+
program.setFile('source/main.brs', `
|
|
964
1034
|
sub main()
|
|
965
1035
|
Library "v30/bslCore.brs"
|
|
966
1036
|
end sub
|
|
967
1037
|
`);
|
|
968
|
-
|
|
969
|
-
|
|
1038
|
+
program.validate();
|
|
1039
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1040
|
+
DiagnosticMessages_1.DiagnosticMessages.libraryStatementMustBeDeclaredAtTopOfFile()
|
|
970
1041
|
]);
|
|
971
1042
|
});
|
|
972
1043
|
it('supports colons as separators in associative array properties', () => {
|
|
973
1044
|
file.parse(`
|
|
974
1045
|
sub Main()
|
|
975
|
-
obj = {x:0 : y: 1}
|
|
1046
|
+
obj = { x: 0 : y: 1 }
|
|
976
1047
|
end sub
|
|
977
1048
|
`);
|
|
978
|
-
(0,
|
|
1049
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
979
1050
|
});
|
|
980
1051
|
it('succeeds when finding variables with "sub" in them', () => {
|
|
981
1052
|
let file = program.setFile('source/main.brs', `
|
|
@@ -990,8 +1061,8 @@ describe('BrsFile', () => {
|
|
|
990
1061
|
});
|
|
991
1062
|
it('succeeds when finding variables with the word "function" in them', () => {
|
|
992
1063
|
file.parse(`
|
|
993
|
-
|
|
994
|
-
|
|
1064
|
+
function Test()
|
|
1065
|
+
typeCheckFunction = RBS_CMN_GetFunction(invalid, methodName)
|
|
995
1066
|
end function
|
|
996
1067
|
`);
|
|
997
1068
|
});
|
|
@@ -1002,14 +1073,14 @@ describe('BrsFile', () => {
|
|
|
1002
1073
|
print "A"
|
|
1003
1074
|
end function
|
|
1004
1075
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1076
|
+
function DoB()
|
|
1077
|
+
print "B"
|
|
1078
|
+
end function
|
|
1008
1079
|
`);
|
|
1009
1080
|
(0, chai_1.expect)(file.callables[0].name).to.equal('DoA');
|
|
1010
1081
|
(0, chai_1.expect)(file.callables[0].nameRange).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 28));
|
|
1011
1082
|
(0, chai_1.expect)(file.callables[1].name).to.equal('DoB');
|
|
1012
|
-
(0, chai_1.expect)(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5,
|
|
1083
|
+
(0, chai_1.expect)(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 25, 5, 28));
|
|
1013
1084
|
});
|
|
1014
1085
|
it('throws an error if the file has already been parsed', () => {
|
|
1015
1086
|
let file = new BrsFile_1.BrsFile('abspath', 'relpath', program);
|
|
@@ -1061,10 +1132,8 @@ describe('BrsFile', () => {
|
|
|
1061
1132
|
function DoSomething
|
|
1062
1133
|
end function
|
|
1063
1134
|
`);
|
|
1064
|
-
(0,
|
|
1065
|
-
(0, chai_1.expect)(file.getDiagnostics()[0]).to.
|
|
1066
|
-
file: file
|
|
1067
|
-
});
|
|
1135
|
+
(0, testHelpers_spec_1.expectHasDiagnostics)(file);
|
|
1136
|
+
(0, chai_1.expect)(file.getDiagnostics()[0].file).to.equal(file);
|
|
1068
1137
|
(0, chai_1.expect)(file.getDiagnostics()[0].range.start.line).to.equal(1);
|
|
1069
1138
|
});
|
|
1070
1139
|
it('supports using the `next` keyword in a for loop', () => {
|
|
@@ -1076,7 +1145,7 @@ describe('BrsFile', () => {
|
|
|
1076
1145
|
next
|
|
1077
1146
|
end sub
|
|
1078
1147
|
`);
|
|
1079
|
-
(0,
|
|
1148
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
1080
1149
|
});
|
|
1081
1150
|
//test is not working yet, but will be enabled when brs supports this syntax
|
|
1082
1151
|
it('supports assigning functions to objects', () => {
|
|
@@ -1089,7 +1158,7 @@ describe('BrsFile', () => {
|
|
|
1089
1158
|
end sub
|
|
1090
1159
|
end function
|
|
1091
1160
|
`);
|
|
1092
|
-
(0,
|
|
1161
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(file);
|
|
1093
1162
|
});
|
|
1094
1163
|
});
|
|
1095
1164
|
describe('findCallables', () => {
|
|
@@ -1210,7 +1279,6 @@ describe('BrsFile', () => {
|
|
|
1210
1279
|
}]);
|
|
1211
1280
|
});
|
|
1212
1281
|
it('finds function calls nested inside statements', () => {
|
|
1213
|
-
var _a;
|
|
1214
1282
|
program.setFile(`source/main.brs`, `
|
|
1215
1283
|
sub main()
|
|
1216
1284
|
if true then
|
|
@@ -1219,7 +1287,9 @@ describe('BrsFile', () => {
|
|
|
1219
1287
|
end sub
|
|
1220
1288
|
`);
|
|
1221
1289
|
program.validate();
|
|
1222
|
-
(0,
|
|
1290
|
+
(0, testHelpers_spec_1.expectDiagnostics)(program, [
|
|
1291
|
+
DiagnosticMessages_1.DiagnosticMessages.callToUnknownFunction('DoesNotExist', 'source')
|
|
1292
|
+
]);
|
|
1223
1293
|
});
|
|
1224
1294
|
it('finds arguments with variable values', () => {
|
|
1225
1295
|
let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
|
|
@@ -1341,13 +1411,13 @@ describe('BrsFile', () => {
|
|
|
1341
1411
|
it('finds variable type from other variable', () => {
|
|
1342
1412
|
file.parse(`
|
|
1343
1413
|
sub Main()
|
|
1344
|
-
|
|
1345
|
-
|
|
1414
|
+
name = "bob"
|
|
1415
|
+
nameCopy = name
|
|
1346
1416
|
end sub
|
|
1347
1417
|
`);
|
|
1348
1418
|
(0, testHelpers_spec_1.expectSymbolTableEquals)(file.parser.references.functionExpressions[0].symbolTable, [
|
|
1349
|
-
['name', new StringType_1.StringType(), util_1.default.createRange(2,
|
|
1350
|
-
['nameCopy', new StringType_1.StringType(), util_1.default.createRange(3,
|
|
1419
|
+
['name', new StringType_1.StringType(), util_1.default.createRange(2, 20, 2, 24)],
|
|
1420
|
+
['nameCopy', new StringType_1.StringType(), util_1.default.createRange(3, 20, 3, 28)]
|
|
1351
1421
|
]);
|
|
1352
1422
|
});
|
|
1353
1423
|
it('sets proper range for functions', () => {
|
|
@@ -1358,7 +1428,6 @@ describe('BrsFile', () => {
|
|
|
1358
1428
|
end function
|
|
1359
1429
|
end sub
|
|
1360
1430
|
`);
|
|
1361
|
-
(0, chai_1.expect)(file.parser.references.functionExpressions).to.be.length(2);
|
|
1362
1431
|
(0, chai_1.expect)(file.parser.references.functionExpressions.map(x => x.range)).to.eql([
|
|
1363
1432
|
util_1.default.createRange(1, 16, 5, 23),
|
|
1364
1433
|
util_1.default.createRange(2, 30, 4, 32)
|
|
@@ -1367,10 +1436,10 @@ describe('BrsFile', () => {
|
|
|
1367
1436
|
});
|
|
1368
1437
|
describe('getHover', () => {
|
|
1369
1438
|
it('works for param types', () => {
|
|
1370
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1439
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1371
1440
|
sub DoSomething(name as string)
|
|
1372
1441
|
name = 1
|
|
1373
|
-
sayMyName = function(name as string)
|
|
1442
|
+
sayMyName = function (name as string)
|
|
1374
1443
|
end function
|
|
1375
1444
|
end sub
|
|
1376
1445
|
`);
|
|
@@ -1385,19 +1454,19 @@ describe('BrsFile', () => {
|
|
|
1385
1454
|
});
|
|
1386
1455
|
//ignore this for now...it's not a huge deal
|
|
1387
1456
|
it('does not match on keywords or data types', () => {
|
|
1388
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1457
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1389
1458
|
sub Main(name as string)
|
|
1390
1459
|
end sub
|
|
1391
|
-
sub as()
|
|
1460
|
+
sub as ()
|
|
1392
1461
|
end sub
|
|
1393
1462
|
`);
|
|
1394
|
-
//hover over the `as`
|
|
1463
|
+
//hover over the `as `
|
|
1395
1464
|
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 31))).not.to.exist;
|
|
1396
1465
|
//hover over the `string`
|
|
1397
1466
|
(0, chai_1.expect)(file.getHover(vscode_languageserver_1.Position.create(1, 36))).not.to.exist;
|
|
1398
1467
|
});
|
|
1399
1468
|
it('finds declared function', () => {
|
|
1400
|
-
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1469
|
+
let file = program.setFile({ src: `${rootDir} /source/main.brs`, dest: 'source/main.brs' }, `
|
|
1401
1470
|
function Main(count = 1)
|
|
1402
1471
|
firstName = "bob"
|
|
1403
1472
|
age = 21
|
|
@@ -1407,7 +1476,11 @@ describe('BrsFile', () => {
|
|
|
1407
1476
|
let hover = file.getHover(vscode_languageserver_1.Position.create(1, 28));
|
|
1408
1477
|
(0, chai_1.expect)(hover).to.exist;
|
|
1409
1478
|
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
|
|
1410
|
-
(0, chai_1.expect)(hover.contents).to.equal(
|
|
1479
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1480
|
+
'```brightscript',
|
|
1481
|
+
'function Main(count? as integer) as dynamic',
|
|
1482
|
+
'```'
|
|
1483
|
+
].join('\n'));
|
|
1411
1484
|
});
|
|
1412
1485
|
it('finds variable function hover in same scope', () => {
|
|
1413
1486
|
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
@@ -1420,7 +1493,35 @@ describe('BrsFile', () => {
|
|
|
1420
1493
|
`);
|
|
1421
1494
|
let hover = file.getHover(vscode_languageserver_1.Position.create(5, 24));
|
|
1422
1495
|
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
|
|
1423
|
-
(0, chai_1.expect)(hover.contents).to.equal(
|
|
1496
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1497
|
+
'```brightscript',
|
|
1498
|
+
'sub (name as string) as void',
|
|
1499
|
+
'```'
|
|
1500
|
+
].join('\n'));
|
|
1501
|
+
});
|
|
1502
|
+
it('does not crash when hovering on built-in functions', async () => {
|
|
1503
|
+
let file = program.setFile('source/main.brs', `
|
|
1504
|
+
function doUcase(text)
|
|
1505
|
+
return ucase(text)
|
|
1506
|
+
end function
|
|
1507
|
+
`);
|
|
1508
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 30))).contents).to.equal([
|
|
1509
|
+
'```brightscript',
|
|
1510
|
+
'function UCase(s as string) as string',
|
|
1511
|
+
'```'
|
|
1512
|
+
].join('\n'));
|
|
1513
|
+
});
|
|
1514
|
+
it('does not crash when hovering on object method call', async () => {
|
|
1515
|
+
let file = program.setFile('source/main.brs', `
|
|
1516
|
+
function getInstr(url, text)
|
|
1517
|
+
return url.instr(text)
|
|
1518
|
+
end function
|
|
1519
|
+
`);
|
|
1520
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 35))).contents).to.equal([
|
|
1521
|
+
'```brightscript',
|
|
1522
|
+
'instr as dynamic',
|
|
1523
|
+
'```'
|
|
1524
|
+
].join('\n'));
|
|
1424
1525
|
});
|
|
1425
1526
|
it('finds function hover in file scope', () => {
|
|
1426
1527
|
let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
@@ -1434,7 +1535,11 @@ describe('BrsFile', () => {
|
|
|
1434
1535
|
`);
|
|
1435
1536
|
let hover = file.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1436
1537
|
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1437
|
-
(0, chai_1.expect)(hover.contents).to.equal(
|
|
1538
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1539
|
+
'```brightscript',
|
|
1540
|
+
'sub sayMyName() as void',
|
|
1541
|
+
'```'
|
|
1542
|
+
].join('\n'));
|
|
1438
1543
|
});
|
|
1439
1544
|
it('finds function hover in scope', () => {
|
|
1440
1545
|
let rootDir = process.cwd();
|
|
@@ -1454,7 +1559,53 @@ describe('BrsFile', () => {
|
|
|
1454
1559
|
let hover = mainFile.getHover(vscode_languageserver_1.Position.create(2, 25));
|
|
1455
1560
|
(0, chai_1.expect)(hover).to.exist;
|
|
1456
1561
|
(0, chai_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
|
|
1457
|
-
(0, chai_1.expect)(hover.contents).to.equal(
|
|
1562
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1563
|
+
'```brightscript',
|
|
1564
|
+
'sub sayMyName(name as string) as void',
|
|
1565
|
+
'```'
|
|
1566
|
+
].join('\n'));
|
|
1567
|
+
});
|
|
1568
|
+
it('includes markdown comments in hover.', async () => {
|
|
1569
|
+
let rootDir = process.cwd();
|
|
1570
|
+
program = new Program_1.Program({
|
|
1571
|
+
rootDir: rootDir
|
|
1572
|
+
});
|
|
1573
|
+
const file = program.setFile('source/lib.brs', `
|
|
1574
|
+
'
|
|
1575
|
+
' The main function
|
|
1576
|
+
'
|
|
1577
|
+
sub main()
|
|
1578
|
+
log("hello")
|
|
1579
|
+
end sub
|
|
1580
|
+
|
|
1581
|
+
'
|
|
1582
|
+
' Prints a message to the log.
|
|
1583
|
+
' Works with *markdown* **content**
|
|
1584
|
+
'
|
|
1585
|
+
sub log(message as string)
|
|
1586
|
+
print message
|
|
1587
|
+
end sub
|
|
1588
|
+
`);
|
|
1589
|
+
//hover over log("hello")
|
|
1590
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(5, 22))).contents).to.equal([
|
|
1591
|
+
'```brightscript',
|
|
1592
|
+
'sub log(message as string) as void',
|
|
1593
|
+
'```',
|
|
1594
|
+
'***',
|
|
1595
|
+
'',
|
|
1596
|
+
' Prints a message to the log.',
|
|
1597
|
+
' Works with *markdown* **content**',
|
|
1598
|
+
''
|
|
1599
|
+
].join('\n'));
|
|
1600
|
+
//hover over sub ma|in()
|
|
1601
|
+
(0, chai_1.expect)((await program.getHover(file.srcPath, vscode_languageserver_1.Position.create(4, 22))).contents).to.equal((0, testHelpers_spec_1.trim) `
|
|
1602
|
+
\`\`\`brightscript
|
|
1603
|
+
sub main() as void
|
|
1604
|
+
\`\`\`
|
|
1605
|
+
***
|
|
1606
|
+
|
|
1607
|
+
The main function
|
|
1608
|
+
`);
|
|
1458
1609
|
});
|
|
1459
1610
|
it('handles mixed case `then` partions of conditionals', () => {
|
|
1460
1611
|
let mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
@@ -1464,7 +1615,7 @@ describe('BrsFile', () => {
|
|
|
1464
1615
|
end if
|
|
1465
1616
|
end sub
|
|
1466
1617
|
`);
|
|
1467
|
-
(0,
|
|
1618
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1468
1619
|
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1469
1620
|
sub Main()
|
|
1470
1621
|
if true Then
|
|
@@ -1472,7 +1623,7 @@ describe('BrsFile', () => {
|
|
|
1472
1623
|
end if
|
|
1473
1624
|
end sub
|
|
1474
1625
|
`);
|
|
1475
|
-
(0,
|
|
1626
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1476
1627
|
mainFile = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
|
|
1477
1628
|
sub Main()
|
|
1478
1629
|
if true THEN
|
|
@@ -1480,7 +1631,7 @@ describe('BrsFile', () => {
|
|
|
1480
1631
|
end if
|
|
1481
1632
|
end sub
|
|
1482
1633
|
`);
|
|
1483
|
-
(0,
|
|
1634
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
|
|
1484
1635
|
});
|
|
1485
1636
|
it('displays the context from multiple scopes', () => {
|
|
1486
1637
|
let commonFile = program.setFile('source/common.brs', `
|
|
@@ -1517,11 +1668,61 @@ describe('BrsFile', () => {
|
|
|
1517
1668
|
`);
|
|
1518
1669
|
program.validate();
|
|
1519
1670
|
let funcCallHover = commonFile.getHover(vscode_languageserver_1.Position.create(2, 27));
|
|
1520
|
-
(0, chai_1.expect)(funcCallHover).to.
|
|
1521
|
-
|
|
1671
|
+
(0, chai_1.expect)(funcCallHover === null || funcCallHover === void 0 ? void 0 : funcCallHover.contents).to.equal([
|
|
1672
|
+
'```brightscript',
|
|
1673
|
+
'function getPi() as string | function getPi() as float | getPi as uninitialized',
|
|
1674
|
+
'```'
|
|
1675
|
+
].join('\n'));
|
|
1522
1676
|
let variableHover = commonFile.getHover(vscode_languageserver_1.Position.create(3, 27));
|
|
1523
|
-
(0, chai_1.expect)(variableHover).to.
|
|
1524
|
-
|
|
1677
|
+
(0, chai_1.expect)(variableHover === null || variableHover === void 0 ? void 0 : variableHover.contents).to.equal([
|
|
1678
|
+
'```brightscript',
|
|
1679
|
+
'pi as string | pi as float | pi as uninitialized',
|
|
1680
|
+
'```'
|
|
1681
|
+
].join('\n'));
|
|
1682
|
+
});
|
|
1683
|
+
it('finds function with custom types as parameters and return types', () => {
|
|
1684
|
+
let file = program.setFile('source/main.bs', `
|
|
1685
|
+
sub main()
|
|
1686
|
+
k = new MyKlass()
|
|
1687
|
+
processMyKlass(k)
|
|
1688
|
+
end sub
|
|
1689
|
+
|
|
1690
|
+
function processMyKlass(data as MyKlass) as MyKlass
|
|
1691
|
+
return data
|
|
1692
|
+
end function
|
|
1693
|
+
|
|
1694
|
+
class MyKlass
|
|
1695
|
+
end class
|
|
1696
|
+
`);
|
|
1697
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1698
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1699
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1700
|
+
'```brightscript',
|
|
1701
|
+
'function processMyKlass(data as MyKlass) as MyKlass',
|
|
1702
|
+
'```'
|
|
1703
|
+
].join('\n'));
|
|
1704
|
+
});
|
|
1705
|
+
it('finds function with arrays as parameters and return types', () => {
|
|
1706
|
+
let file = program.setFile('source/main.bs', `
|
|
1707
|
+
sub main()
|
|
1708
|
+
k = new MyKlass()
|
|
1709
|
+
processData([k])
|
|
1710
|
+
end sub
|
|
1711
|
+
|
|
1712
|
+
function processData(data as MyKlass[]) as MyKlass[]
|
|
1713
|
+
return data
|
|
1714
|
+
end function
|
|
1715
|
+
|
|
1716
|
+
class MyKlass
|
|
1717
|
+
end class
|
|
1718
|
+
`);
|
|
1719
|
+
let hover = file.getHover(vscode_languageserver_1.Position.create(3, 29));
|
|
1720
|
+
(0, chai_1.expect)(hover).to.exist;
|
|
1721
|
+
(0, chai_1.expect)(hover.contents).to.equal([
|
|
1722
|
+
'```brightscript',
|
|
1723
|
+
'function processData(data as MyKlass[]) as MyKlass[]',
|
|
1724
|
+
'```'
|
|
1725
|
+
].join('\n'));
|
|
1525
1726
|
});
|
|
1526
1727
|
});
|
|
1527
1728
|
it('does not throw when encountering incomplete import statement', () => {
|
|
@@ -1830,9 +2031,9 @@ describe('BrsFile', () => {
|
|
|
1830
2031
|
});
|
|
1831
2032
|
it('computes correct locations for sourcemap', async () => {
|
|
1832
2033
|
let source = `function abc(name)\n firstName = name\nend function`;
|
|
1833
|
-
let tokens =
|
|
2034
|
+
let tokens = Lexer_1.Lexer.scan(source).tokens
|
|
1834
2035
|
//remove newlines and EOF
|
|
1835
|
-
.filter(x => x.kind !==
|
|
2036
|
+
.filter(x => x.kind !== TokenKind_1.TokenKind.Eof && x.kind !== TokenKind_1.TokenKind.Newline);
|
|
1836
2037
|
program.options.sourceMap = true;
|
|
1837
2038
|
let result = testTranspile(source, source, 'none');
|
|
1838
2039
|
//load the source map
|
|
@@ -2090,14 +2291,13 @@ describe('BrsFile', () => {
|
|
|
2090
2291
|
describe('callfunc operator', () => {
|
|
2091
2292
|
describe('transpile', () => {
|
|
2092
2293
|
it('does not produce diagnostics', () => {
|
|
2093
|
-
var _a;
|
|
2094
2294
|
program.setFile('source/main.bs', `
|
|
2095
2295
|
sub main()
|
|
2096
2296
|
someObject@.someFunction(paramObject.value)
|
|
2097
2297
|
end sub
|
|
2098
2298
|
`);
|
|
2099
2299
|
program.validate();
|
|
2100
|
-
(0,
|
|
2300
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2101
2301
|
});
|
|
2102
2302
|
it('sets invalid on empty callfunc', () => {
|
|
2103
2303
|
testTranspile(`
|
|
@@ -2137,7 +2337,7 @@ describe('BrsFile', () => {
|
|
|
2137
2337
|
name: 'transform callback',
|
|
2138
2338
|
afterFileParse: onParsed
|
|
2139
2339
|
});
|
|
2140
|
-
file = program.setFile(`
|
|
2340
|
+
file = program.setFile({ src: `absolute_path/file${ext}`, dest: `relative_path/file${ext}` }, `
|
|
2141
2341
|
sub Sum()
|
|
2142
2342
|
print "hello world"
|
|
2143
2343
|
end sub
|
|
@@ -2510,11 +2710,11 @@ describe('BrsFile', () => {
|
|
|
2510
2710
|
(0, chai_1.expect)(file.parser).to.equal(newParser);
|
|
2511
2711
|
});
|
|
2512
2712
|
it('call parse when previously skipped', () => {
|
|
2513
|
-
program.setFile('source/main.d.bs', `
|
|
2713
|
+
program.setFile('source/main.d.bs', `'typedef
|
|
2514
2714
|
sub main()
|
|
2515
2715
|
end sub
|
|
2516
2716
|
`);
|
|
2517
|
-
const file = program.setFile('source/main.brs', `
|
|
2717
|
+
const file = program.setFile('source/main.brs', `'source
|
|
2518
2718
|
sub main()
|
|
2519
2719
|
end sub
|
|
2520
2720
|
`);
|
|
@@ -2571,5 +2771,207 @@ describe('BrsFile', () => {
|
|
|
2571
2771
|
testPluginTranspile();
|
|
2572
2772
|
});
|
|
2573
2773
|
});
|
|
2774
|
+
describe('getSymbolTypeFromToken', () => {
|
|
2775
|
+
function checkSymbolLookups(file, funcExpr, lookups) {
|
|
2776
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2777
|
+
mainScope.linkSymbolTable();
|
|
2778
|
+
for (const lookup of lookups) {
|
|
2779
|
+
const position = vscode_languageserver_1.Position.create(lookup.line, lookup.col);
|
|
2780
|
+
const token = file.parser.getTokenAt(position);
|
|
2781
|
+
const symbol = file.getSymbolTypeFromToken(token, funcExpr, mainScope);
|
|
2782
|
+
const context = {
|
|
2783
|
+
file: file,
|
|
2784
|
+
scope: mainScope,
|
|
2785
|
+
position: position
|
|
2786
|
+
};
|
|
2787
|
+
(0, chai_1.expect)(symbol.expandedTokenText).to.equal(lookup.name);
|
|
2788
|
+
(0, chai_1.expect)(symbol.type.equals(lookup.type, context)).be.true;
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
it('gets simple types based on the containing function expression', () => {
|
|
2792
|
+
const file = program.setFile('source/main.bs', `
|
|
2793
|
+
sub doSomething(aInt as integer, aFloat as float, aStr as string, aBool as boolean, aObj as object)
|
|
2794
|
+
print aInt
|
|
2795
|
+
print aFloat
|
|
2796
|
+
print aStr
|
|
2797
|
+
print aBool
|
|
2798
|
+
print aObj
|
|
2799
|
+
end sub
|
|
2800
|
+
`);
|
|
2801
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2802
|
+
const lookups = [
|
|
2803
|
+
{ line: 2, col: 28, name: 'aInt', type: new IntegerType_1.IntegerType() },
|
|
2804
|
+
{ line: 3, col: 28, name: 'aFloat', type: new FloatType_1.FloatType() },
|
|
2805
|
+
{ line: 4, col: 28, name: 'aStr', type: new StringType_1.StringType() },
|
|
2806
|
+
{ line: 5, col: 28, name: 'aBool', type: new BooleanType_1.BooleanType() },
|
|
2807
|
+
{ line: 6, col: 28, name: 'aObj', type: new ObjectType_1.ObjectType() }
|
|
2808
|
+
];
|
|
2809
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2810
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2811
|
+
});
|
|
2812
|
+
it('gets custom types based on the containing function expression', () => {
|
|
2813
|
+
const file = program.setFile('source/main.bs', `
|
|
2814
|
+
sub doSomething(klass as MyKlass)
|
|
2815
|
+
print klass
|
|
2816
|
+
end sub
|
|
2817
|
+
|
|
2818
|
+
class MyKlass
|
|
2819
|
+
end class
|
|
2820
|
+
`);
|
|
2821
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2822
|
+
mainScope.linkSymbolTable();
|
|
2823
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2824
|
+
const token = file.parser.getTokenAt(vscode_languageserver_1.Position.create(2, 28));
|
|
2825
|
+
const symbol = file.getSymbolTypeFromToken(token, funcExpr, mainScope);
|
|
2826
|
+
(0, chai_1.expect)(symbol.expandedTokenText).to.equal('klass');
|
|
2827
|
+
const classStmt = file.parser.references.classStatements[0];
|
|
2828
|
+
(0, chai_1.expect)(classStmt.name.text).to.equal('MyKlass');
|
|
2829
|
+
(0, chai_1.expect)(symbol.type.isAssignableTo(classStmt.getCustomType())).be.true;
|
|
2830
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2831
|
+
});
|
|
2832
|
+
it('gets types of properties of a klass', () => {
|
|
2833
|
+
const file = program.setFile('source/main.bs', `
|
|
2834
|
+
sub doSomething()
|
|
2835
|
+
klass = new MyKlass()
|
|
2836
|
+
print klass.name
|
|
2837
|
+
print klass.age
|
|
2838
|
+
' verify case insensitivity
|
|
2839
|
+
print KLASS.NAME
|
|
2840
|
+
print klass.AGE
|
|
2841
|
+
end sub
|
|
2842
|
+
|
|
2843
|
+
class MyKlass
|
|
2844
|
+
name as string
|
|
2845
|
+
age as integer
|
|
2846
|
+
end class
|
|
2847
|
+
`);
|
|
2848
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2849
|
+
const lookups = [
|
|
2850
|
+
{ line: 3, col: 35, name: 'MyKlass.name', type: new StringType_1.StringType() },
|
|
2851
|
+
{ line: 4, col: 35, name: 'MyKlass.age', type: new IntegerType_1.IntegerType() }
|
|
2852
|
+
];
|
|
2853
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2854
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2855
|
+
});
|
|
2856
|
+
it('gets types of properties of an object', () => {
|
|
2857
|
+
const file = program.setFile('source/main.bs', `
|
|
2858
|
+
sub doSomething()
|
|
2859
|
+
obj = { name: "Joe", age: 37}
|
|
2860
|
+
print obj.name
|
|
2861
|
+
print obj.age
|
|
2862
|
+
end sub
|
|
2863
|
+
`);
|
|
2864
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2865
|
+
const lookups = [
|
|
2866
|
+
{ line: 3, col: 32, name: 'obj.name', type: new StringType_1.StringType() },
|
|
2867
|
+
{ line: 4, col: 32, name: 'obj.age', type: new IntegerType_1.IntegerType() }
|
|
2868
|
+
];
|
|
2869
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2870
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2871
|
+
});
|
|
2872
|
+
it('gets return types of functions', () => {
|
|
2873
|
+
const file = program.setFile('source/main.bs', `
|
|
2874
|
+
sub doSomething()
|
|
2875
|
+
pi = makeKlass().getSelf().getPi()
|
|
2876
|
+
print pi
|
|
2877
|
+
end sub
|
|
2878
|
+
|
|
2879
|
+
function makeKlass() as MyKlass
|
|
2880
|
+
return new MyKlass()
|
|
2881
|
+
end function
|
|
2882
|
+
|
|
2883
|
+
class MyKlass
|
|
2884
|
+
function getPi() as float
|
|
2885
|
+
return 3.14
|
|
2886
|
+
end function
|
|
2887
|
+
|
|
2888
|
+
function getSelf() as MyKlass
|
|
2889
|
+
return m
|
|
2890
|
+
end function
|
|
2891
|
+
end class
|
|
2892
|
+
`);
|
|
2893
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2894
|
+
mainScope.linkSymbolTable();
|
|
2895
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2896
|
+
const klassMemberTable = file.parser.references.classStatements[0].memberTable;
|
|
2897
|
+
const lookups = [
|
|
2898
|
+
{ line: 2, col: 31, name: 'makeKlass', type: file.parser.references.functionExpressions[1].getFunctionType() },
|
|
2899
|
+
// The expanded text for this should probably be MyKlass.getSelf()
|
|
2900
|
+
{ line: 2, col: 41, name: 'MyKlass.MyKlass', type: klassMemberTable.getSymbol('getSelf')[0].type },
|
|
2901
|
+
{ line: 2, col: 51, name: 'MyKlass.getPi', type: klassMemberTable.getSymbol('getPi')[0].type },
|
|
2902
|
+
{ line: 3, col: 28, name: 'pi', type: new FloatType_1.FloatType() }
|
|
2903
|
+
];
|
|
2904
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2905
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2906
|
+
});
|
|
2907
|
+
it('gets types of elements of arrays', () => {
|
|
2908
|
+
const file = program.setFile('source/main.bs', `
|
|
2909
|
+
sub doSomething(words as string[], klasses as MyKlass[])
|
|
2910
|
+
myWord = words[0]
|
|
2911
|
+
pi = klasses[0].getPi()
|
|
2912
|
+
print myWord
|
|
2913
|
+
print pi
|
|
2914
|
+
end sub
|
|
2915
|
+
|
|
2916
|
+
class MyKlass
|
|
2917
|
+
function getPi() as float
|
|
2918
|
+
return 3.14
|
|
2919
|
+
end function
|
|
2920
|
+
end class
|
|
2921
|
+
`);
|
|
2922
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2923
|
+
mainScope.linkSymbolTable();
|
|
2924
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2925
|
+
const klassMemberTable = file.parser.references.classStatements[0].memberTable;
|
|
2926
|
+
const lookups = [
|
|
2927
|
+
{ line: 2, col: 34, name: 'words', type: new ArrayType_1.ArrayType(new StringType_1.StringType()) },
|
|
2928
|
+
{ line: 3, col: 41, name: 'MyKlass.getPi', type: klassMemberTable.getSymbol('getPi')[0].type },
|
|
2929
|
+
{ line: 4, col: 28, name: 'myWord', type: new StringType_1.StringType() },
|
|
2930
|
+
{ line: 5, col: 28, name: 'pi', type: new FloatType_1.FloatType() }
|
|
2931
|
+
];
|
|
2932
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2933
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2934
|
+
});
|
|
2935
|
+
it('gets types of elements of arrays via square bracket reference', () => {
|
|
2936
|
+
const file = program.setFile('source/main.bs', `
|
|
2937
|
+
function printFirst(numbers as float[]) as float
|
|
2938
|
+
firstFloat = numbers[0]
|
|
2939
|
+
print firstFloat
|
|
2940
|
+
return firstFloat
|
|
2941
|
+
end function
|
|
2942
|
+
`);
|
|
2943
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2944
|
+
mainScope.linkSymbolTable();
|
|
2945
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2946
|
+
const lookups = [
|
|
2947
|
+
{ line: 2, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
2948
|
+
{ line: 3, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
2949
|
+
];
|
|
2950
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2951
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2952
|
+
});
|
|
2953
|
+
it('gets types of elements of arrays after for each', () => {
|
|
2954
|
+
const file = program.setFile('source/main.bs', `
|
|
2955
|
+
function printAllReturnFirst(numbers as float[]) as float
|
|
2956
|
+
for each num in numbers
|
|
2957
|
+
print num
|
|
2958
|
+
end for
|
|
2959
|
+
|
|
2960
|
+
firstFloat = numbers[0]
|
|
2961
|
+
print firstFloat
|
|
2962
|
+
return firstFloat
|
|
2963
|
+
end function
|
|
2964
|
+
`);
|
|
2965
|
+
const mainScope = program.getScopesForFile(file)[0];
|
|
2966
|
+
mainScope.linkSymbolTable();
|
|
2967
|
+
const funcExpr = file.parser.references.functionExpressions[0];
|
|
2968
|
+
const lookups = [
|
|
2969
|
+
{ line: 6, col: 26, name: 'firstFloat', type: new FloatType_1.FloatType() },
|
|
2970
|
+
{ line: 7, col: 32, name: 'firstFloat', type: new FloatType_1.FloatType() }
|
|
2971
|
+
];
|
|
2972
|
+
checkSymbolLookups(file, funcExpr, lookups);
|
|
2973
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(program);
|
|
2974
|
+
});
|
|
2975
|
+
});
|
|
2574
2976
|
});
|
|
2575
2977
|
//# sourceMappingURL=BrsFile.spec.js.map
|