brighterscript 0.66.0-alpha.4 → 0.66.0-alpha.6

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 (214) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/DiagnosticMessages.d.ts +21 -3
  3. package/dist/DiagnosticMessages.js +35 -2
  4. package/dist/DiagnosticMessages.js.map +1 -1
  5. package/dist/LanguageServer.d.ts +1 -0
  6. package/dist/LanguageServer.js +8 -5
  7. package/dist/LanguageServer.js.map +1 -1
  8. package/dist/Program.d.ts +20 -8
  9. package/dist/Program.js +107 -60
  10. package/dist/Program.js.map +1 -1
  11. package/dist/ProgramBuilder.js +14 -2
  12. package/dist/ProgramBuilder.js.map +1 -1
  13. package/dist/Scope.d.ts +15 -13
  14. package/dist/Scope.js +26 -65
  15. package/dist/Scope.js.map +1 -1
  16. package/dist/SymbolTable.d.ts +17 -10
  17. package/dist/SymbolTable.js +48 -26
  18. package/dist/SymbolTable.js.map +1 -1
  19. package/dist/XmlScope.d.ts +2 -0
  20. package/dist/XmlScope.js +38 -0
  21. package/dist/XmlScope.js.map +1 -1
  22. package/dist/astUtils/creators.d.ts +3 -1
  23. package/dist/astUtils/creators.js +14 -4
  24. package/dist/astUtils/creators.js.map +1 -1
  25. package/dist/astUtils/reflection.d.ts +24 -5
  26. package/dist/astUtils/reflection.js +58 -13
  27. package/dist/astUtils/reflection.js.map +1 -1
  28. package/dist/astUtils/reflection.spec.js +85 -3
  29. package/dist/astUtils/reflection.spec.js.map +1 -1
  30. package/dist/bscPlugin/CallExpressionInfo.d.ts +3 -3
  31. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  32. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
  33. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  34. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +44 -1
  35. package/dist/bscPlugin/completions/CompletionsProcessor.js +353 -20
  36. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  37. package/dist/bscPlugin/completions/CompletionsProcessor.spec.d.ts +1 -0
  38. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1452 -0
  39. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
  40. package/dist/bscPlugin/hover/HoverProcessor.d.ts +9 -4
  41. package/dist/bscPlugin/hover/HoverProcessor.js +64 -67
  42. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  43. package/dist/bscPlugin/hover/HoverProcessor.spec.js +162 -4
  44. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  45. package/dist/bscPlugin/validation/BrsFileValidator.js +20 -16
  46. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  47. package/dist/bscPlugin/validation/ScopeValidator.d.ts +22 -1
  48. package/dist/bscPlugin/validation/ScopeValidator.js +194 -42
  49. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  50. package/dist/bscPlugin/validation/ScopeValidator.spec.js +621 -1
  51. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  52. package/dist/diagnosticUtils.d.ts +7 -2
  53. package/dist/diagnosticUtils.js +43 -15
  54. package/dist/diagnosticUtils.js.map +1 -1
  55. package/dist/files/BrsFile.Class.spec.js +10 -8
  56. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  57. package/dist/files/BrsFile.d.ts +3 -20
  58. package/dist/files/BrsFile.js +7 -355
  59. package/dist/files/BrsFile.js.map +1 -1
  60. package/dist/files/BrsFile.spec.js +2 -248
  61. package/dist/files/BrsFile.spec.js.map +1 -1
  62. package/dist/files/XmlFile.d.ts +1 -6
  63. package/dist/files/XmlFile.js +0 -13
  64. package/dist/files/XmlFile.js.map +1 -1
  65. package/dist/files/XmlFile.spec.js +0 -36
  66. package/dist/files/XmlFile.spec.js.map +1 -1
  67. package/dist/globalCallables.js +1 -5
  68. package/dist/globalCallables.js.map +1 -1
  69. package/dist/interfaces.d.ts +22 -2
  70. package/dist/interfaces.js +4 -1
  71. package/dist/interfaces.js.map +1 -1
  72. package/dist/lexer/Lexer.d.ts +12 -0
  73. package/dist/lexer/Lexer.js +27 -2
  74. package/dist/lexer/Lexer.js.map +1 -1
  75. package/dist/lexer/Lexer.spec.js +40 -0
  76. package/dist/lexer/Lexer.spec.js.map +1 -1
  77. package/dist/lexer/Token.d.ts +4 -0
  78. package/dist/lexer/Token.js.map +1 -1
  79. package/dist/lexer/TokenKind.d.ts +4 -0
  80. package/dist/lexer/TokenKind.js +10 -1
  81. package/dist/lexer/TokenKind.js.map +1 -1
  82. package/dist/parser/AstNode.d.ts +8 -1
  83. package/dist/parser/AstNode.js +16 -0
  84. package/dist/parser/AstNode.js.map +1 -1
  85. package/dist/parser/Expression.d.ts +16 -1
  86. package/dist/parser/Expression.js +75 -11
  87. package/dist/parser/Expression.js.map +1 -1
  88. package/dist/parser/Parser.d.ts +7 -0
  89. package/dist/parser/Parser.js +55 -7
  90. package/dist/parser/Parser.js.map +1 -1
  91. package/dist/parser/Parser.spec.js +330 -4
  92. package/dist/parser/Parser.spec.js.map +1 -1
  93. package/dist/parser/SGTypes.d.ts +1 -1
  94. package/dist/parser/Statement.d.ts +18 -6
  95. package/dist/parser/Statement.js +54 -16
  96. package/dist/parser/Statement.js.map +1 -1
  97. package/dist/parser/tests/Parser.spec.js +2 -1
  98. package/dist/parser/tests/Parser.spec.js.map +1 -1
  99. package/dist/parser/tests/controlFlow/For.spec.js +16 -8
  100. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  101. package/dist/parser/tests/controlFlow/ForEach.spec.js +12 -6
  102. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  103. package/dist/parser/tests/controlFlow/While.spec.js +8 -4
  104. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  105. package/dist/parser/tests/expression/Call.spec.js +4 -4
  106. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  107. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +13 -13
  108. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  109. package/dist/parser/tests/statement/ConstStatement.spec.js +1 -34
  110. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  111. package/dist/parser/tests/statement/Enum.spec.js +1 -257
  112. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  113. package/dist/parser/tests/statement/InterfaceStatement.spec.js +8 -0
  114. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  115. package/dist/parser/tests/statement/PrintStatement.spec.js +6 -3
  116. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  117. package/dist/parser/tests/statement/ReturnStatement.spec.js +5 -3
  118. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  119. package/dist/parser/tests/statement/Set.spec.js +26 -13
  120. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  121. package/dist/roku-types/data.json +156 -111
  122. package/dist/roku-types/index.d.ts +2 -27
  123. package/dist/types/ArrayType.d.ts +4 -1
  124. package/dist/types/ArrayType.js +43 -7
  125. package/dist/types/ArrayType.js.map +1 -1
  126. package/dist/types/ArrayType.spec.js +31 -2
  127. package/dist/types/ArrayType.spec.js.map +1 -1
  128. package/dist/types/AssociativeArrayType.d.ts +11 -0
  129. package/dist/types/AssociativeArrayType.js +52 -0
  130. package/dist/types/AssociativeArrayType.js.map +1 -0
  131. package/dist/types/BaseFunctionType.d.ts +2 -1
  132. package/dist/types/BaseFunctionType.js +1 -1
  133. package/dist/types/BaseFunctionType.js.map +1 -1
  134. package/dist/types/BooleanType.d.ts +2 -4
  135. package/dist/types/BooleanType.js +6 -7
  136. package/dist/types/BooleanType.js.map +1 -1
  137. package/dist/types/BscType.d.ts +8 -4
  138. package/dist/types/BscType.js +42 -14
  139. package/dist/types/BscType.js.map +1 -1
  140. package/dist/types/BscTypeKind.d.ts +2 -0
  141. package/dist/types/BscTypeKind.js +2 -0
  142. package/dist/types/BscTypeKind.js.map +1 -1
  143. package/dist/types/BuiltInInterfaceAdder.d.ts +20 -0
  144. package/dist/types/BuiltInInterfaceAdder.js +139 -0
  145. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  146. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
  147. package/dist/types/BuiltInInterfaceAdder.spec.js +109 -0
  148. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
  149. package/dist/types/ClassType.d.ts +6 -1
  150. package/dist/types/ClassType.js +26 -2
  151. package/dist/types/ClassType.js.map +1 -1
  152. package/dist/types/ComponentType.d.ts +26 -0
  153. package/dist/types/ComponentType.js +80 -0
  154. package/dist/types/ComponentType.js.map +1 -0
  155. package/dist/types/DoubleType.d.ts +2 -4
  156. package/dist/types/DoubleType.js +6 -7
  157. package/dist/types/DoubleType.js.map +1 -1
  158. package/dist/types/DynamicType.d.ts +2 -2
  159. package/dist/types/DynamicType.js +3 -1
  160. package/dist/types/DynamicType.js.map +1 -1
  161. package/dist/types/EnumType.d.ts +4 -5
  162. package/dist/types/EnumType.js +8 -7
  163. package/dist/types/EnumType.js.map +1 -1
  164. package/dist/types/FloatType.d.ts +2 -4
  165. package/dist/types/FloatType.js +6 -7
  166. package/dist/types/FloatType.js.map +1 -1
  167. package/dist/types/FunctionType.d.ts +2 -1
  168. package/dist/types/FunctionType.js +6 -2
  169. package/dist/types/FunctionType.js.map +1 -1
  170. package/dist/types/IntegerType.d.ts +2 -4
  171. package/dist/types/IntegerType.js +6 -7
  172. package/dist/types/IntegerType.js.map +1 -1
  173. package/dist/types/InterfaceType.d.ts +2 -1
  174. package/dist/types/InterfaceType.js +8 -4
  175. package/dist/types/InterfaceType.js.map +1 -1
  176. package/dist/types/InterfaceType.spec.js +2 -2
  177. package/dist/types/InvalidType.d.ts +1 -1
  178. package/dist/types/InvalidType.js +5 -1
  179. package/dist/types/InvalidType.js.map +1 -1
  180. package/dist/types/LongIntegerType.d.ts +2 -4
  181. package/dist/types/LongIntegerType.js +6 -7
  182. package/dist/types/LongIntegerType.js.map +1 -1
  183. package/dist/types/ObjectType.d.ts +3 -3
  184. package/dist/types/ObjectType.js +3 -1
  185. package/dist/types/ObjectType.js.map +1 -1
  186. package/dist/types/ReferenceType.d.ts +14 -0
  187. package/dist/types/ReferenceType.js +114 -13
  188. package/dist/types/ReferenceType.js.map +1 -1
  189. package/dist/types/ReferenceType.spec.js +15 -0
  190. package/dist/types/ReferenceType.spec.js.map +1 -1
  191. package/dist/types/StringType.d.ts +2 -4
  192. package/dist/types/StringType.js +5 -6
  193. package/dist/types/StringType.js.map +1 -1
  194. package/dist/types/TypedFunctionType.d.ts +2 -1
  195. package/dist/types/TypedFunctionType.js +10 -3
  196. package/dist/types/TypedFunctionType.js.map +1 -1
  197. package/dist/types/UninitializedType.d.ts +2 -1
  198. package/dist/types/UninitializedType.js +1 -1
  199. package/dist/types/UninitializedType.js.map +1 -1
  200. package/dist/types/UnionType.d.ts +4 -2
  201. package/dist/types/UnionType.js +25 -4
  202. package/dist/types/UnionType.js.map +1 -1
  203. package/dist/types/UnionType.spec.js +46 -19
  204. package/dist/types/UnionType.spec.js.map +1 -1
  205. package/dist/types/VoidType.d.ts +2 -1
  206. package/dist/types/VoidType.js +6 -2
  207. package/dist/types/VoidType.js.map +1 -1
  208. package/dist/types/helpers.d.ts +2 -0
  209. package/dist/types/helpers.js +18 -3
  210. package/dist/types/helpers.js.map +1 -1
  211. package/dist/util.d.ts +25 -2
  212. package/dist/util.js +179 -13
  213. package/dist/util.js.map +1 -1
  214. package/package.json +1 -1
@@ -0,0 +1,1452 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chai_config_spec_1 = require("../../chai-config.spec");
4
+ const Program_1 = require("../../Program");
5
+ const util_1 = require("../../util");
6
+ const vscode_languageserver_1 = require("vscode-languageserver");
7
+ const sinon_1 = require("sinon");
8
+ const testHelpers_spec_1 = require("../../testHelpers.spec");
9
+ const XmlFile_1 = require("../../files/XmlFile");
10
+ const TokenKind_1 = require("../../lexer/TokenKind");
11
+ const CompletionsProcessor_1 = require("./CompletionsProcessor");
12
+ const pick = require("object.pick");
13
+ const BrsFile_1 = require("../../files/BrsFile");
14
+ const fsExtra = require("fs-extra");
15
+ describe('CompletionsProcessor', () => {
16
+ let program;
17
+ let sinon = (0, sinon_1.createSandbox)();
18
+ beforeEach(() => {
19
+ fsExtra.emptyDirSync(testHelpers_spec_1.tempDir);
20
+ fsExtra.ensureDirSync(testHelpers_spec_1.rootDir);
21
+ fsExtra.ensureDirSync(testHelpers_spec_1.stagingDir);
22
+ program = new Program_1.Program({ rootDir: testHelpers_spec_1.rootDir });
23
+ });
24
+ afterEach(() => {
25
+ sinon.restore();
26
+ program.dispose();
27
+ });
28
+ describe('getCompletions - Program.spec', () => {
29
+ it('includes `for each` variable', () => {
30
+ program.setFile('source/main.brs', `
31
+ sub main()
32
+ items = [1, 2, 3]
33
+ for each thing in items
34
+ t =
35
+ end for
36
+ end sub
37
+ `);
38
+ program.validate();
39
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 28)).map(x => x.label);
40
+ (0, chai_config_spec_1.expect)(completions).to.include('thing');
41
+ });
42
+ it('includes `for` variable', () => {
43
+ program.setFile('source/main.brs', `
44
+ sub main()
45
+ for i = 0 to 10
46
+ t =
47
+ end for
48
+ end sub
49
+ `);
50
+ program.validate();
51
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 28)).map(x => x.label);
52
+ (0, chai_config_spec_1.expect)(completions).to.include('i');
53
+ });
54
+ it('should include first-level namespace names for brighterscript files', () => {
55
+ program.setFile('source/main.bs', `
56
+ namespace NameA.NameB.NameC
57
+ sub DoSomething()
58
+ end sub
59
+ end namespace
60
+ sub main()
61
+ print
62
+ end sub
63
+ `);
64
+ program.validate();
65
+ // print |
66
+ const completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(6, 25));
67
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
68
+ label: 'NameA',
69
+ kind: vscode_languageserver_1.CompletionItemKind.Module
70
+ }]);
71
+ (0, testHelpers_spec_1.expectCompletionsExcludes)(completions, [{
72
+ label: 'NameB',
73
+ kind: vscode_languageserver_1.CompletionItemKind.Module
74
+ }, {
75
+ label: 'NameA.NameB',
76
+ kind: vscode_languageserver_1.CompletionItemKind.Module
77
+ }, {
78
+ label: 'NameA.NameB.NameC',
79
+ kind: vscode_languageserver_1.CompletionItemKind.Module
80
+ }, {
81
+ label: 'NameA.NameB.NameC.DoSomething',
82
+ kind: vscode_languageserver_1.CompletionItemKind.Module
83
+ }]);
84
+ });
85
+ it('resolves completions for namespaces with next namespace part for brighterscript file', () => {
86
+ program.setFile('source/main.bs', `
87
+ namespace NameA.NameB.NameC
88
+ sub DoSomething()
89
+ end sub
90
+ end namespace
91
+ sub main()
92
+ NameA.
93
+ end sub
94
+ `);
95
+ program.validate();
96
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(6, 26)).map(x => x.label);
97
+ (0, chai_config_spec_1.expect)(completions).to.include('NameB');
98
+ (0, chai_config_spec_1.expect)(completions).not.to.include('NameA');
99
+ (0, chai_config_spec_1.expect)(completions).not.to.include('NameA.NameB');
100
+ (0, chai_config_spec_1.expect)(completions).not.to.include('NameA.NameB.NameC');
101
+ (0, chai_config_spec_1.expect)(completions).not.to.include('NameA.NameB.NameC.DoSomething');
102
+ });
103
+ it('finds namespace members for brighterscript file', () => {
104
+ program.setFile('source/main.bs', `
105
+ sub main()
106
+ NameA.
107
+ NameA.NameB.
108
+ NameA.NameB.NameC.
109
+ end sub
110
+ namespace NameA
111
+ sub alertA()
112
+ end sub
113
+ end namespace
114
+ namespace NameA
115
+ sub info()
116
+ end sub
117
+ end namespace
118
+ namespace NameA.NameB
119
+ sub alertB()
120
+ end sub
121
+ end namespace
122
+ namespace NameA.NameB.NameC
123
+ sub alertC()
124
+ end sub
125
+ end namespace
126
+ `);
127
+ program.validate();
128
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 26)).map(x => x.label).sort()).to.eql(['NameB', 'alertA', 'info']);
129
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(3, 32)).map(x => x.label).sort()).to.eql(['NameC', 'alertB']);
130
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(4, 38)).map(x => x.label).sort()).to.eql(['alertC']);
131
+ });
132
+ it('finds namespace members for classes', () => {
133
+ program.setFile('source/main.bs', `
134
+ sub main()
135
+ NameA.
136
+ NameA.NameB.
137
+ NameA.NameB.NameC.
138
+ end sub
139
+ namespace NameA
140
+ sub alertA()
141
+ end sub
142
+ end namespace
143
+ namespace NameA
144
+ sub info()
145
+ end sub
146
+ class MyClassA
147
+ end class
148
+ end namespace
149
+ namespace NameA.NameB
150
+ sub alertB()
151
+ end sub
152
+ class MyClassB
153
+ end class
154
+ end namespace
155
+ namespace NameA.NameB.NameC
156
+ sub alertC()
157
+ end sub
158
+ end namespace
159
+ `);
160
+ program.validate();
161
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 26)).map(x => x.label).sort()).to.eql(['MyClassA', 'NameB', 'alertA', 'info']);
162
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(3, 32)).map(x => x.label).sort()).to.eql(['MyClassB', 'NameC', 'alertB']);
163
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(4, 38)).map(x => x.label).sort()).to.eql(['alertC']);
164
+ });
165
+ it('finds only namespaces that have classes, when new keyword is used', () => {
166
+ program.setFile('source/main.bs', `
167
+ sub main()
168
+ a = new NameA.
169
+ b = new NameA.NameB.
170
+ c = new NameA.NameB.NameC.
171
+ end sub
172
+ namespace NameA
173
+ sub alertA()
174
+ end sub
175
+ end namespace
176
+ namespace NameA
177
+ sub info()
178
+ end sub
179
+ class MyClassA
180
+ end class
181
+ end namespace
182
+ namespace NameA.NoClassA
183
+ end namespace
184
+ namespace NameA.NoClassB
185
+ end namespace
186
+ namespace NameA.NameB
187
+ sub alertB()
188
+ end sub
189
+ class MyClassB
190
+ end class
191
+ end namespace
192
+ namespace NameA.NameB.NoClass
193
+ end namespace
194
+ namespace NameA.NameB.NameC
195
+ sub alertC()
196
+ end sub
197
+ end namespace
198
+ `);
199
+ program.validate();
200
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 34)).map(x => x.label).sort()).to.eql(['MyClassA', 'NameB']);
201
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(3, 40)).map(x => x.label).sort()).to.eql(['MyClassB']);
202
+ (0, chai_config_spec_1.expect)(program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(4, 46)).map(x => x.label).sort()).to.be.empty;
203
+ });
204
+ //Bron.. pain to get this working.. do we realy need this? seems moot with ropm..
205
+ it.skip('should include translated namespace function names for brightscript files', () => {
206
+ program.setFile('source/main.bs', `
207
+ namespace NameA.NameB.NameC
208
+ sub DoSomething()
209
+ end sub
210
+ end namespace
211
+ `);
212
+ program.setFile('source/lib.brs', `
213
+ sub test()
214
+
215
+ end sub
216
+ `);
217
+ program.validate();
218
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/lib.brs`, vscode_languageserver_1.Position.create(2, 23));
219
+ (0, chai_config_spec_1.expect)(completions.map(x => x.label)).to.include('NameA_NameB_NameC_DoSomething');
220
+ });
221
+ it('includes global completions for file with no scope', () => {
222
+ program.setFile('source/main.brs', `
223
+ function Main()
224
+ age = 1
225
+ end function
226
+ `);
227
+ program.validate();
228
+ let completions = program.getCompletions('source/main.brs', vscode_languageserver_1.Position.create(2, 21));
229
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label.toLowerCase() === 'abs')).to.be.lengthOf(1);
230
+ });
231
+ it('filters out text results for top-level function statements', () => {
232
+ program.setFile('source/main.brs', `
233
+ function Main()
234
+ age = 1
235
+ end function
236
+ `);
237
+ program.validate();
238
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 21));
239
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'Main')).to.be.lengthOf(1);
240
+ });
241
+ it('does not filter text results for object properties used in conditional statements', () => {
242
+ program.setFile('source/main.brs', `
243
+ sub Main()
244
+ p.
245
+ end sub
246
+ sub SayHello()
247
+ person = {}
248
+ if person.isAlive then
249
+ print "Hello"
250
+ end if
251
+ end sub
252
+ `);
253
+ program.validate();
254
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 22));
255
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'isAlive')).to.be.lengthOf(1);
256
+ });
257
+ it('does not filter text results for object properties used in assignments', () => {
258
+ program.setFile('source/main.brs', `
259
+ sub Main()
260
+ p.
261
+ end sub
262
+ sub SayHello()
263
+ person = {}
264
+ localVar = person.name
265
+ end sub
266
+ `);
267
+ program.validate();
268
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 22));
269
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'name')).to.be.lengthOf(1);
270
+ });
271
+ it('does not filter text results for object properties', () => {
272
+ program.setFile('source/main.brs', `
273
+ sub Main()
274
+ p.
275
+ end sub
276
+ sub SayHello()
277
+ person = {}
278
+ person.name = "bob"
279
+ end sub
280
+ `);
281
+ program.validate();
282
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 22));
283
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'name')).to.be.lengthOf(1);
284
+ });
285
+ it('filters out text results for local vars used in conditional statements', () => {
286
+ program.setFile('source/main.brs', `
287
+ sub Main()
288
+
289
+ end sub
290
+ sub SayHello()
291
+ isTrue = true
292
+ if isTrue then
293
+ print "is true"
294
+ end if
295
+ end sub
296
+ `);
297
+ program.validate();
298
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 10));
299
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'isTrue')).to.be.lengthOf(0);
300
+ });
301
+ it('filters out text results for local variable assignments', () => {
302
+ program.setFile('source/main.brs', `
303
+ sub Main()
304
+
305
+ end sub
306
+ sub SayHello()
307
+ message = "Hello"
308
+ end sub
309
+ `);
310
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 10));
311
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'message')).to.be.lengthOf(0);
312
+ });
313
+ it('filters out text results for local variables used in assignments', () => {
314
+ program.setFile('source/main.brs', `
315
+ sub Main()
316
+
317
+ end sub
318
+ sub SayHello()
319
+ message = "Hello"
320
+ otherVar = message
321
+ end sub
322
+ `);
323
+ program.validate();
324
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 10));
325
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.label === 'message')).to.be.lengthOf(0);
326
+ });
327
+ it('does not suggest local variables when initiated to the right of a period', () => {
328
+ program.setFile('source/main.brs', `
329
+ function Main()
330
+ helloMessage = "jack"
331
+ person.hello
332
+ end function
333
+ `);
334
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 32));
335
+ (0, chai_config_spec_1.expect)(completions.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Variable).map(x => x.label)).not.to.contain('helloMessage');
336
+ });
337
+ it('finds all file paths when initiated on xml uri', () => {
338
+ let xmlPath = (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/components/component1.xml`;
339
+ program.setFile('components/component1.xml', (0, testHelpers_spec_1.trim) `
340
+ <?xml version="1.0" encoding="utf-8" ?>
341
+ <component name="HeroScene" extends="Scene">
342
+ <script type="text/brightscript" uri="" />
343
+ </component>
344
+ `);
345
+ program.setFile('components/component1.brs', '');
346
+ program.validate();
347
+ let completions = program.getCompletions(xmlPath, vscode_languageserver_1.Position.create(2, 42));
348
+ (0, chai_config_spec_1.expect)(completions[0]).to.include({
349
+ kind: vscode_languageserver_1.CompletionItemKind.File,
350
+ label: 'component1.brs'
351
+ });
352
+ (0, chai_config_spec_1.expect)(completions[1]).to.include({
353
+ kind: vscode_languageserver_1.CompletionItemKind.File,
354
+ label: 'pkg:/components/component1.brs'
355
+ });
356
+ //it should NOT include the global methods
357
+ (0, chai_config_spec_1.expect)(completions).to.be.lengthOf(2);
358
+ });
359
+ it('get all functions and properties in scope when doing any dotted get on non m ', () => {
360
+ program.setFile('source/main.bs', `
361
+ sub main()
362
+ thing.anonPropA = "foo"
363
+ thing.anonPropB = "bar"
364
+ thing.person
365
+ end sub
366
+ class MyClassA
367
+ personName = "rafa"
368
+ personAName = "rafaA"
369
+ function personAMethodA()
370
+ end function
371
+ function personAMethodB()
372
+ end function
373
+ end class
374
+ namespace NameA
375
+ sub alertA()
376
+ end sub
377
+ end namespace
378
+ namespace NameA.NameB
379
+ sub alertB()
380
+ end sub
381
+ class MyClassB
382
+ personName = "roger"
383
+ personBName = "rogerB"
384
+ function personAMethodC()
385
+ end function
386
+ function personBMethodA()
387
+ end function
388
+ function personBMethodB()
389
+ end function
390
+ end class
391
+ end namespace
392
+ namespace NameA.NameB.NameC
393
+ sub alertC()
394
+ end sub
395
+ end namespace
396
+ `);
397
+ program.validate();
398
+ //note - we let the vscode extension do the filtering, so we still return everything; otherwise it exhibits strange behaviour in the IDE
399
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(4, 32))).map(x => x.label).sort()).to.eql(['anonPropA', 'anonPropB', 'person', 'personAMethodA', 'personAMethodB', 'personAMethodC', 'personAName', 'personBMethodA', 'personBMethodB', 'personBName', 'personName']);
400
+ });
401
+ it('get all functions and properties relevant for m ', () => {
402
+ program.setFile('source/main.bs', `
403
+ class MyClassA
404
+ function new()
405
+ m.
406
+ end function
407
+ personName = "rafa"
408
+ personAName = "rafaA"
409
+ function personAMethodA()
410
+ end function
411
+ function personAMethodB()
412
+ end function
413
+ end class
414
+ class MyClassB
415
+ personName = "roger"
416
+ personBName = "rogerB"
417
+ function personAMethodC()
418
+ end function
419
+ function personBMethodA()
420
+ end function
421
+ function personBMethodB()
422
+ end function
423
+ end class
424
+ class MyClassC extends MyClassA
425
+ function new()
426
+ m.
427
+ end function
428
+ personCName = "rogerC"
429
+ function personCMethodC()
430
+ end function
431
+ function personCMethodA()
432
+ end function
433
+ function personCMethodB()
434
+ end function
435
+ end class
436
+ sub alertC()
437
+ end sub
438
+ `);
439
+ program.validate();
440
+ const myClassACompletions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(3, 26));
441
+ // remove completions with sortText (they are built in methods), then sort the remaining labels
442
+ const myClassACompletionsSorted = myClassACompletions.filter(x => !x.sortText).map(x => x.label).sort();
443
+ (0, chai_config_spec_1.expect)(myClassACompletionsSorted).to.eql(['personAMethodA', 'personAMethodB', 'personAName', 'personName']);
444
+ const myClassCCompletions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(24, 26));
445
+ // remove completions with sortText (they are built in methods), then sort the remaining labels
446
+ const myClassCCompletionsSorted = myClassCCompletions.filter(x => !x.sortText).map(x => x.label).sort();
447
+ (0, chai_config_spec_1.expect)(myClassCCompletionsSorted).to.eql(['personAMethodA', 'personAMethodB', 'personAName', 'personCMethodA', 'personCMethodB', 'personCMethodC', 'personCName', 'personName']);
448
+ });
449
+ it.skip('include non-namespaced classes in the list of general output', () => {
450
+ program.setFile('source/main.bs', `
451
+ function regularFunc()
452
+ MyClass
453
+ end function
454
+ sub alertC()
455
+ end sub
456
+ class MyClassA
457
+ end class
458
+ class MyClassB
459
+ end class
460
+ class MyClassC extends MyClassA
461
+ end class
462
+ `);
463
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(3, 26))).map(x => x.label).sort()).to.include.members(['MyClassA', 'MyClassB', 'MyClassC']);
464
+ });
465
+ it('only include classes when using new keyword', () => {
466
+ program.setFile('source/main.bs', `
467
+ class MyClassA
468
+ end class
469
+ class MyClassB
470
+ end class
471
+ class MyClassC extends MyClassA
472
+ end class
473
+ function regularFunc()
474
+ new MyClass
475
+ end function
476
+ sub alertC()
477
+ end sub
478
+ `);
479
+ program.validate();
480
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 29))).map(x => x.label).sort()).to.eql(['MyClassA', 'MyClassB', 'MyClassC']);
481
+ });
482
+ it('gets completions when using callfunc invocation', () => {
483
+ program.setFile('source/main.bs', `
484
+ function doStuff(myNode)
485
+ myNode@.sayHello(1, 2)
486
+ end function
487
+ `);
488
+ program.setFile('components/MyNode.bs', `
489
+ function sayHello(text, text2)
490
+ end function
491
+ `);
492
+ program.setFile('components/MyNode.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
493
+ <component name="Component1" extends="Scene">
494
+ <script type="text/brightscript" uri="pkg:/components/MyNode.bs" />
495
+ <interface>
496
+ <function name="sayHello"/>
497
+ </interface>
498
+ </component>`);
499
+ program.validate();
500
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
501
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 30))).map(x => x.label).sort()).to.eql(['sayHello']);
502
+ });
503
+ it('gets completions for callfunc invocation with multiple nodes', () => {
504
+ program.setFile('source/main.bs', `
505
+ function main()
506
+ myNode@.sayHello(arg1)
507
+ end function
508
+ `);
509
+ program.setFile('components/MyNode.bs', `
510
+ function sayHello(text, text2)
511
+ end function
512
+ function sayHello2(text, text2)
513
+ end function
514
+ `);
515
+ program.setFile('components/MyNode.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
516
+ <component name="Component1" extends="Scene">
517
+ <script type="text/brightscript" uri="pkg:/components/MyNode.bs" />
518
+ <interface>
519
+ <function name="sayHello"/>
520
+ <function name="sayHello2"/>
521
+ </interface>
522
+ </component>`);
523
+ program.setFile('components/MyNode2.bs', `
524
+ function sayHello3(text, text2)
525
+ end function
526
+ function sayHello4(text, text2)
527
+ end function
528
+ `);
529
+ program.setFile('components/MyNode2.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
530
+ <component name="Component2" extends="Scene">
531
+ <script type="text/brightscript" uri="pkg:/components/MyNode2.bs" />
532
+ <interface>
533
+ <function name="sayHello3"/>
534
+ <function name="sayHello4"/>
535
+ </interface>
536
+ </component>`);
537
+ program.validate();
538
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 30))).map(x => x.label).sort()).to.eql(['sayHello', 'sayHello2', 'sayHello3', 'sayHello4']);
539
+ });
540
+ it('gets completions for callfunc invocation with multiple nodes and validates single code completion results', () => {
541
+ program.setFile('source/main.bs', `
542
+ function main()
543
+ ParentNode@.sayHello(arg1)
544
+ end function
545
+ `);
546
+ program.setFile('components/ParentNode.bs', `
547
+ function sayHello(text, text2)
548
+ end function
549
+ `);
550
+ program.setFile('components/ParentNode.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
551
+ <component name="ParentNode" extends="Scene">
552
+ <script type="text/brightscript" uri="pkg:/components/ParentNode.bs" />
553
+ <interface>
554
+ <function name="sayHello"/>
555
+ </interface>
556
+ </component>`);
557
+ program.setFile('components/ChildNode.bs', `
558
+ function sayHello(text, text2)
559
+ end function
560
+ `);
561
+ program.setFile('components/ChildNode.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
562
+ <component name="ChildNode" extends="ParentNode">
563
+ <script type="text/brightscript" uri="pkg:/components/ChildNode.bs" />
564
+ </component>`);
565
+ program.validate();
566
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 31))).map(x => x.label).sort()).to.eql(['sayHello']);
567
+ });
568
+ it('gets completions for extended nodes with callfunc invocation - ensure overridden methods included', () => {
569
+ program.setFile('source/main.bs', `
570
+ function main()
571
+ myNode@.sayHello(arg1)
572
+ end function
573
+ `);
574
+ program.setFile('components/MyNode.bs', `
575
+ function sayHello(text, text2)
576
+ end function
577
+ function sayHello2(text, text2)
578
+ end function
579
+ `);
580
+ program.setFile('components/MyNode.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
581
+ <component name="Component1" extends="Scene">
582
+ <script type="text/brightscript" uri="pkg:/components/MyNode.bs" />
583
+ <interface>
584
+ <function name="sayHello"/>
585
+ <function name="sayHello2"/>
586
+ </interface>
587
+ </component>`);
588
+ program.setFile('components/MyNode2.bs', `
589
+ function sayHello3(text, text2)
590
+ end function
591
+ function sayHello2(text, text2)
592
+ end function
593
+ function sayHello4(text, text2)
594
+ end function
595
+ `);
596
+ program.setFile('components/MyNode2.xml', (0, testHelpers_spec_1.trim) `<?xml version="1.0" encoding="utf-8" ?>
597
+ <component name="Component2" extends="Component1">
598
+ <script type="text/brightscript" uri="pkg:/components/MyNode2.bs" />
599
+ <interface>
600
+ <function name="sayHello3"/>
601
+ <function name="sayHello4"/>
602
+ </interface>
603
+ </component>`);
604
+ program.validate();
605
+ (0, chai_config_spec_1.expect)((program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 30))).map(x => x.label).sort()).to.eql(['sayHello', 'sayHello2', 'sayHello3', 'sayHello4']);
606
+ });
607
+ describe('getCompletions', () => {
608
+ it('returns all functions in scope', () => {
609
+ program.setFile('source/main.brs', `
610
+ sub Main()
611
+
612
+ end sub
613
+
614
+ sub ActionA()
615
+ end sub
616
+ `);
617
+ program.setFile('source/lib.brs', `
618
+ sub ActionB()
619
+ end sub
620
+ `);
621
+ program.validate();
622
+ let completions = program
623
+ //get completions
624
+ .getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, util_1.default.createPosition(2, 10))
625
+ //only keep the label property for this test
626
+ .map(x => pick(x, 'label'));
627
+ (0, chai_config_spec_1.expect)(completions).to.deep.include({ label: 'Main' });
628
+ (0, chai_config_spec_1.expect)(completions).to.deep.include({ label: 'ActionA' });
629
+ (0, chai_config_spec_1.expect)(completions).to.deep.include({ label: 'ActionB' });
630
+ });
631
+ it('returns all variables in scope', () => {
632
+ program.setFile('source/main.brs', `
633
+ sub Main()
634
+ name = "bob"
635
+ age = 20
636
+ shoeSize = 12.5
637
+ end sub
638
+ sub ActionA()
639
+ end sub
640
+ `);
641
+ program.setFile('source/lib.brs', `
642
+ sub ActionB()
643
+ end sub
644
+ `);
645
+ program.validate();
646
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, util_1.default.createPosition(2, 24));
647
+ let labels = completions.map(x => pick(x, 'label'));
648
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'Main' });
649
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'ActionA' });
650
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'ActionB' });
651
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'name' });
652
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'age' });
653
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'shoeSize' });
654
+ });
655
+ it('returns empty set when out of range', () => {
656
+ const position = util_1.default.createPosition(99, 99);
657
+ const mainFile = program.setFile('source/main.brs', '');
658
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, position);
659
+ const completionProcessor = new CompletionsProcessor_1.CompletionsProcessor({
660
+ program: program,
661
+ file: mainFile,
662
+ position: position,
663
+ scopes: [],
664
+ completions: []
665
+ });
666
+ program.validate();
667
+ //get the name of all global completions
668
+ const globalCompletions = program.globalScope.getAllFiles().flatMap(x => completionProcessor.getBrsFileCompletions(position, x, program.globalScope)).map(x => x.label);
669
+ //filter out completions from global scope
670
+ completions = completions.filter(x => !globalCompletions.includes(x.label));
671
+ (0, chai_config_spec_1.expect)(completions).to.be.empty;
672
+ });
673
+ it('finds parameters', () => {
674
+ program.setFile('source/main.brs', `
675
+ sub Main(count = 1)
676
+ firstName = "bob"
677
+ age = 21
678
+ shoeSize = 10
679
+ end sub
680
+ `);
681
+ program.validate();
682
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 10));
683
+ let labels = completions.map(x => pick(x, 'label'));
684
+ (0, chai_config_spec_1.expect)(labels).to.deep.include({ label: 'count' });
685
+ });
686
+ });
687
+ });
688
+ describe('getCompletions - BrsFile.spec', () => {
689
+ it('does not crash for callfunc on a function call', () => {
690
+ const file = program.setFile('source/main.brs', `
691
+ sub main()
692
+ getManager()@.
693
+ end sub
694
+ `);
695
+ program.validate();
696
+ (0, chai_config_spec_1.expect)(() => {
697
+ program.getCompletions(file.srcPath, util_1.default.createPosition(2, 34));
698
+ }).not.to.throw;
699
+ });
700
+ it('suggests pkg paths in strings that match that criteria', () => {
701
+ program.setFile('source/main.brs', `
702
+ sub main()
703
+ print "pkg:"
704
+ end sub
705
+ `);
706
+ program.validate();
707
+ const result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
708
+ const names = result.map(x => x.label);
709
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
710
+ 'pkg:/source/main.brs'
711
+ ]);
712
+ });
713
+ it('suggests libpkg paths in strings that match that criteria', () => {
714
+ program.setFile('source/main.brs', `
715
+ sub main()
716
+ print "libpkg:"
717
+ end sub
718
+ `);
719
+ program.validate();
720
+ const result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
721
+ const names = result.map(x => x.label);
722
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
723
+ 'libpkg:/source/main.brs'
724
+ ]);
725
+ });
726
+ it('suggests pkg paths in template strings', () => {
727
+ program.setFile('source/main.brs', `
728
+ sub main()
729
+ print \`pkg:\`
730
+ end sub
731
+ `);
732
+ program.validate();
733
+ const result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
734
+ const names = result.map(x => x.label);
735
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
736
+ 'pkg:/source/main.brs'
737
+ ]);
738
+ });
739
+ it('waits for the file to be processed before collecting completions', () => {
740
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
741
+ program.setFile('source/main.brs', `
742
+ sub Main()
743
+ print "hello"
744
+ Say
745
+ end sub
746
+
747
+ sub SayHello()
748
+ end sub
749
+ `);
750
+ program.validate();
751
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
752
+ let names = result.map(x => x.label);
753
+ (0, chai_config_spec_1.expect)(names).to.includes('Main');
754
+ (0, chai_config_spec_1.expect)(names).to.includes('SayHello');
755
+ });
756
+ it('includes every type of item at base level', () => {
757
+ program.setFile('source/main.bs', `
758
+ sub main()
759
+ print
760
+ end sub
761
+ sub speak()
762
+ end sub
763
+ namespace stuff
764
+ end namespace
765
+ class Person
766
+ end class
767
+ enum Direction
768
+ end enum
769
+ `);
770
+ program.validate();
771
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 26)), [{
772
+ label: 'main',
773
+ kind: vscode_languageserver_1.CompletionItemKind.Function
774
+ }, {
775
+ label: 'speak',
776
+ kind: vscode_languageserver_1.CompletionItemKind.Function
777
+ }, {
778
+ label: 'stuff',
779
+ kind: vscode_languageserver_1.CompletionItemKind.Module
780
+ }, {
781
+ label: 'Person',
782
+ kind: vscode_languageserver_1.CompletionItemKind.Class
783
+ }, {
784
+ label: 'Direction',
785
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
786
+ }]);
787
+ });
788
+ describe('namespaces', () => {
789
+ it('gets full namespace completions at any point through the leading identifier', () => {
790
+ program.setFile('source/main.bs', `
791
+ sub main()
792
+ foo.bar
793
+ end sub
794
+
795
+ namespace foo.bar
796
+ end namespace
797
+
798
+ class Person
799
+ end class
800
+ `);
801
+ program.validate();
802
+ const result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 24)).map(x => x.label);
803
+ (0, chai_config_spec_1.expect)(result).includes('main');
804
+ (0, chai_config_spec_1.expect)(result).includes('foo');
805
+ (0, chai_config_spec_1.expect)(result).includes('Person');
806
+ });
807
+ it('gets namespace completions', () => {
808
+ program.setFile('source/main.bs', `
809
+ namespace foo.bar
810
+ function sayHello()
811
+ end function
812
+ end namespace
813
+
814
+ sub Main()
815
+ print "hello"
816
+ foo.ba
817
+ foo.bar.
818
+ end sub
819
+ `);
820
+ program.validate();
821
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 30));
822
+ let names = result.map(x => x.label);
823
+ (0, chai_config_spec_1.expect)(names).to.includes('bar');
824
+ result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(9, 32));
825
+ names = result.map(x => x.label);
826
+ (0, chai_config_spec_1.expect)(names).to.includes('sayHello');
827
+ });
828
+ });
829
+ it('always includes `m`', () => {
830
+ program.setFile('source/main.brs', `
831
+ sub Main()
832
+
833
+ end sub
834
+ `);
835
+ program.validate();
836
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
837
+ let names = result.map(x => x.label);
838
+ (0, chai_config_spec_1.expect)(names).to.contain('m');
839
+ });
840
+ it('does not fail for missing previousToken', () => {
841
+ //add a single character to the file, and get completions after it
842
+ program.setFile('source/main.brs', `i`);
843
+ program.validate();
844
+ (0, chai_config_spec_1.expect)(() => {
845
+ program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(0, 1)).map(x => x.label);
846
+ }).not.to.throw;
847
+ });
848
+ it.skip('includes all keywords`', () => {
849
+ program.setFile('source/main.brs', `
850
+ sub Main()
851
+
852
+ end sub
853
+ `);
854
+ program.validate();
855
+ let keywords = Object.keys(TokenKind_1.Keywords).filter(x => !x.includes(' '));
856
+ //inside the function
857
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
858
+ let names = result.map(x => x.label);
859
+ for (let keyword of keywords) {
860
+ (0, chai_config_spec_1.expect)(names).to.include(keyword);
861
+ }
862
+ //outside the function
863
+ result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 8));
864
+ names = result.map(x => x.label);
865
+ for (let keyword of keywords) {
866
+ (0, chai_config_spec_1.expect)(names).to.include(keyword);
867
+ }
868
+ });
869
+ it('does not provide completions within a comment', () => {
870
+ program.setFile('source/main.brs', `
871
+ sub Main()
872
+ 'some comment
873
+ end sub
874
+ `);
875
+ program.validate();
876
+ //inside the function
877
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 33));
878
+ (0, chai_config_spec_1.expect)(result).to.be.lengthOf(0);
879
+ });
880
+ it('does not provide duplicate entries for variables', () => {
881
+ program.setFile('source/main.brs', `
882
+ sub Main()
883
+ name = "bob"
884
+ age = 12
885
+ name = "john"
886
+ end sub
887
+ `);
888
+ program.validate();
889
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
890
+ let count = result.reduce((total, x) => {
891
+ return x.label === 'name' ? total + 1 : total;
892
+ }, 0);
893
+ (0, chai_config_spec_1.expect)(count).to.equal(1);
894
+ });
895
+ it('does not include `as` and `string` text options when used in function params', () => {
896
+ program.setFile('source/main.brs', `
897
+ sub Main(name as string)
898
+
899
+ end sub
900
+ `);
901
+ program.validate();
902
+ let result = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
903
+ (0, chai_config_spec_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
904
+ (0, chai_config_spec_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
905
+ });
906
+ it('does not provide intellisense results when inside a comment', () => {
907
+ program.setFile('source/main.brs', `
908
+ sub Main(name as string)
909
+ 'this is a comment
910
+ end sub
911
+ `);
912
+ program.validate();
913
+ let results = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 30));
914
+ (0, chai_config_spec_1.expect)(results).to.be.empty;
915
+ });
916
+ it('does provide intellisence for labels only after a goto keyword', () => {
917
+ var _a;
918
+ program.setFile('source/main.brs', `
919
+ sub Main(name as string)
920
+ something:
921
+ goto \nend sub
922
+ `);
923
+ program.validate();
924
+ let results = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 25));
925
+ (0, chai_config_spec_1.expect)(results.length).to.equal(1);
926
+ (0, chai_config_spec_1.expect)((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
927
+ });
928
+ });
929
+ describe('getCompletions - XmlFile.spec', () => {
930
+ it('formats completion paths with proper slashes', () => {
931
+ let scriptPath = (0, util_1.standardizePath) `C:/app/components/component1/component1.brs`;
932
+ program.files[scriptPath] = new BrsFile_1.BrsFile(scriptPath, (0, util_1.standardizePath) `components/component1/component1.brs`, program);
933
+ let xmlFile = new XmlFile_1.XmlFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/components/component1/component1.xml`, (0, util_1.standardizePath) `components/component1/component1.xml`, program);
934
+ xmlFile.parser.references.scriptTagImports.push({
935
+ pkgPath: (0, util_1.standardizePath) `components/component1/component1.brs`,
936
+ text: 'component1.brs',
937
+ filePathRange: vscode_languageserver_1.Range.create(1, 1, 1, 1)
938
+ });
939
+ const processesor = new CompletionsProcessor_1.CompletionsProcessor(null);
940
+ const completions = processesor.getXmlFileCompletions(vscode_languageserver_1.Position.create(1, 1), xmlFile);
941
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
942
+ label: 'component1.brs',
943
+ kind: vscode_languageserver_1.CompletionItemKind.File
944
+ }, {
945
+ label: 'pkg:/components/component1/component1.brs',
946
+ kind: vscode_languageserver_1.CompletionItemKind.File
947
+ }]);
948
+ });
949
+ //TODO - refine this test once cdata scripts are supported
950
+ it('prevents scope completions entirely', () => {
951
+ program.setFile('components/component1.brs', ``);
952
+ let xmlFile = program.setFile('components/component1.xml', (0, testHelpers_spec_1.trim) `
953
+ <?xml version="1.0" encoding="utf-8" ?>
954
+ <component name="ParentScene" extends="GrandparentScene">
955
+ <script type="text/brightscript" uri="./Component1.brs" />
956
+ </component>
957
+ `);
958
+ program.validate();
959
+ (0, chai_config_spec_1.expect)(program.getCompletions(xmlFile.srcPath, vscode_languageserver_1.Position.create(1, 1))).to.be.empty;
960
+ });
961
+ });
962
+ describe('documentation', () => {
963
+ it('returns documentation when possible', () => {
964
+ program.setFile('source/main.brs', `
965
+ sub Main()
966
+ print "hello"
967
+ Say
968
+ end sub
969
+
970
+ ' Says hello to the world
971
+ sub SayHello()
972
+ end sub
973
+ `);
974
+ program.validate();
975
+ // Say|
976
+ let completions = program.getCompletions(`${testHelpers_spec_1.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 22));
977
+ //it should find the completions for the global scope
978
+ (0, chai_config_spec_1.expect)(completions).to.be.length.greaterThan(0);
979
+ //it should find documentation for completions
980
+ (0, chai_config_spec_1.expect)(completions.filter(x => !!x.documentation)).to.have.length.greaterThan(0);
981
+ });
982
+ });
983
+ describe('getPartialVariableName', () => {
984
+ let entry = {
985
+ src: `${testHelpers_spec_1.rootDir}/source/lib.brs`,
986
+ dest: `source/lib.brs`
987
+ };
988
+ it('creates proper tokens', () => {
989
+ const file = program.setFile(entry, `call(ModuleA.ModuleB.ModuleC.`);
990
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
991
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
992
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
993
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
994
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
995
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
996
+ });
997
+ });
998
+ describe('const completions', () => {
999
+ it('shows up in standard completions', () => {
1000
+ program.setFile('source/main.bs', `
1001
+ const API_KEY = "123"
1002
+ sub log(message)
1003
+ log()
1004
+ end sub
1005
+ `);
1006
+ program.validate();
1007
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(
1008
+ // log(|)
1009
+ program.getCompletions('source/main.bs', util_1.default.createPosition(3, 24)), [{
1010
+ label: 'API_KEY',
1011
+ kind: vscode_languageserver_1.CompletionItemKind.Constant
1012
+ }]);
1013
+ });
1014
+ it('shows up in namespace completions', () => {
1015
+ program.setFile('source/main.bs', `
1016
+ namespace constants
1017
+ const API_KEY = "123"
1018
+ end namespace
1019
+ sub log(message)
1020
+ log(constants.)
1021
+ end sub
1022
+ `);
1023
+ program.validate();
1024
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(
1025
+ // log(|)
1026
+ program.getCompletions('source/main.bs', util_1.default.createPosition(5, 34)), [{
1027
+ label: 'API_KEY',
1028
+ kind: vscode_languageserver_1.CompletionItemKind.Constant
1029
+ }]);
1030
+ });
1031
+ });
1032
+ describe('enum completions', () => {
1033
+ it('does not crash when completing enum members with unsupported values', () => {
1034
+ program.setFile('source/main.bs', `
1035
+ sub Main()
1036
+ direction.obj
1037
+ end sub
1038
+ enum Direction
1039
+ up
1040
+ down
1041
+ obj = {}
1042
+ end enum
1043
+ `);
1044
+ program.validate();
1045
+ // direction.|obj
1046
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 30)), [{
1047
+ label: 'up',
1048
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1049
+ }, {
1050
+ label: 'down',
1051
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1052
+ }, {
1053
+ label: 'obj',
1054
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1055
+ }]);
1056
+ });
1057
+ it('gets enum statement completions from global enum', () => {
1058
+ program.setFile('source/main.bs', `
1059
+ sub Main()
1060
+ direction.down
1061
+ end sub
1062
+ enum Direction
1063
+ up
1064
+ down
1065
+ end enum
1066
+ `);
1067
+ program.validate();
1068
+ // |direction.down
1069
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 20)), [{
1070
+ label: 'Direction',
1071
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1072
+ }]);
1073
+ // dire|ction.down
1074
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 24)), [{
1075
+ label: 'Direction',
1076
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1077
+ }]);
1078
+ // direction|.down
1079
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 29)), [{
1080
+ label: 'Direction',
1081
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1082
+ }]);
1083
+ });
1084
+ it('gets enum member completions from global enum', () => {
1085
+ program.setFile('source/main.bs', `
1086
+ sub Main()
1087
+ direction.down
1088
+ end sub
1089
+ enum Direction
1090
+ up
1091
+ down
1092
+ end enum
1093
+ `);
1094
+ program.validate();
1095
+ // direction.|down
1096
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 30)), [{
1097
+ label: 'up',
1098
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1099
+ }, {
1100
+ label: 'down',
1101
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1102
+ }]);
1103
+ // direction.do|wn
1104
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 32)), [{
1105
+ label: 'up',
1106
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1107
+ }, {
1108
+ label: 'down',
1109
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1110
+ }]);
1111
+ // direction.down|
1112
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 34)), [{
1113
+ label: 'up',
1114
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1115
+ }, {
1116
+ label: 'down',
1117
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1118
+ }]);
1119
+ });
1120
+ it('gets enum statement completions from namespaced enum', () => {
1121
+ program.setFile('source/main.bs', `
1122
+ sub Main()
1123
+ enums.direction.down
1124
+ end sub
1125
+ namespace enums
1126
+ enum Direction
1127
+ up
1128
+ down
1129
+ end enum
1130
+ end namespace
1131
+ `);
1132
+ program.validate();
1133
+ // enums.|direction.down
1134
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 26)), [{
1135
+ label: 'Direction',
1136
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1137
+ }]);
1138
+ // enums.dire|ction.down
1139
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 30)), [{
1140
+ label: 'Direction',
1141
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1142
+ }]);
1143
+ // enums.direction|.down
1144
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 35)), [{
1145
+ label: 'Direction',
1146
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1147
+ }]);
1148
+ });
1149
+ it('gets enum member completions from namespaced enum', () => {
1150
+ program.setFile('source/main.bs', `
1151
+ sub Main()
1152
+ enums.direction.down
1153
+ end sub
1154
+ namespace enums
1155
+ enum Direction
1156
+ up
1157
+ down
1158
+ end enum
1159
+ end namespace
1160
+ `);
1161
+ program.validate();
1162
+ // enums.direction.|down
1163
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 36)), [{
1164
+ label: 'up',
1165
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1166
+ }, {
1167
+ label: 'down',
1168
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1169
+ }]);
1170
+ // enums.direction.do|wn
1171
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 38)), [{
1172
+ label: 'up',
1173
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1174
+ }, {
1175
+ label: 'down',
1176
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1177
+ }]);
1178
+ // enums.direction.down|
1179
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 40)), [{
1180
+ label: 'up',
1181
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1182
+ }, {
1183
+ label: 'down',
1184
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1185
+ }]);
1186
+ });
1187
+ it('excludes enum member completions from namespace enum', () => {
1188
+ program.setFile('source/main.bs', `
1189
+ sub Main()
1190
+ direction.ba
1191
+ end sub
1192
+ namespace enums
1193
+ enum Direction
1194
+ up
1195
+ down
1196
+ end enum
1197
+ end namespace
1198
+ `);
1199
+ program.validate();
1200
+ //should NOT find Direction because it's not directly available at the top level (you need to go through `enums.` to get at it)
1201
+ // dire|ction.down
1202
+ (0, testHelpers_spec_1.expectCompletionsExcludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 24)), [{
1203
+ label: 'Direction',
1204
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1205
+ }]);
1206
+ });
1207
+ it('infers namespace for enum statement completions', () => {
1208
+ program.setFile('source/main.bs', `
1209
+ namespace enums
1210
+ sub Main()
1211
+ direction.down
1212
+ end sub
1213
+ enum Direction
1214
+ up
1215
+ down
1216
+ end enum
1217
+ end namespace
1218
+ enum Logic
1219
+ yes
1220
+ no
1221
+ end enum
1222
+ `);
1223
+ program.validate();
1224
+ // dire|ction.down
1225
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(3, 33)), [{
1226
+ label: 'Direction',
1227
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1228
+ }, {
1229
+ label: 'Logic',
1230
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1231
+ }]);
1232
+ });
1233
+ it('infers namespace for enum member completions', () => {
1234
+ program.setFile('source/main.bs', `
1235
+ namespace enums
1236
+ sub Main()
1237
+ direction.down
1238
+ end sub
1239
+ enum Direction
1240
+ up
1241
+ down
1242
+ end enum
1243
+ end namespace
1244
+ `);
1245
+ program.validate();
1246
+ // direction.do|wn
1247
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(3, 36)), [{
1248
+ label: 'up',
1249
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1250
+ }, {
1251
+ label: 'down',
1252
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1253
+ }]);
1254
+ });
1255
+ it('supports explicit namespace for enum statement completions', () => {
1256
+ program.setFile('source/main.bs', `
1257
+ namespace enums
1258
+ sub Main()
1259
+ enums.direction.down
1260
+ end sub
1261
+ enum Direction
1262
+ up
1263
+ down
1264
+ end enum
1265
+ end namespace
1266
+ `);
1267
+ program.validate();
1268
+ // enums.dire|ction.down
1269
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(3, 38)), [{
1270
+ label: 'Direction',
1271
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1272
+ }]);
1273
+ });
1274
+ it('supports explicit namespace for enum statement completions', () => {
1275
+ program.setFile('source/main.bs', `
1276
+ namespace logger
1277
+ sub log()
1278
+ enums.direction.down
1279
+ end sub
1280
+ end namespace
1281
+ namespace enums
1282
+ enum Direction
1283
+ up
1284
+ down
1285
+ end enum
1286
+ end namespace
1287
+ `);
1288
+ program.validate();
1289
+ // enums.dire|ction.down
1290
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(3, 38)), [{
1291
+ label: 'Direction',
1292
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
1293
+ }]);
1294
+ });
1295
+ it('gives completions for underlying types on enum members', () => {
1296
+ program.setFile('source/main.bs', `
1297
+ enum Direction
1298
+ up = "up"
1299
+ down = "down"
1300
+ end enum
1301
+
1302
+ sub goAway(dir as Direction)
1303
+ print dir.
1304
+ end sub
1305
+
1306
+ `);
1307
+ program.validate();
1308
+ // print dir.|
1309
+ const completions = program.getCompletions('source/main.bs', util_1.default.createPosition(7, 31));
1310
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1311
+ label: 'Trim',
1312
+ kind: vscode_languageserver_1.CompletionItemKind.Method
1313
+ }]);
1314
+ });
1315
+ it('gives completions for underlying types on enum members on future enum declaration', () => {
1316
+ program.setFile('source/main.bs', `
1317
+ sub goAway(dir as Direction)
1318
+ print dir.
1319
+ end sub
1320
+
1321
+ enum Direction
1322
+ up = "up"
1323
+ down = "down"
1324
+ end enum
1325
+ `);
1326
+ program.validate();
1327
+ // print dir.|
1328
+ const completions = program.getCompletions('source/main.bs', util_1.default.createPosition(2, 31));
1329
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1330
+ label: 'Trim',
1331
+ kind: vscode_languageserver_1.CompletionItemKind.Method
1332
+ }]);
1333
+ });
1334
+ it('does not give other members on enum member completion', () => {
1335
+ program.setFile('source/main.bs', `
1336
+ sub goAway(dir as Direction)
1337
+ print dir.
1338
+ end sub
1339
+
1340
+ enum Direction
1341
+ up = "up"
1342
+ down = "down"
1343
+ end enum
1344
+ `);
1345
+ program.validate();
1346
+ // print dir.|
1347
+ const completions = program.getCompletions('source/main.bs', util_1.default.createPosition(2, 31));
1348
+ (0, testHelpers_spec_1.expectCompletionsExcludes)(completions, [{
1349
+ label: 'down',
1350
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember
1351
+ }]);
1352
+ });
1353
+ });
1354
+ describe('built in type members', () => {
1355
+ it('finds built in members', () => {
1356
+ program.setFile('source/main.bs', `
1357
+ sub foo(name as string)
1358
+ print name.
1359
+ end sub
1360
+ `);
1361
+ program.validate();
1362
+ // print name|.
1363
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 32)), [{
1364
+ label: 'Replace',
1365
+ kind: vscode_languageserver_1.CompletionItemKind.Method
1366
+ }]);
1367
+ });
1368
+ });
1369
+ describe('global callables', () => {
1370
+ it('finds built in members', () => {
1371
+ program.setFile('source/main.bs', `
1372
+ sub foo(name as string)
1373
+ print
1374
+ end sub
1375
+ `);
1376
+ program.validate();
1377
+ // print |
1378
+ const completions = program.getCompletions('source/main.bs', util_1.default.createPosition(2, 27));
1379
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1380
+ label: 'LCase',
1381
+ kind: vscode_languageserver_1.CompletionItemKind.Function
1382
+ }]);
1383
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1384
+ label: 'CreateObject',
1385
+ kind: vscode_languageserver_1.CompletionItemKind.Function
1386
+ }]);
1387
+ });
1388
+ });
1389
+ describe('callfunc completions', () => {
1390
+ it('finds callfunc members', () => {
1391
+ program.setFile('components/Widget.xml', (0, testHelpers_spec_1.trim) `
1392
+ <?xml version="1.0" encoding="utf-8" ?>
1393
+ <component name="Widget" extends="Group">
1394
+ <script uri="Widget.brs"/>
1395
+ <interface>
1396
+ <function name="someFunc" />
1397
+ </interface>
1398
+ </component>
1399
+ `);
1400
+ program.setFile('components/Widget.brs', `
1401
+ function someFunc(input as string) as float
1402
+ return input.toFloat()
1403
+ end function
1404
+ `);
1405
+ program.setFile('source/util.bs', `
1406
+ sub callWidgetSomeFunc(widget as roSGNodeWidget)
1407
+ print widget@.
1408
+ end sub
1409
+ `);
1410
+ program.validate();
1411
+ // print widget@.|
1412
+ let completions = program.getCompletions('source/util.bs', util_1.default.createPosition(2, 34));
1413
+ (0, chai_config_spec_1.expect)(completions.length).to.eql(1);
1414
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1415
+ label: 'someFunc',
1416
+ kind: vscode_languageserver_1.CompletionItemKind.Function
1417
+ }]);
1418
+ });
1419
+ it('includes documentation', () => {
1420
+ program.setFile('components/Widget.xml', (0, testHelpers_spec_1.trim) `
1421
+ <?xml version="1.0" encoding="utf-8" ?>
1422
+ <component name="Widget" extends="Group">
1423
+ <script uri="Widget.brs"/>
1424
+ <interface>
1425
+ <function name="someFunc" />
1426
+ </interface>
1427
+ </component>
1428
+ `);
1429
+ program.setFile('components/Widget.brs', `
1430
+ ' This is documentation
1431
+ function someFunc(input as string) as float
1432
+ return input.toFloat()
1433
+ end function
1434
+ `);
1435
+ program.setFile('source/util.bs', `
1436
+ sub callWidgetSomeFunc(widget as roSGNodeWidget)
1437
+ print widget@.
1438
+ end sub
1439
+ `);
1440
+ program.validate();
1441
+ // print widget@.|
1442
+ let completions = program.getCompletions('source/util.bs', util_1.default.createPosition(2, 34));
1443
+ (0, chai_config_spec_1.expect)(completions.length).to.eql(1);
1444
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(completions, [{
1445
+ label: 'someFunc',
1446
+ kind: vscode_languageserver_1.CompletionItemKind.Function,
1447
+ documentation: 'This is documentation'
1448
+ }]);
1449
+ });
1450
+ });
1451
+ });
1452
+ //# sourceMappingURL=CompletionsProcessor.spec.js.map