brighterscript 1.0.0-alpha.22 → 1.0.0-alpha.24

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/dist/DiagnosticCollection.d.ts +3 -1
  3. package/dist/DiagnosticCollection.js +3 -5
  4. package/dist/DiagnosticCollection.js.map +1 -1
  5. package/dist/DiagnosticMessages.d.ts +24 -3
  6. package/dist/DiagnosticMessages.js +28 -7
  7. package/dist/DiagnosticMessages.js.map +1 -1
  8. package/dist/LanguageServer.d.ts +2 -1
  9. package/dist/LanguageServer.js +96 -31
  10. package/dist/LanguageServer.js.map +1 -1
  11. package/dist/Program.d.ts +14 -8
  12. package/dist/Program.js +125 -71
  13. package/dist/Program.js.map +1 -1
  14. package/dist/ProgramBuilder.js +2 -1
  15. package/dist/ProgramBuilder.js.map +1 -1
  16. package/dist/Scope.d.ts +23 -15
  17. package/dist/Scope.js +124 -122
  18. package/dist/Scope.js.map +1 -1
  19. package/dist/SymbolTable.d.ts +17 -6
  20. package/dist/SymbolTable.js +38 -9
  21. package/dist/SymbolTable.js.map +1 -1
  22. package/dist/XmlScope.js +3 -2
  23. package/dist/XmlScope.js.map +1 -1
  24. package/dist/astUtils/reflection.d.ts +5 -1
  25. package/dist/astUtils/reflection.js +15 -2
  26. package/dist/astUtils/reflection.js.map +1 -1
  27. package/dist/astUtils/visitors.d.ts +2 -1
  28. package/dist/astUtils/visitors.js.map +1 -1
  29. package/dist/bscPlugin/BscPlugin.d.ts +3 -1
  30. package/dist/bscPlugin/BscPlugin.js +8 -0
  31. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  32. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
  33. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +11 -5
  34. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  35. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +75 -1
  36. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  37. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +6 -0
  38. package/dist/bscPlugin/completions/CompletionsProcessor.js +53 -0
  39. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
  40. package/dist/bscPlugin/hover/HoverProcessor.d.ts +17 -0
  41. package/dist/bscPlugin/hover/HoverProcessor.js +190 -0
  42. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
  43. package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
  44. package/dist/bscPlugin/hover/HoverProcessor.spec.js +195 -0
  45. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
  46. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +8 -1
  47. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +64 -63
  48. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  49. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +238 -23
  50. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  51. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +7 -1
  52. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +77 -30
  53. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
  54. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +14 -1
  55. package/dist/bscPlugin/validation/BrsFileValidator.js +104 -27
  56. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  57. package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
  58. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +48 -0
  59. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
  60. package/dist/bscPlugin/validation/ScopeValidator.d.ts +24 -3
  61. package/dist/bscPlugin/validation/ScopeValidator.js +251 -44
  62. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  63. package/dist/cli.js +18 -10
  64. package/dist/cli.js.map +1 -1
  65. package/dist/files/BrsFile.Class.spec.js +135 -38
  66. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  67. package/dist/files/BrsFile.d.ts +21 -10
  68. package/dist/files/BrsFile.js +158 -179
  69. package/dist/files/BrsFile.js.map +1 -1
  70. package/dist/files/BrsFile.spec.js +222 -126
  71. package/dist/files/BrsFile.spec.js.map +1 -1
  72. package/dist/files/XmlFile.d.ts +2 -2
  73. package/dist/files/XmlFile.js +1 -0
  74. package/dist/files/XmlFile.js.map +1 -1
  75. package/dist/files/tests/imports.spec.js +1 -1
  76. package/dist/files/tests/imports.spec.js.map +1 -1
  77. package/dist/files/tests/optionalChaning.spec.js +20 -16
  78. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  79. package/dist/globalCallables.js +3 -0
  80. package/dist/globalCallables.js.map +1 -1
  81. package/dist/index.d.ts +1 -1
  82. package/dist/index.js +3 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/interfaces.d.ts +77 -3
  85. package/dist/lexer/Lexer.spec.js +7 -0
  86. package/dist/lexer/Lexer.spec.js.map +1 -1
  87. package/dist/lexer/TokenKind.d.ts +1 -0
  88. package/dist/lexer/TokenKind.js +8 -3
  89. package/dist/lexer/TokenKind.js.map +1 -1
  90. package/dist/parser/Expression.d.ts +12 -3
  91. package/dist/parser/Expression.js +16 -4
  92. package/dist/parser/Expression.js.map +1 -1
  93. package/dist/parser/Parser.Class.spec.js +1 -1
  94. package/dist/parser/Parser.d.ts +14 -3
  95. package/dist/parser/Parser.js +138 -48
  96. package/dist/parser/Parser.js.map +1 -1
  97. package/dist/parser/Parser.spec.js +232 -115
  98. package/dist/parser/Parser.spec.js.map +1 -1
  99. package/dist/parser/Statement.d.ts +41 -7
  100. package/dist/parser/Statement.js +85 -12
  101. package/dist/parser/Statement.js.map +1 -1
  102. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +73 -31
  103. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  104. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +148 -47
  105. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  106. package/dist/parser/tests/expression/TernaryExpression.spec.js +219 -37
  107. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  108. package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
  109. package/dist/parser/tests/statement/ConstStatement.spec.js +213 -0
  110. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
  111. package/dist/parser/tests/statement/Enum.spec.js +56 -8
  112. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  113. package/dist/parser/tests/statement/InterfaceStatement.spec.js +16 -2
  114. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  115. package/dist/parser/tests/statement/PrintStatement.spec.js +72 -57
  116. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  117. package/dist/preprocessor/Manifest.js +2 -2
  118. package/dist/preprocessor/Manifest.js.map +1 -1
  119. package/dist/preprocessor/Preprocessor.js +10 -6
  120. package/dist/preprocessor/Preprocessor.js.map +1 -1
  121. package/dist/roku-types/data.json +1002 -788
  122. package/dist/roku-types/index.d.ts +64 -239
  123. package/dist/types/DynamicType.d.ts +1 -0
  124. package/dist/types/DynamicType.js +1 -0
  125. package/dist/types/DynamicType.js.map +1 -1
  126. package/dist/util.d.ts +57 -16
  127. package/dist/util.js +139 -30
  128. package/dist/util.js.map +1 -1
  129. package/dist/validators/ClassValidator.d.ts +4 -1
  130. package/dist/validators/ClassValidator.js +34 -25
  131. package/dist/validators/ClassValidator.js.map +1 -1
  132. package/package.json +5 -2
@@ -15,17 +15,18 @@ const BrsTranspileState_1 = require("./BrsTranspileState");
15
15
  const source_map_1 = require("source-map");
16
16
  const BrsFile_1 = require("../files/BrsFile");
17
17
  const Program_1 = require("../Program");
18
+ const visitors_1 = require("../astUtils/visitors");
18
19
  const SymbolTable_1 = require("../SymbolTable");
19
- const TypedFunctionType_1 = require("../types/TypedFunctionType");
20
- const LazyType_1 = require("../types/LazyType");
20
+ const ArrayType_1 = require("../types/ArrayType");
21
+ const CustomType_1 = require("../types/CustomType");
22
+ const DynamicType_1 = require("../types/DynamicType");
21
23
  const IntegerType_1 = require("../types/IntegerType");
22
- const StringType_1 = require("../types/StringType");
24
+ const LazyType_1 = require("../types/LazyType");
23
25
  const ObjectType_1 = require("../types/ObjectType");
24
- const CustomType_1 = require("../types/CustomType");
26
+ const StringType_1 = require("../types/StringType");
27
+ const TypedFunctionType_1 = require("../types/TypedFunctionType");
25
28
  const VoidType_1 = require("../types/VoidType");
26
- const DynamicType_1 = require("../types/DynamicType");
27
29
  const util_1 = require("../util");
28
- const ArrayType_1 = require("../types/ArrayType");
29
30
  describe('parser', () => {
30
31
  it('emits empty object when empty token list is provided', () => {
31
32
  (0, chai_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
@@ -119,9 +120,11 @@ describe('parser', () => {
119
120
  }
120
121
  it('works for references.expressions', () => {
121
122
  const parser = Parser_1.Parser.parse(`
123
+ b += "plus-equal"
122
124
  a += 1 + 2
123
- a++
124
- a--
125
+ b += getValue1() + getValue2()
126
+ increment++
127
+ decrement--
125
128
  some.node@.doCallfunc()
126
129
  bravo(3 + 4).jump(callMe())
127
130
  obj = {
@@ -142,11 +145,23 @@ describe('parser', () => {
142
145
  end function
143
146
  `);
144
147
  const expected = [
148
+ '"plus-equal"',
149
+ 'b',
150
+ 'b += "plus-equal"',
151
+ '1',
152
+ '2',
153
+ 'a',
145
154
  'a += 1 + 2',
146
- 'a++',
147
- 'a--',
155
+ 'getValue1()',
156
+ 'getValue2()',
157
+ 'b',
158
+ 'b += getValue1() + getValue2()',
159
+ 'increment++',
160
+ 'decrement--',
148
161
  //currently the "toString" does a transpile, so that's why this is different.
149
162
  'some.node.callfunc("doCallfunc", invalid)',
163
+ '3',
164
+ '4',
150
165
  '3 + 4',
151
166
  'callMe()',
152
167
  'bravo(3 + 4).jump(callMe())',
@@ -161,11 +176,45 @@ describe('parser', () => {
161
176
  'call1().a.b.call2()',
162
177
  '"bob"',
163
178
  'name.space.getSomething()'
164
- ].sort();
165
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected);
179
+ ];
180
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
181
+ //tell the parser we modified the AST and need to regenerate references
182
+ parser.invalidateReferences();
183
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
184
+ });
185
+ it('works for references.expressions', () => {
186
+ const parser = Parser_1.Parser.parse(`
187
+ value = true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value
188
+ `);
189
+ const expected = [
190
+ 'true',
191
+ 'type(true)',
192
+ '"something"',
193
+ 'true',
194
+ 'Enums.A.Value',
195
+ '"value"',
196
+ 'Enum1.Value',
197
+ 'Name.Space.Enum2.Value',
198
+ 'true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value'
199
+ ];
200
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
201
+ //tell the parser we modified the AST and need to regenerate references
202
+ parser.invalidateReferences();
203
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
204
+ });
205
+ it('works for logical expression', () => {
206
+ const parser = Parser_1.Parser.parse(`
207
+ value = Enums.A.Value = "value"
208
+ `);
209
+ const expected = [
210
+ 'Enums.A.Value',
211
+ '"value"',
212
+ 'Enums.A.Value = "value"'
213
+ ];
214
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
166
215
  //tell the parser we modified the AST and need to regenerate references
167
216
  parser.invalidateReferences();
168
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected);
217
+ (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
169
218
  });
170
219
  });
171
220
  describe('callfunc operator', () => {
@@ -427,7 +476,7 @@ describe('parser', () => {
427
476
  const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
428
477
  (0, chai_1.expect)(strFunctionType.returnType.toString()).to.equal('string');
429
478
  });
430
- it('adds a fully qualified name of a function in a namespace to the parsers symbol table', () => {
479
+ it('adds a transpiled name of a function in a namespace to the parsers symbol table', () => {
431
480
  let parser = parse(`
432
481
  namespace Name.Space
433
482
  function funcInt() as integer
@@ -439,8 +488,8 @@ describe('parser', () => {
439
488
  end function
440
489
  end namespace
441
490
  `, Parser_1.ParseMode.BrighterScript);
442
- (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name.Space.funcInt')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
443
- (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name.Space.funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
491
+ (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcInt')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
492
+ (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
444
493
  });
445
494
  });
446
495
  it('supports << operator', () => {
@@ -809,6 +858,38 @@ describe('parser', () => {
809
858
  `);
810
859
  (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
811
860
  });
861
+ it('allows `mod` as an AA literal property', () => {
862
+ const parser = parse(`
863
+ sub main()
864
+ person = {
865
+ mod: true
866
+ }
867
+ person.mod = false
868
+ print person.mod
869
+ end sub
870
+ `);
871
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
872
+ });
873
+ it('converts aa literal property TokenKind to Identifier', () => {
874
+ const parser = parse(`
875
+ sub main()
876
+ person = {
877
+ mod: true
878
+ and: true
879
+ }
880
+ end sub
881
+ `);
882
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
883
+ const elements = [];
884
+ parser.ast.walk((0, visitors_1.createVisitor)({
885
+ AAMemberExpression: (node) => {
886
+ elements.push(node);
887
+ }
888
+ }), {
889
+ walkMode: visitors_1.WalkMode.visitAllRecursive
890
+ });
891
+ (0, chai_1.expect)(elements.map(x => x.keyToken.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
892
+ });
812
893
  });
813
894
  it('"end" is not allowed as a local identifier', () => {
814
895
  let { diagnostics } = parse(`
@@ -1449,23 +1530,23 @@ describe('parser', () => {
1449
1530
  describe('tokenChain', () => {
1450
1531
  it('can find a chain of tokens', () => {
1451
1532
  const parser = parse(`
1452
- sub someFunc()
1453
- print m.field.childField
1454
- end sub
1455
- `, Parser_1.ParseMode.BrighterScript);
1456
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 38));
1533
+ sub someFunc(var)
1534
+ print var.field.childField
1535
+ end sub
1536
+ `);
1537
+ const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 42));
1457
1538
  const tokenChain = parser.getTokenChain(childFieldToken).chain;
1458
1539
  const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1459
1540
  (0, chai_1.expect)(tokenChain.length).to.equal(3);
1460
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['m', 'field', 'childField']);
1541
+ (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'childField']);
1461
1542
  (0, chai_1.expect)(tokenChain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1462
1543
  });
1463
1544
  it('can find a chain of tokens with function call with no args in the middle', () => {
1464
1545
  const parser = parse(`
1465
- sub someFunc()
1466
- print var.field.funcCall().childField
1467
- end sub
1468
- `, Parser_1.ParseMode.BrighterScript);
1546
+ sub someFunc(var)
1547
+ print var.field.funcCall().childField
1548
+ end sub
1549
+ `);
1469
1550
  const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 49));
1470
1551
  const tokenChain = parser.getTokenChain(childFieldToken).chain;
1471
1552
  const tokenChainTokens = tokenChain.map(tcm => tcm.token);
@@ -1475,10 +1556,10 @@ describe('parser', () => {
1475
1556
  });
1476
1557
  it('can find a chain of tokens with function call with multiple args in the middle', () => {
1477
1558
  const parser = parse(`
1478
- sub someFunc()
1479
- print var.field.funcCall(1, "string", {key: value}).childField
1480
- end sub
1481
- `, Parser_1.ParseMode.BrighterScript);
1559
+ sub someFunc(var)
1560
+ print var.field.funcCall(1, "string", {key: value}).childField
1561
+ end sub
1562
+ `);
1482
1563
  const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 75));
1483
1564
  const tokenChain = parser.getTokenChain(childFieldToken).chain;
1484
1565
  const tokenChainTokens = tokenChain.map(tcm => tcm.token);
@@ -1488,10 +1569,10 @@ describe('parser', () => {
1488
1569
  });
1489
1570
  it('can find a chain of tokens with function call with function call inside', () => {
1490
1571
  const parser = parse(`
1491
- sub someFunc()
1492
- print var.field.funcCall(a(), b(), otherFunc2(c(), {d: func3(e)})).childField
1493
- end sub
1494
- `, Parser_1.ParseMode.BrighterScript);
1572
+ sub someFunc(var)
1573
+ print var.field.funcCall(a(), b(), otherFunc2(c(), {d: func3(e)})).childField
1574
+ end sub
1575
+ `);
1495
1576
  const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 90));
1496
1577
  const tokenChain = parser.getTokenChain(childFieldToken).chain;
1497
1578
  const tokenChainTokens = tokenChain.map(tcm => tcm.token);
@@ -1501,10 +1582,10 @@ describe('parser', () => {
1501
1582
  });
1502
1583
  it('can find a chain of tokens with array references inside', () => {
1503
1584
  const parser = parse(`
1504
- sub someFunc()
1505
- print var.field.myArray[0].childField
1506
- end sub
1507
- `, Parser_1.ParseMode.BrighterScript);
1585
+ sub someFunc(var)
1586
+ print var.field.myArray[0].childField
1587
+ end sub
1588
+ `);
1508
1589
  const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 50));
1509
1590
  const tokenChain = parser.getTokenChain(childFieldToken).chain;
1510
1591
  const tokenChainTokens = tokenChain.map(tcm => tcm.token);
@@ -1514,97 +1595,133 @@ describe('parser', () => {
1514
1595
  });
1515
1596
  it('includes unknown when an expression in brackets is part of the chain', () => {
1516
1597
  const parser = parse(`
1517
- sub someFunc()
1518
- print (1 + 1).toStr()
1519
- end sub
1520
- `, Parser_1.ParseMode.BrighterScript);
1521
- const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 34));
1598
+ sub someFunc()
1599
+ print (1 + 1).toStr()
1600
+ end sub
1601
+ `);
1602
+ const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 38));
1522
1603
  const tokenChainResponse = parser.getTokenChain(toStrToken);
1523
1604
  (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1524
1605
  });
1525
1606
  it('includes unknown when an expression in double brackets is part of the chain', () => {
1526
1607
  const parser = parse(`
1527
- sub someFunc()
1528
- print ((2 + 1)*3).toStr()
1529
- end sub
1530
- `, Parser_1.ParseMode.BrighterScript);
1531
- const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 38));
1608
+ sub someFunc()
1609
+ print ((2 + 1)*3).toStr()
1610
+ end sub
1611
+ `);
1612
+ const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 42));
1532
1613
  const tokenChainResponse = parser.getTokenChain(toStrToken);
1533
1614
  (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1534
1615
  });
1535
1616
  it('includes unknown when a complicated expression in brackets is part of the chain', () => {
1536
1617
  const parser = parse(`
1537
- sub someFunc(currentDate, lastUpdate)
1538
- print (INT((currentDate.asSeconds() - lastUpdate) / 86400)).toStr()
1539
- end sub
1540
- `, Parser_1.ParseMode.BrighterScript);
1618
+ sub someFunc(currentDate, lastUpdate)
1619
+ print (INT((currentDate.asSeconds() - lastUpdate) / 86400)).toStr()
1620
+ end sub
1621
+ `);
1541
1622
  const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 81));
1542
1623
  const tokenChainResponse = parser.getTokenChain(toStrToken);
1543
1624
  (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1544
1625
  });
1545
- });
1546
- it('includes unknown when property is referenced via brackets', () => {
1547
- const parser = parse(`
1548
- sub someFunc()
1549
- complexObj = {prop: "hello", subObj: {prop: "foo", grandChildObj:{prop:"bar"}}}
1550
- print complexObj.subObj.prop
1551
- print complexObj["subObj"].prop
1552
- print complexObj["subObj"]["grandChildObj"].prop
1553
- end sub
1554
- `, Parser_1.ParseMode.BrighterScript);
1555
- const propAsChainToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 44)); // complexObj.subObj.prop
1556
- const propAsAsBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 47)); // complexObj["subObj"].prop
1557
- const propAsAsDoubleBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(5, 64)); // complexObj["subObj"]["grandChildObj"].prop
1558
- let tokenChainResponse = parser.getTokenChain(propAsChainToken);
1559
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1560
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['complexObj', 'subObj', 'prop']);
1561
- tokenChainResponse = parser.getTokenChain(propAsAsBracketToken);
1562
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1563
- (0, chai_1.expect)(tokenChainResponse.chain[0].usage).to.eql(Parser_1.TokenUsage.ArrayReference);
1564
- tokenChainResponse = parser.getTokenChain(propAsAsDoubleBracketToken);
1565
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1566
- });
1567
- it('allows token kinds from AllowedLocalIdentifiers as start of a chain', () => {
1568
- const parser = parse(`
1569
- sub testLocalIdentifiers(override, string, float)
1570
- override.someProp.someFunc()
1571
- string.someProp.someFunc()
1572
- float.someProp.someFunc()
1573
- end sub
1574
- `, Parser_1.ParseMode.BrightScript);
1575
- const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // override.someProp.someFunc()
1576
- const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 40)); // string.someProp.someFunc()
1577
- const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 38)); // float.someProp.someFunc()
1578
- let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1579
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1580
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['override', 'someProp', 'someFunc']);
1581
- tokenChainResponse = parser.getTokenChain(stringFuncToken);
1582
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1583
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['string', 'someProp', 'someFunc']);
1584
- tokenChainResponse = parser.getTokenChain(floatFuncToken);
1585
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1586
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['float', 'someProp', 'someFunc']);
1587
- });
1588
- it('allows token kinds from AllowedProperties in middle of a chain', () => {
1589
- const parser = parse(`
1590
- sub testAllowedProperties(someObj)
1591
- someObj.override.someFunc()
1592
- someObj.string.someFunc()
1593
- someObj.float.someFunc()
1594
- end sub
1595
- `, Parser_1.ParseMode.BrightScript);
1596
- const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 36)); // someObj.override.someFunc()
1597
- const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 36)); // someObj.string.someFunc()
1598
- const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 36)); // someObj.float.someFunc()
1599
- let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1600
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1601
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'override', 'someFunc']);
1602
- tokenChainResponse = parser.getTokenChain(stringFuncToken);
1603
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1604
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'string', 'someFunc']);
1605
- tokenChainResponse = parser.getTokenChain(floatFuncToken);
1606
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1607
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'float', 'someFunc']);
1626
+ it('indicates IndexedGet when referenced via brackets', () => {
1627
+ const parser = parse(`
1628
+ sub someFunc()
1629
+ complexObj = {prop: "hello", subObj: {prop: "foo", grandChildObj:{prop:"bar"}}}
1630
+ print complexObj.subObj.prop
1631
+ print complexObj["subObj"].prop
1632
+ print complexObj["subObj"]["grandChildObj"].prop
1633
+ end sub
1634
+ `);
1635
+ const propAsChainToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 48)); // complexObj.subObj.prop
1636
+ const propAsAsBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 51)); // complexObj["subObj"].prop
1637
+ const propAsAsDoubleBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(5, 68)); // complexObj["subObj"]["grandChildObj"].prop
1638
+ let tokenChainResponse = parser.getTokenChain(propAsChainToken);
1639
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1640
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['complexObj', 'subObj', 'prop']);
1641
+ tokenChainResponse = parser.getTokenChain(propAsAsBracketToken);
1642
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1643
+ (0, chai_1.expect)(tokenChainResponse.chain[0].usage).to.eql(Parser_1.TokenUsage.ArrayReference);
1644
+ tokenChainResponse = parser.getTokenChain(propAsAsDoubleBracketToken);
1645
+ (0, chai_1.expect)(tokenChainResponse.chain[0].usage).to.equal(Parser_1.TokenUsage.Direct);
1646
+ });
1647
+ it('allows token kinds from AllowedLocalIdentifiers as start of a chain', () => {
1648
+ const parser = parse(`
1649
+ sub testLocalIdentifiers(override, string, float)
1650
+ override.someProp.someFunc()
1651
+ string.someProp.someFunc()
1652
+ float.someProp.someFunc()
1653
+ end sub
1654
+ `);
1655
+ const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // override.someProp.someFunc()
1656
+ const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 40)); // string.someProp.someFunc()
1657
+ const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 38)); // float.someProp.someFunc()
1658
+ let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1659
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1660
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['override', 'someProp', 'someFunc']);
1661
+ tokenChainResponse = parser.getTokenChain(stringFuncToken);
1662
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1663
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['string', 'someProp', 'someFunc']);
1664
+ tokenChainResponse = parser.getTokenChain(floatFuncToken);
1665
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1666
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['float', 'someProp', 'someFunc']);
1667
+ });
1668
+ it('allows token kinds from AllowedProperties in middle of a chain', () => {
1669
+ const parser = parse(`
1670
+ sub testAllowedProperties(someObj)
1671
+ someObj.override.someFunc()
1672
+ someObj.string.someFunc()
1673
+ someObj.float.someFunc()
1674
+ end sub
1675
+ `);
1676
+ const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // someObj.override.someFunc()
1677
+ const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 40)); // someObj.string.someFunc()
1678
+ const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 40)); // someObj.float.someFunc()
1679
+ let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1680
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1681
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'override', 'someFunc']);
1682
+ tokenChainResponse = parser.getTokenChain(stringFuncToken);
1683
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1684
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'string', 'someFunc']);
1685
+ tokenChainResponse = parser.getTokenChain(floatFuncToken);
1686
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1687
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'float', 'someFunc']);
1688
+ });
1689
+ it('finds tokens in the middle of a chain', () => {
1690
+ const parser = parse(`
1691
+ sub testMiddleOfChain()
1692
+ print m.nodes[8].label.text
1693
+ print alpha.bravo(charlie.delta)
1694
+ print m.otherFunc().name
1695
+ end sub
1696
+ `);
1697
+ const labelToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // 'label'
1698
+ const nodesToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 31)); // 'nodes'
1699
+ const bravoToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 35)); // 'bravo'
1700
+ let tokenChainResponse = parser.getTokenChain(labelToken);
1701
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1702
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'nodes', 'label']);
1703
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.ArrayReference, Parser_1.TokenUsage.Direct]);
1704
+ tokenChainResponse = parser.getTokenChain(nodesToken);
1705
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1706
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'nodes']);
1707
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1708
+ tokenChainResponse = parser.getTokenChain(bravoToken);
1709
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1710
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['alpha', 'bravo']);
1711
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1712
+ });
1713
+ it('gets chain from ending dot', () => {
1714
+ const parser = parse(`
1715
+ sub testDotAtEndOfChain()
1716
+ m.someFunc().data[0].param.
1717
+ end sub
1718
+ `);
1719
+ const endDotToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 46)); // dot of 'param.'
1720
+ let tokenChainResponse = parser.getTokenChain(endDotToken);
1721
+ (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1722
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'someFunc', 'data', 'param']);
1723
+ (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Call, Parser_1.TokenUsage.ArrayReference, Parser_1.TokenUsage.Direct]);
1724
+ });
1608
1725
  });
1609
1726
  });
1610
1727
  function parse(text, mode) {