OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.test.generated.all_the_rest_test; | 5 library analyzer.test.dart.element.builder_test; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | |
11 import 'package:analyzer/error/error.dart'; | |
12 import 'package:analyzer/error/listener.dart'; | |
13 import 'package:analyzer/file_system/file_system.dart'; | |
14 import 'package:analyzer/file_system/memory_file_system.dart'; | |
15 import 'package:analyzer/file_system/physical_file_system.dart'; | |
16 import 'package:analyzer/src/dart/ast/ast.dart'; | 10 import 'package:analyzer/src/dart/ast/ast.dart'; |
17 import 'package:analyzer/src/dart/ast/utilities.dart' hide ConstantEvaluator; | |
18 import 'package:analyzer/src/dart/element/builder.dart'; | 11 import 'package:analyzer/src/dart/element/builder.dart'; |
19 import 'package:analyzer/src/dart/element/element.dart'; | 12 import 'package:analyzer/src/dart/element/element.dart'; |
20 import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader; | |
21 import 'package:analyzer/src/error/codes.dart'; | |
22 import 'package:analyzer/src/generated/engine.dart'; | 13 import 'package:analyzer/src/generated/engine.dart'; |
23 import 'package:analyzer/src/generated/java_engine_io.dart'; | |
24 import 'package:analyzer/src/generated/java_io.dart'; | |
25 import 'package:analyzer/src/generated/resolver.dart'; | 14 import 'package:analyzer/src/generated/resolver.dart'; |
26 import 'package:analyzer/src/generated/sdk.dart'; | |
27 import 'package:analyzer/src/generated/sdk_io.dart'; | |
28 import 'package:analyzer/src/generated/source.dart'; | 15 import 'package:analyzer/src/generated/source.dart'; |
29 import 'package:analyzer/src/generated/source_io.dart'; | |
30 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 16 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
31 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 17 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
32 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; | |
33 import 'package:analyzer/src/generated/testing/token_factory.dart'; | 18 import 'package:analyzer/src/generated/testing/token_factory.dart'; |
34 import 'package:analyzer/src/generated/utilities_dart.dart'; | 19 import 'package:analyzer/src/generated/utilities_dart.dart'; |
35 import 'package:analyzer/src/source/source_resource.dart'; | |
36 import 'package:path/path.dart' as path; | |
37 import 'package:source_span/source_span.dart'; | |
38 import 'package:test/test.dart'; | 20 import 'package:test/test.dart'; |
39 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 21 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
40 | 22 |
41 import 'parser_test.dart'; | 23 import '../../generated/parser_test.dart'; |
42 import 'resolver_test_case.dart'; | 24 import '../../generated/test_support.dart'; |
43 import 'test_support.dart'; | |
44 | 25 |
45 main() { | 26 main() { |
46 defineReflectiveSuite(() { | 27 defineReflectiveSuite(() { |
47 defineReflectiveTests(ContentCacheTest); | |
48 // ignore: deprecated_member_use | |
49 defineReflectiveTests(CustomUriResolverTest); | |
50 defineReflectiveTests(DartUriResolverTest); | |
51 // ignore: deprecated_member_use | |
52 defineReflectiveTests(DirectoryBasedDartSdkTest); | |
53 // ignore: deprecated_member_use | |
54 defineReflectiveTests(DirectoryBasedSourceContainerTest); | |
55 defineReflectiveTests(ElementBuilderTest); | 28 defineReflectiveTests(ElementBuilderTest); |
56 defineReflectiveTests(ElementLocatorTest); | |
57 defineReflectiveTests(EnumMemberBuilderTest); | |
58 defineReflectiveTests(ErrorReporterTest); | |
59 defineReflectiveTests(ErrorSeverityTest); | |
60 defineReflectiveTests(ExitDetectorTest); | |
61 defineReflectiveTests(ExitDetectorTest2); | |
62 defineReflectiveTests(FileBasedSourceTest); | |
63 defineReflectiveTests(ResolveRelativeUriTest); | |
64 // ignore: deprecated_member_use | |
65 defineReflectiveTests(SDKLibrariesReaderTest); | |
66 defineReflectiveTests(UriKindTest); | |
67 }); | 29 }); |
68 } | 30 } |
69 | 31 |
70 /** | |
71 * Create a tiny mock SDK for use in URI resolution tests. | |
72 */ | |
73 DartSdk _createSdk() { | |
74 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); | |
75 String sdkFolderName = | |
76 resourceProvider.pathContext.separator == '/' ? '/sdk' : r'C:\sdk'; | |
77 Folder sdkFolder = resourceProvider.newFolder(sdkFolderName); | |
78 expect(sdkFolder, isNotNull); | |
79 resourceProvider.newFile( | |
80 resourceProvider.pathContext.join(sdkFolderName, 'lib', '_internal', | |
81 'sdk_library_metadata', 'lib', 'libraries.dart'), | |
82 ''' | |
83 const Map<String, LibraryInfo> libraries = const { | |
84 "core": const LibraryInfo("core/core.dart") | |
85 }; | |
86 '''); | |
87 resourceProvider.newFile( | |
88 resourceProvider.pathContext | |
89 .join(sdkFolderName, 'lib', 'core', 'core.dart'), | |
90 ''' | |
91 library dart.core; | |
92 '''); | |
93 return new FolderBasedDartSdk(resourceProvider, sdkFolder); | |
94 } | |
95 | |
96 @reflectiveTest | |
97 class ContentCacheTest { | |
98 void test_setContents() { | |
99 Source source = new TestSource(); | |
100 ContentCache cache = new ContentCache(); | |
101 expect(cache.getContents(source), isNull); | |
102 expect(cache.getModificationStamp(source), isNull); | |
103 String contents = "library lib;"; | |
104 expect(cache.setContents(source, contents), isNull); | |
105 expect(cache.getContents(source), contents); | |
106 expect(cache.getModificationStamp(source), isNotNull); | |
107 expect(cache.setContents(source, contents), contents); | |
108 expect(cache.setContents(source, null), contents); | |
109 expect(cache.getContents(source), isNull); | |
110 expect(cache.getModificationStamp(source), isNull); | |
111 expect(cache.setContents(source, null), isNull); | |
112 } | |
113 } | |
114 | |
115 @deprecated | |
116 @reflectiveTest | |
117 class CustomUriResolverTest { | |
118 void test_creation() { | |
119 expect(new CustomUriResolver({}), isNotNull); | |
120 } | |
121 | |
122 void test_resolve_unknown_uri() { | |
123 UriResolver resolver = new CustomUriResolver({ | |
124 'custom:library': '/path/to/library.dart', | |
125 }); | |
126 Source result = resolver.resolveAbsolute(Uri.parse("custom:non_library")); | |
127 expect(result, isNull); | |
128 } | |
129 | |
130 void test_resolve_uri() { | |
131 String filePath = | |
132 FileUtilities2.createFile("/path/to/library.dart").getAbsolutePath(); | |
133 UriResolver resolver = new CustomUriResolver({ | |
134 'custom:library': filePath, | |
135 }); | |
136 Source result = resolver.resolveAbsolute(Uri.parse("custom:library")); | |
137 expect(result, isNotNull); | |
138 expect(result.fullName, filePath); | |
139 } | |
140 } | |
141 | |
142 @reflectiveTest | |
143 class DartUriResolverTest { | |
144 void test_creation() { | |
145 DartSdk sdk = _createSdk(); | |
146 expect(new DartUriResolver(sdk), isNotNull); | |
147 } | |
148 | |
149 void test_isDartUri_null_scheme() { | |
150 Uri uri = Uri.parse("foo.dart"); | |
151 expect('', uri.scheme); | |
152 expect(DartUriResolver.isDartUri(uri), isFalse); | |
153 } | |
154 | |
155 void test_resolve_dart() { | |
156 DartSdk sdk = _createSdk(); | |
157 UriResolver resolver = new DartUriResolver(sdk); | |
158 Source result = resolver.resolveAbsolute(Uri.parse("dart:core")); | |
159 expect(result, isNotNull); | |
160 } | |
161 | |
162 void test_resolve_dart_nonExistingLibrary() { | |
163 DartSdk sdk = _createSdk(); | |
164 UriResolver resolver = new DartUriResolver(sdk); | |
165 Source result = resolver.resolveAbsolute(Uri.parse("dart:cor")); | |
166 expect(result, isNull); | |
167 } | |
168 | |
169 void test_resolve_nonDart() { | |
170 DartSdk sdk = _createSdk(); | |
171 UriResolver resolver = new DartUriResolver(sdk); | |
172 Source result = | |
173 resolver.resolveAbsolute(Uri.parse("package:some/file.dart")); | |
174 expect(result, isNull); | |
175 } | |
176 } | |
177 | |
178 @deprecated | |
179 @reflectiveTest | |
180 class DirectoryBasedDartSdkTest { | |
181 void fail_getDocFileFor() { | |
182 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
183 JavaFile docFile = sdk.getDocFileFor("html"); | |
184 expect(docFile, isNotNull); | |
185 } | |
186 | |
187 void test_analysisOptions_afterContextCreation() { | |
188 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
189 sdk.context; | |
190 expect(() { | |
191 sdk.analysisOptions = new AnalysisOptionsImpl(); | |
192 }, throwsStateError); | |
193 } | |
194 | |
195 void test_analysisOptions_beforeContextCreation() { | |
196 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
197 sdk.analysisOptions = new AnalysisOptionsImpl(); | |
198 sdk.context; | |
199 // cannot change "analysisOptions" in the context | |
200 expect(() { | |
201 sdk.context.analysisOptions = new AnalysisOptionsImpl(); | |
202 }, throwsStateError); | |
203 } | |
204 | |
205 void test_creation() { | |
206 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
207 expect(sdk, isNotNull); | |
208 } | |
209 | |
210 void test_fromFile_invalid() { | |
211 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
212 expect( | |
213 sdk.fromFileUri(new JavaFile("/not/in/the/sdk.dart").toURI()), isNull); | |
214 } | |
215 | |
216 void test_fromFile_library() { | |
217 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
218 Source source = sdk.fromFileUri(new JavaFile.relative( | |
219 new JavaFile.relative(sdk.libraryDirectory, "core"), "core.dart") | |
220 .toURI()); | |
221 expect(source, isNotNull); | |
222 expect(source.isInSystemLibrary, isTrue); | |
223 expect(source.uri.toString(), "dart:core"); | |
224 } | |
225 | |
226 void test_fromFile_library_firstExact() { | |
227 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
228 JavaFile dirHtml = new JavaFile.relative(sdk.libraryDirectory, "html"); | |
229 JavaFile dirDartium = new JavaFile.relative(dirHtml, "dartium"); | |
230 JavaFile file = new JavaFile.relative(dirDartium, "html_dartium.dart"); | |
231 expect(file.isFile(), isTrue); | |
232 Source source = sdk.fromFileUri(file.toURI()); | |
233 expect(source, isNotNull); | |
234 expect(source.isInSystemLibrary, isTrue); | |
235 expect(source.uri.toString(), "dart:html"); | |
236 } | |
237 | |
238 void test_fromFile_library_html_common_dart2js() { | |
239 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
240 JavaFile dirHtml = new JavaFile.relative(sdk.libraryDirectory, "html"); | |
241 JavaFile dirCommon = new JavaFile.relative(dirHtml, "html_common"); | |
242 JavaFile file = | |
243 new JavaFile.relative(dirCommon, "html_common_dart2js.dart"); | |
244 expect(file.isFile(), isTrue); | |
245 Source source = sdk.fromFileUri(file.toURI()); | |
246 expect(source, isNotNull); | |
247 expect(source.isInSystemLibrary, isTrue); | |
248 expect(source.uri.toString(), "dart:html_common/html_common_dart2js.dart"); | |
249 } | |
250 | |
251 void test_fromFile_part() { | |
252 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
253 Source source = sdk.fromFileUri(new JavaFile.relative( | |
254 new JavaFile.relative(sdk.libraryDirectory, "core"), "num.dart") | |
255 .toURI()); | |
256 expect(source, isNotNull); | |
257 expect(source.isInSystemLibrary, isTrue); | |
258 expect(source.uri.toString(), "dart:core/num.dart"); | |
259 } | |
260 | |
261 void test_getDart2JsExecutable() { | |
262 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
263 JavaFile executable = sdk.dart2JsExecutable; | |
264 expect(executable, isNotNull); | |
265 expect(executable.exists(), isTrue); | |
266 expect(executable.isExecutable(), isTrue); | |
267 } | |
268 | |
269 void test_getDirectory() { | |
270 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
271 JavaFile directory = sdk.directory; | |
272 expect(directory, isNotNull); | |
273 expect(directory.exists(), isTrue); | |
274 } | |
275 | |
276 void test_getDocDirectory() { | |
277 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
278 JavaFile directory = sdk.docDirectory; | |
279 expect(directory, isNotNull); | |
280 } | |
281 | |
282 void test_getLibraryDirectory() { | |
283 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
284 JavaFile directory = sdk.libraryDirectory; | |
285 expect(directory, isNotNull); | |
286 expect(directory.exists(), isTrue); | |
287 } | |
288 | |
289 void test_getPubExecutable() { | |
290 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
291 JavaFile executable = sdk.pubExecutable; | |
292 expect(executable, isNotNull); | |
293 expect(executable.exists(), isTrue); | |
294 expect(executable.isExecutable(), isTrue); | |
295 } | |
296 | |
297 void test_getSdkVersion() { | |
298 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
299 String version = sdk.sdkVersion; | |
300 expect(version, isNotNull); | |
301 expect(version.length > 0, isTrue); | |
302 } | |
303 | |
304 void test_getVmExecutable() { | |
305 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
306 JavaFile executable = sdk.vmExecutable; | |
307 expect(executable, isNotNull); | |
308 expect(executable.exists(), isTrue); | |
309 expect(executable.isExecutable(), isTrue); | |
310 } | |
311 | |
312 void test_useSummary_afterContextCreation() { | |
313 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
314 sdk.context; | |
315 expect(() { | |
316 sdk.useSummary = true; | |
317 }, throwsStateError); | |
318 } | |
319 | |
320 void test_useSummary_beforeContextCreation() { | |
321 DirectoryBasedDartSdk sdk = _createDartSdk(); | |
322 sdk.useSummary = true; | |
323 sdk.context; | |
324 } | |
325 | |
326 DirectoryBasedDartSdk _createDartSdk() { | |
327 JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory; | |
328 expect(sdkDirectory, isNotNull, | |
329 reason: | |
330 "No SDK configured; set the property 'com.google.dart.sdk' on the co
mmand line"); | |
331 return new DirectoryBasedDartSdk(sdkDirectory); | |
332 } | |
333 } | |
334 | |
335 @deprecated | |
336 @reflectiveTest | |
337 class DirectoryBasedSourceContainerTest { | |
338 void test_contains() { | |
339 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); | |
340 File file1 = resourceProvider.getFile('/does/not/exist/some.dart'); | |
341 File file2 = resourceProvider.getFile('/does/not/exist/folder/some2.dart'); | |
342 File file3 = resourceProvider.getFile('/does/not/exist3/some3.dart'); | |
343 Source source1 = new FileSource(file1); | |
344 Source source2 = new FileSource(file2); | |
345 Source source3 = new FileSource(file3); | |
346 DirectoryBasedSourceContainer container = | |
347 new DirectoryBasedSourceContainer.con2('/does/not/exist'); | |
348 expect(container.contains(source1), isTrue); | |
349 expect(container.contains(source2), isTrue); | |
350 expect(container.contains(source3), isFalse); | |
351 } | |
352 } | |
353 | |
354 @reflectiveTest | 32 @reflectiveTest |
355 class ElementBuilderTest extends ParserTestCase { | 33 class ElementBuilderTest extends ParserTestCase { |
356 CompilationUnitElement compilationUnitElement; | 34 CompilationUnitElement compilationUnitElement; |
357 CompilationUnit compilationUnit; | 35 CompilationUnit compilationUnit; |
358 | 36 |
359 /** | 37 /** |
360 * Parse the given [code], pass it through [ElementBuilder], and return the | 38 * Parse the given [code], pass it through [ElementBuilder], and return the |
361 * resulting [ElementHolder]. | 39 * resulting [ElementHolder]. |
362 */ | 40 */ |
363 ElementHolder buildElementsForText(String code) { | 41 ElementHolder buildElementsForText(String code) { |
(...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 AstFactory.methodDeclaration2( | 2218 AstFactory.methodDeclaration2( |
2541 null, | 2219 null, |
2542 null, | 2220 null, |
2543 null, | 2221 null, |
2544 null, | 2222 null, |
2545 AstFactory.identifier3("main"), | 2223 AstFactory.identifier3("main"), |
2546 AstFactory.formalParameterList([formalParameter]), | 2224 AstFactory.formalParameterList([formalParameter]), |
2547 body); | 2225 body); |
2548 } | 2226 } |
2549 } | 2227 } |
2550 | |
2551 @reflectiveTest | |
2552 class ElementLocatorTest extends ResolverTestCase { | |
2553 void fail_locate_Identifier_partOfDirective() { | |
2554 // Can't resolve the library element without the library declaration. | |
2555 // AstNode id = findNodeIn("foo", "part of foo.bar;"); | |
2556 // Element element = ElementLocator.locate(id); | |
2557 // assertInstanceOf(LibraryElement.class, element); | |
2558 fail("Test this case"); | |
2559 } | |
2560 | |
2561 @override | |
2562 void reset() { | |
2563 AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl(); | |
2564 analysisOptions.hint = false; | |
2565 resetWithOptions(analysisOptions); | |
2566 } | |
2567 | |
2568 void test_locate_AssignmentExpression() { | |
2569 AstNode id = _findNodeIn( | |
2570 "+=", | |
2571 r''' | |
2572 int x = 0; | |
2573 void main() { | |
2574 x += 1; | |
2575 }'''); | |
2576 Element element = ElementLocator.locate(id); | |
2577 EngineTestCase.assertInstanceOf( | |
2578 (obj) => obj is MethodElement, MethodElement, element); | |
2579 } | |
2580 | |
2581 void test_locate_BinaryExpression() { | |
2582 AstNode id = _findNodeIn("+", "var x = 3 + 4;"); | |
2583 Element element = ElementLocator.locate(id); | |
2584 EngineTestCase.assertInstanceOf( | |
2585 (obj) => obj is MethodElement, MethodElement, element); | |
2586 } | |
2587 | |
2588 void test_locate_ClassDeclaration() { | |
2589 AstNode id = _findNodeIn("class", "class A { }"); | |
2590 Element element = ElementLocator.locate(id); | |
2591 EngineTestCase.assertInstanceOf( | |
2592 (obj) => obj is ClassElement, ClassElement, element); | |
2593 } | |
2594 | |
2595 void test_locate_CompilationUnit() { | |
2596 CompilationUnit cu = _resolveContents("// only comment"); | |
2597 expect(cu.element, isNotNull); | |
2598 Element element = ElementLocator.locate(cu); | |
2599 expect(element, same(cu.element)); | |
2600 } | |
2601 | |
2602 void test_locate_ConstructorDeclaration() { | |
2603 AstNode id = _findNodeIndexedIn( | |
2604 "bar", | |
2605 0, | |
2606 r''' | |
2607 class A { | |
2608 A.bar() {} | |
2609 }'''); | |
2610 ConstructorDeclaration declaration = | |
2611 id.getAncestor((node) => node is ConstructorDeclaration); | |
2612 Element element = ElementLocator.locate(declaration); | |
2613 EngineTestCase.assertInstanceOf( | |
2614 (obj) => obj is ConstructorElement, ConstructorElement, element); | |
2615 } | |
2616 | |
2617 void test_locate_ExportDirective() { | |
2618 AstNode id = _findNodeIn("export", "export 'dart:core';"); | |
2619 Element element = ElementLocator.locate(id); | |
2620 EngineTestCase.assertInstanceOf( | |
2621 (obj) => obj is ExportElement, ExportElement, element); | |
2622 } | |
2623 | |
2624 void test_locate_FunctionDeclaration() { | |
2625 AstNode id = _findNodeIn("f", "int f() => 3;"); | |
2626 FunctionDeclaration declaration = | |
2627 id.getAncestor((node) => node is FunctionDeclaration); | |
2628 Element element = ElementLocator.locate(declaration); | |
2629 EngineTestCase.assertInstanceOf( | |
2630 (obj) => obj is FunctionElement, FunctionElement, element); | |
2631 } | |
2632 | |
2633 void | |
2634 test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalPar
ameter() { | |
2635 AstNode id = _findNodeIndexedIn( | |
2636 "Class", | |
2637 2, | |
2638 r''' | |
2639 class Class { | |
2640 const Class.name(); | |
2641 } | |
2642 void main(@Class.name() parameter) { | |
2643 }'''); | |
2644 Element element = ElementLocator.locate(id); | |
2645 EngineTestCase.assertInstanceOf( | |
2646 (obj) => obj is ClassElement, ClassElement, element); | |
2647 } | |
2648 | |
2649 void | |
2650 test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalP
arameter() { | |
2651 AstNode id = _findNodeIndexedIn( | |
2652 "Class", | |
2653 2, | |
2654 r''' | |
2655 class Class { | |
2656 const Class(); | |
2657 } | |
2658 void main(@Class() parameter) { | |
2659 }'''); | |
2660 Element element = ElementLocator.locate(id); | |
2661 EngineTestCase.assertInstanceOf( | |
2662 (obj) => obj is ConstructorElement, ConstructorElement, element); | |
2663 } | |
2664 | |
2665 void test_locate_Identifier_className() { | |
2666 AstNode id = _findNodeIn("A", "class A { }"); | |
2667 Element element = ElementLocator.locate(id); | |
2668 EngineTestCase.assertInstanceOf( | |
2669 (obj) => obj is ClassElement, ClassElement, element); | |
2670 } | |
2671 | |
2672 void test_locate_Identifier_constructor_named() { | |
2673 AstNode id = _findNodeIndexedIn( | |
2674 "bar", | |
2675 0, | |
2676 r''' | |
2677 class A { | |
2678 A.bar() {} | |
2679 }'''); | |
2680 Element element = ElementLocator.locate(id); | |
2681 EngineTestCase.assertInstanceOf( | |
2682 (obj) => obj is ConstructorElement, ConstructorElement, element); | |
2683 } | |
2684 | |
2685 void test_locate_Identifier_constructor_unnamed() { | |
2686 AstNode id = _findNodeIndexedIn( | |
2687 "A", | |
2688 1, | |
2689 r''' | |
2690 class A { | |
2691 A() {} | |
2692 }'''); | |
2693 Element element = ElementLocator.locate(id); | |
2694 EngineTestCase.assertInstanceOf( | |
2695 (obj) => obj is ConstructorElement, ConstructorElement, element); | |
2696 } | |
2697 | |
2698 void test_locate_Identifier_fieldName() { | |
2699 AstNode id = _findNodeIn("x", "class A { var x; }"); | |
2700 Element element = ElementLocator.locate(id); | |
2701 EngineTestCase.assertInstanceOf( | |
2702 (obj) => obj is FieldElement, FieldElement, element); | |
2703 } | |
2704 | |
2705 void test_locate_Identifier_libraryDirective() { | |
2706 AstNode id = _findNodeIn("foo", "library foo.bar;"); | |
2707 Element element = ElementLocator.locate(id); | |
2708 EngineTestCase.assertInstanceOf( | |
2709 (obj) => obj is LibraryElement, LibraryElement, element); | |
2710 } | |
2711 | |
2712 void test_locate_Identifier_propertyAccess() { | |
2713 AstNode id = _findNodeIn( | |
2714 "length", | |
2715 r''' | |
2716 void main() { | |
2717 int x = 'foo'.length; | |
2718 }'''); | |
2719 Element element = ElementLocator.locate(id); | |
2720 EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement, | |
2721 PropertyAccessorElement, element); | |
2722 } | |
2723 | |
2724 void test_locate_ImportDirective() { | |
2725 AstNode id = _findNodeIn("import", "import 'dart:core';"); | |
2726 Element element = ElementLocator.locate(id); | |
2727 EngineTestCase.assertInstanceOf( | |
2728 (obj) => obj is ImportElement, ImportElement, element); | |
2729 } | |
2730 | |
2731 void test_locate_IndexExpression() { | |
2732 AstNode id = _findNodeIndexedIn( | |
2733 "\\[", | |
2734 1, | |
2735 r''' | |
2736 void main() { | |
2737 List x = [1, 2]; | |
2738 var y = x[0]; | |
2739 }'''); | |
2740 Element element = ElementLocator.locate(id); | |
2741 EngineTestCase.assertInstanceOf( | |
2742 (obj) => obj is MethodElement, MethodElement, element); | |
2743 } | |
2744 | |
2745 void test_locate_InstanceCreationExpression() { | |
2746 AstNode node = _findNodeIndexedIn( | |
2747 "A(", | |
2748 0, | |
2749 r''' | |
2750 class A {} | |
2751 void main() { | |
2752 new A(); | |
2753 }'''); | |
2754 Element element = ElementLocator.locate(node); | |
2755 EngineTestCase.assertInstanceOf( | |
2756 (obj) => obj is ConstructorElement, ConstructorElement, element); | |
2757 } | |
2758 | |
2759 void test_locate_InstanceCreationExpression_type_prefixedIdentifier() { | |
2760 // prepare: new pref.A() | |
2761 SimpleIdentifier identifier = AstFactory.identifier3("A"); | |
2762 PrefixedIdentifier prefixedIdentifier = | |
2763 AstFactory.identifier4("pref", identifier); | |
2764 InstanceCreationExpression creation = | |
2765 AstFactory.instanceCreationExpression2( | |
2766 Keyword.NEW, AstFactory.typeName3(prefixedIdentifier)); | |
2767 // set ClassElement | |
2768 ClassElement classElement = ElementFactory.classElement2("A"); | |
2769 identifier.staticElement = classElement; | |
2770 // set ConstructorElement | |
2771 ConstructorElement constructorElement = | |
2772 ElementFactory.constructorElement2(classElement, null); | |
2773 creation.constructorName.staticElement = constructorElement; | |
2774 // verify that "A" is resolved to ConstructorElement | |
2775 Element element = ElementLocator.locate(identifier); | |
2776 expect(element, same(classElement)); | |
2777 } | |
2778 | |
2779 void test_locate_InstanceCreationExpression_type_simpleIdentifier() { | |
2780 // prepare: new A() | |
2781 SimpleIdentifier identifier = AstFactory.identifier3("A"); | |
2782 InstanceCreationExpression creation = | |
2783 AstFactory.instanceCreationExpression2( | |
2784 Keyword.NEW, AstFactory.typeName3(identifier)); | |
2785 // set ClassElement | |
2786 ClassElement classElement = ElementFactory.classElement2("A"); | |
2787 identifier.staticElement = classElement; | |
2788 // set ConstructorElement | |
2789 ConstructorElement constructorElement = | |
2790 ElementFactory.constructorElement2(classElement, null); | |
2791 creation.constructorName.staticElement = constructorElement; | |
2792 // verify that "A" is resolved to ConstructorElement | |
2793 Element element = ElementLocator.locate(identifier); | |
2794 expect(element, same(classElement)); | |
2795 } | |
2796 | |
2797 void test_locate_LibraryDirective() { | |
2798 AstNode id = _findNodeIn("library", "library foo;"); | |
2799 Element element = ElementLocator.locate(id); | |
2800 EngineTestCase.assertInstanceOf( | |
2801 (obj) => obj is LibraryElement, LibraryElement, element); | |
2802 } | |
2803 | |
2804 void test_locate_MethodDeclaration() { | |
2805 AstNode id = _findNodeIn( | |
2806 "m", | |
2807 r''' | |
2808 class A { | |
2809 void m() {} | |
2810 }'''); | |
2811 MethodDeclaration declaration = | |
2812 id.getAncestor((node) => node is MethodDeclaration); | |
2813 Element element = ElementLocator.locate(declaration); | |
2814 EngineTestCase.assertInstanceOf( | |
2815 (obj) => obj is MethodElement, MethodElement, element); | |
2816 } | |
2817 | |
2818 void test_locate_MethodInvocation_method() { | |
2819 AstNode id = _findNodeIndexedIn( | |
2820 "bar", | |
2821 1, | |
2822 r''' | |
2823 class A { | |
2824 int bar() => 42; | |
2825 } | |
2826 void main() { | |
2827 var f = new A().bar(); | |
2828 }'''); | |
2829 Element element = ElementLocator.locate(id); | |
2830 EngineTestCase.assertInstanceOf( | |
2831 (obj) => obj is MethodElement, MethodElement, element); | |
2832 } | |
2833 | |
2834 void test_locate_MethodInvocation_topLevel() { | |
2835 String code = r''' | |
2836 foo(x) {} | |
2837 void main() { | |
2838 foo(0); | |
2839 }'''; | |
2840 CompilationUnit cu = _resolveContents(code); | |
2841 int offset = code.indexOf('foo(0)'); | |
2842 AstNode node = new NodeLocator(offset).searchWithin(cu); | |
2843 MethodInvocation invocation = | |
2844 node.getAncestor((n) => n is MethodInvocation); | |
2845 Element element = ElementLocator.locate(invocation); | |
2846 EngineTestCase.assertInstanceOf( | |
2847 (obj) => obj is FunctionElement, FunctionElement, element); | |
2848 } | |
2849 | |
2850 void test_locate_PartOfDirective() { | |
2851 Source librarySource = addNamedSource( | |
2852 '/lib.dart', | |
2853 ''' | |
2854 library my.lib; | |
2855 part 'part.dart'; | |
2856 '''); | |
2857 Source unitSource = addNamedSource( | |
2858 '/part.dart', | |
2859 ''' | |
2860 part of my.lib; | |
2861 '''); | |
2862 CompilationUnit unit = | |
2863 analysisContext.resolveCompilationUnit2(unitSource, librarySource); | |
2864 PartOfDirective partOf = unit.directives.first; | |
2865 Element element = ElementLocator.locate(partOf); | |
2866 EngineTestCase.assertInstanceOf( | |
2867 (obj) => obj is LibraryElement, LibraryElement, element); | |
2868 } | |
2869 | |
2870 void test_locate_PostfixExpression() { | |
2871 AstNode id = _findNodeIn("++", "int addOne(int x) => x++;"); | |
2872 Element element = ElementLocator.locate(id); | |
2873 EngineTestCase.assertInstanceOf( | |
2874 (obj) => obj is MethodElement, MethodElement, element); | |
2875 } | |
2876 | |
2877 void test_locate_PrefixedIdentifier() { | |
2878 AstNode id = _findNodeIn( | |
2879 "int", | |
2880 r''' | |
2881 import 'dart:core' as core; | |
2882 core.int value;'''); | |
2883 PrefixedIdentifier identifier = | |
2884 id.getAncestor((node) => node is PrefixedIdentifier); | |
2885 Element element = ElementLocator.locate(identifier); | |
2886 EngineTestCase.assertInstanceOf( | |
2887 (obj) => obj is ClassElement, ClassElement, element); | |
2888 } | |
2889 | |
2890 void test_locate_PrefixExpression() { | |
2891 AstNode id = _findNodeIn("++", "int addOne(int x) => ++x;"); | |
2892 Element element = ElementLocator.locate(id); | |
2893 EngineTestCase.assertInstanceOf( | |
2894 (obj) => obj is MethodElement, MethodElement, element); | |
2895 } | |
2896 | |
2897 void test_locate_StringLiteral_exportUri() { | |
2898 addNamedSource("/foo.dart", "library foo;"); | |
2899 AstNode id = _findNodeIn("'foo.dart'", "export 'foo.dart';"); | |
2900 Element element = ElementLocator.locate(id); | |
2901 EngineTestCase.assertInstanceOf( | |
2902 (obj) => obj is LibraryElement, LibraryElement, element); | |
2903 } | |
2904 | |
2905 void test_locate_StringLiteral_expression() { | |
2906 AstNode id = _findNodeIn("abc", "var x = 'abc';"); | |
2907 Element element = ElementLocator.locate(id); | |
2908 expect(element, isNull); | |
2909 } | |
2910 | |
2911 void test_locate_StringLiteral_importUri() { | |
2912 addNamedSource("/foo.dart", "library foo; class A {}"); | |
2913 AstNode id = | |
2914 _findNodeIn("'foo.dart'", "import 'foo.dart'; class B extends A {}"); | |
2915 Element element = ElementLocator.locate(id); | |
2916 EngineTestCase.assertInstanceOf( | |
2917 (obj) => obj is LibraryElement, LibraryElement, element); | |
2918 } | |
2919 | |
2920 void test_locate_StringLiteral_partUri() { | |
2921 addNamedSource("/foo.dart", "part of app;"); | |
2922 AstNode id = _findNodeIn("'foo.dart'", "library app; part 'foo.dart';"); | |
2923 Element element = ElementLocator.locate(id); | |
2924 EngineTestCase.assertInstanceOf((obj) => obj is CompilationUnitElement, | |
2925 CompilationUnitElement, element); | |
2926 } | |
2927 | |
2928 void test_locate_VariableDeclaration() { | |
2929 AstNode id = _findNodeIn("x", "var x = 'abc';"); | |
2930 VariableDeclaration declaration = | |
2931 id.getAncestor((node) => node is VariableDeclaration); | |
2932 Element element = ElementLocator.locate(declaration); | |
2933 EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableElement, | |
2934 TopLevelVariableElement, element); | |
2935 } | |
2936 | |
2937 /** | |
2938 * Find the first AST node matching a pattern in the resolved AST for the give
n source. | |
2939 * | |
2940 * [nodePattern] the (unique) pattern used to identify the node of interest. | |
2941 * [code] the code to resolve. | |
2942 * Returns the matched node in the resolved AST for the given source lines. | |
2943 */ | |
2944 AstNode _findNodeIn(String nodePattern, String code) { | |
2945 return _findNodeIndexedIn(nodePattern, 0, code); | |
2946 } | |
2947 | |
2948 /** | |
2949 * Find the AST node matching the given indexed occurrence of a pattern in the
resolved AST for | |
2950 * the given source. | |
2951 * | |
2952 * [nodePattern] the pattern used to identify the node of interest. | |
2953 * [index] the index of the pattern match of interest. | |
2954 * [code] the code to resolve. | |
2955 * Returns the matched node in the resolved AST for the given source lines | |
2956 */ | |
2957 AstNode _findNodeIndexedIn(String nodePattern, int index, String code) { | |
2958 CompilationUnit cu = _resolveContents(code); | |
2959 int start = _getOffsetOfMatch(code, nodePattern, index); | |
2960 int end = start + nodePattern.length; | |
2961 return new NodeLocator(start, end).searchWithin(cu); | |
2962 } | |
2963 | |
2964 int _getOffsetOfMatch(String contents, String pattern, int matchIndex) { | |
2965 if (matchIndex == 0) { | |
2966 return contents.indexOf(pattern); | |
2967 } | |
2968 Iterable<Match> matches = new RegExp(pattern).allMatches(contents); | |
2969 Match match = matches.toList()[matchIndex]; | |
2970 return match.start; | |
2971 } | |
2972 | |
2973 /** | |
2974 * Parse, resolve and verify the given source lines to produce a fully | |
2975 * resolved AST. | |
2976 * | |
2977 * [code] the code to resolve. | |
2978 * | |
2979 * Returns the result of resolving the AST structure representing the content | |
2980 * of the source. | |
2981 * | |
2982 * Throws if source cannot be verified. | |
2983 */ | |
2984 CompilationUnit _resolveContents(String code) { | |
2985 Source source = addSource(code); | |
2986 LibraryElement library = resolve2(source); | |
2987 assertNoErrors(source); | |
2988 verify([source]); | |
2989 return analysisContext.resolveCompilationUnit(source, library); | |
2990 } | |
2991 } | |
2992 | |
2993 @reflectiveTest | |
2994 class EnumMemberBuilderTest extends EngineTestCase { | |
2995 void test_visitEnumDeclaration_multiple() { | |
2996 String firstName = "ONE"; | |
2997 String secondName = "TWO"; | |
2998 String thirdName = "THREE"; | |
2999 EnumDeclaration enumDeclaration = | |
3000 AstFactory.enumDeclaration2("E", [firstName, secondName, thirdName]); | |
3001 | |
3002 ClassElement enumElement = _buildElement(enumDeclaration); | |
3003 List<FieldElement> fields = enumElement.fields; | |
3004 expect(fields, hasLength(5)); | |
3005 | |
3006 FieldElement constant = fields[2]; | |
3007 expect(constant, isNotNull); | |
3008 expect(constant.name, firstName); | |
3009 expect(constant.isStatic, isTrue); | |
3010 expect((constant as FieldElementImpl).evaluationResult, isNotNull); | |
3011 _assertGetter(constant); | |
3012 | |
3013 constant = fields[3]; | |
3014 expect(constant, isNotNull); | |
3015 expect(constant.name, secondName); | |
3016 expect(constant.isStatic, isTrue); | |
3017 expect((constant as FieldElementImpl).evaluationResult, isNotNull); | |
3018 _assertGetter(constant); | |
3019 | |
3020 constant = fields[4]; | |
3021 expect(constant, isNotNull); | |
3022 expect(constant.name, thirdName); | |
3023 expect(constant.isStatic, isTrue); | |
3024 expect((constant as FieldElementImpl).evaluationResult, isNotNull); | |
3025 _assertGetter(constant); | |
3026 } | |
3027 | |
3028 void test_visitEnumDeclaration_single() { | |
3029 String firstName = "ONE"; | |
3030 EnumDeclaration enumDeclaration = | |
3031 AstFactory.enumDeclaration2("E", [firstName]); | |
3032 enumDeclaration.constants[0].documentationComment = AstFactory | |
3033 .documentationComment( | |
3034 [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); | |
3035 | |
3036 ClassElement enumElement = _buildElement(enumDeclaration); | |
3037 List<FieldElement> fields = enumElement.fields; | |
3038 expect(fields, hasLength(3)); | |
3039 | |
3040 FieldElement field = fields[0]; | |
3041 expect(field, isNotNull); | |
3042 expect(field.name, "index"); | |
3043 expect(field.isStatic, isFalse); | |
3044 expect(field.isSynthetic, isTrue); | |
3045 _assertGetter(field); | |
3046 | |
3047 field = fields[1]; | |
3048 expect(field, isNotNull); | |
3049 expect(field.name, "values"); | |
3050 expect(field.isStatic, isTrue); | |
3051 expect(field.isSynthetic, isTrue); | |
3052 expect((field as FieldElementImpl).evaluationResult, isNotNull); | |
3053 _assertGetter(field); | |
3054 | |
3055 FieldElement constant = fields[2]; | |
3056 expect(constant, isNotNull); | |
3057 expect(constant.name, firstName); | |
3058 expect(constant.isStatic, isTrue); | |
3059 expect((constant as FieldElementImpl).evaluationResult, isNotNull); | |
3060 expect(constant.documentationComment, '/// aaa'); | |
3061 _assertGetter(constant); | |
3062 } | |
3063 | |
3064 void _assertGetter(FieldElement field) { | |
3065 PropertyAccessorElement getter = field.getter; | |
3066 expect(getter, isNotNull); | |
3067 expect(getter.variable, same(field)); | |
3068 expect(getter.type, isNotNull); | |
3069 } | |
3070 | |
3071 ClassElement _buildElement(EnumDeclaration enumDeclaration) { | |
3072 ElementHolder holder = new ElementHolder(); | |
3073 ElementBuilder elementBuilder = _makeBuilder(holder); | |
3074 enumDeclaration.accept(elementBuilder); | |
3075 EnumMemberBuilder memberBuilder = | |
3076 new EnumMemberBuilder(new TestTypeProvider()); | |
3077 enumDeclaration.accept(memberBuilder); | |
3078 List<ClassElement> enums = holder.enums; | |
3079 expect(enums, hasLength(1)); | |
3080 return enums[0]; | |
3081 } | |
3082 | |
3083 ElementBuilder _makeBuilder(ElementHolder holder) => | |
3084 new ElementBuilder(holder, new CompilationUnitElementImpl('test.dart')); | |
3085 } | |
3086 | |
3087 @reflectiveTest | |
3088 class ErrorReporterTest extends EngineTestCase { | |
3089 /** | |
3090 * Create a type with the given name in a compilation unit with the given name
. | |
3091 * | |
3092 * @param fileName the name of the compilation unit containing the class | |
3093 * @param typeName the name of the type to be created | |
3094 * @return the type that was created | |
3095 */ | |
3096 InterfaceType createType(String fileName, String typeName) { | |
3097 CompilationUnitElementImpl unit = ElementFactory.compilationUnit(fileName); | |
3098 ClassElementImpl element = ElementFactory.classElement2(typeName); | |
3099 unit.types = <ClassElement>[element]; | |
3100 return element.type; | |
3101 } | |
3102 | |
3103 void test_creation() { | |
3104 GatheringErrorListener listener = new GatheringErrorListener(); | |
3105 TestSource source = new TestSource(); | |
3106 expect(new ErrorReporter(listener, source), isNotNull); | |
3107 } | |
3108 | |
3109 void test_reportErrorForElement_named() { | |
3110 DartType type = createType("/test1.dart", "A"); | |
3111 ClassElement element = type.element; | |
3112 GatheringErrorListener listener = new GatheringErrorListener(); | |
3113 ErrorReporter reporter = new ErrorReporter(listener, element.source); | |
3114 reporter.reportErrorForElement( | |
3115 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, | |
3116 element, | |
3117 ['A']); | |
3118 AnalysisError error = listener.errors[0]; | |
3119 expect(error.offset, element.nameOffset); | |
3120 } | |
3121 | |
3122 void test_reportErrorForElement_unnamed() { | |
3123 ImportElementImpl element = | |
3124 ElementFactory.importFor(ElementFactory.library(null, ''), null); | |
3125 GatheringErrorListener listener = new GatheringErrorListener(); | |
3126 ErrorReporter reporter = new ErrorReporter( | |
3127 listener, | |
3128 new NonExistingSource( | |
3129 '/test.dart', path.toUri('/test.dart'), UriKind.FILE_URI)); | |
3130 reporter.reportErrorForElement( | |
3131 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, | |
3132 element, | |
3133 ['A']); | |
3134 AnalysisError error = listener.errors[0]; | |
3135 expect(error.offset, element.nameOffset); | |
3136 } | |
3137 | |
3138 void test_reportErrorForSpan() { | |
3139 GatheringErrorListener listener = new GatheringErrorListener(); | |
3140 ErrorReporter reporter = new ErrorReporter(listener, new TestSource()); | |
3141 | |
3142 var src = ''' | |
3143 foo: bar | |
3144 zap: baz | |
3145 '''; | |
3146 | |
3147 int offset = src.indexOf('baz'); | |
3148 int length = 'baz'.length; | |
3149 | |
3150 SourceSpan span = new SourceFile(src).span(offset, offset + length); | |
3151 | |
3152 reporter.reportErrorForSpan( | |
3153 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE, | |
3154 span, | |
3155 ['test', 'zip', 'zap']); | |
3156 expect(listener.errors, hasLength(1)); | |
3157 expect(listener.errors.first.offset, offset); | |
3158 expect(listener.errors.first.length, length); | |
3159 } | |
3160 | |
3161 void test_reportTypeErrorForNode_differentNames() { | |
3162 DartType firstType = createType("/test1.dart", "A"); | |
3163 DartType secondType = createType("/test2.dart", "B"); | |
3164 GatheringErrorListener listener = new GatheringErrorListener(); | |
3165 ErrorReporter reporter = | |
3166 new ErrorReporter(listener, firstType.element.source); | |
3167 reporter.reportTypeErrorForNode( | |
3168 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, | |
3169 AstFactory.identifier3("x"), | |
3170 [firstType, secondType]); | |
3171 AnalysisError error = listener.errors[0]; | |
3172 expect(error.message.indexOf("(") < 0, isTrue); | |
3173 } | |
3174 | |
3175 void test_reportTypeErrorForNode_sameName() { | |
3176 String typeName = "A"; | |
3177 DartType firstType = createType("/test1.dart", typeName); | |
3178 DartType secondType = createType("/test2.dart", typeName); | |
3179 GatheringErrorListener listener = new GatheringErrorListener(); | |
3180 ErrorReporter reporter = | |
3181 new ErrorReporter(listener, firstType.element.source); | |
3182 reporter.reportTypeErrorForNode( | |
3183 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, | |
3184 AstFactory.identifier3("x"), | |
3185 [firstType, secondType]); | |
3186 AnalysisError error = listener.errors[0]; | |
3187 expect(error.message.indexOf("(") >= 0, isTrue); | |
3188 } | |
3189 } | |
3190 | |
3191 @reflectiveTest | |
3192 class ErrorSeverityTest extends EngineTestCase { | |
3193 void test_max_error_error() { | |
3194 expect(ErrorSeverity.ERROR.max(ErrorSeverity.ERROR), | |
3195 same(ErrorSeverity.ERROR)); | |
3196 } | |
3197 | |
3198 void test_max_error_none() { | |
3199 expect( | |
3200 ErrorSeverity.ERROR.max(ErrorSeverity.NONE), same(ErrorSeverity.ERROR)); | |
3201 } | |
3202 | |
3203 void test_max_error_warning() { | |
3204 expect(ErrorSeverity.ERROR.max(ErrorSeverity.WARNING), | |
3205 same(ErrorSeverity.ERROR)); | |
3206 } | |
3207 | |
3208 void test_max_none_error() { | |
3209 expect( | |
3210 ErrorSeverity.NONE.max(ErrorSeverity.ERROR), same(ErrorSeverity.ERROR)); | |
3211 } | |
3212 | |
3213 void test_max_none_none() { | |
3214 expect( | |
3215 ErrorSeverity.NONE.max(ErrorSeverity.NONE), same(ErrorSeverity.NONE)); | |
3216 } | |
3217 | |
3218 void test_max_none_warning() { | |
3219 expect(ErrorSeverity.NONE.max(ErrorSeverity.WARNING), | |
3220 same(ErrorSeverity.WARNING)); | |
3221 } | |
3222 | |
3223 void test_max_warning_error() { | |
3224 expect(ErrorSeverity.WARNING.max(ErrorSeverity.ERROR), | |
3225 same(ErrorSeverity.ERROR)); | |
3226 } | |
3227 | |
3228 void test_max_warning_none() { | |
3229 expect(ErrorSeverity.WARNING.max(ErrorSeverity.NONE), | |
3230 same(ErrorSeverity.WARNING)); | |
3231 } | |
3232 | |
3233 void test_max_warning_warning() { | |
3234 expect(ErrorSeverity.WARNING.max(ErrorSeverity.WARNING), | |
3235 same(ErrorSeverity.WARNING)); | |
3236 } | |
3237 } | |
3238 | |
3239 /** | |
3240 * Tests for the [ExitDetector] that do not require that the AST be resolved. | |
3241 * | |
3242 * See [ExitDetectorTest2] for tests that require the AST to be resolved. | |
3243 */ | |
3244 @reflectiveTest | |
3245 class ExitDetectorTest extends ParserTestCase { | |
3246 void test_asExpression() { | |
3247 _assertFalse("a as Object;"); | |
3248 } | |
3249 | |
3250 void test_asExpression_throw() { | |
3251 _assertTrue("throw '' as Object;"); | |
3252 } | |
3253 | |
3254 void test_assertStatement() { | |
3255 _assertFalse("assert(a);"); | |
3256 } | |
3257 | |
3258 void test_assertStatement_throw() { | |
3259 _assertFalse("assert((throw 0));"); | |
3260 } | |
3261 | |
3262 void test_assignmentExpression() { | |
3263 _assertFalse("v = 1;"); | |
3264 } | |
3265 | |
3266 void test_assignmentExpression_compound_lazy() { | |
3267 enableLazyAssignmentOperators = true; | |
3268 _assertFalse("v ||= false;"); | |
3269 } | |
3270 | |
3271 void test_assignmentExpression_lhs_throw() { | |
3272 _assertTrue("a[throw ''] = 0;"); | |
3273 } | |
3274 | |
3275 void test_assignmentExpression_rhs_throw() { | |
3276 _assertTrue("v = throw '';"); | |
3277 } | |
3278 | |
3279 void test_await_false() { | |
3280 _assertFalse("await x;"); | |
3281 } | |
3282 | |
3283 void test_await_throw_true() { | |
3284 _assertTrue("bool b = await (throw '' || true);"); | |
3285 } | |
3286 | |
3287 void test_binaryExpression_and() { | |
3288 _assertFalse("a && b;"); | |
3289 } | |
3290 | |
3291 void test_binaryExpression_and_lhs() { | |
3292 _assertTrue("throw '' && b;"); | |
3293 } | |
3294 | |
3295 void test_binaryExpression_and_rhs() { | |
3296 _assertFalse("a && (throw '');"); | |
3297 } | |
3298 | |
3299 void test_binaryExpression_and_rhs2() { | |
3300 _assertFalse("false && (throw '');"); | |
3301 } | |
3302 | |
3303 void test_binaryExpression_and_rhs3() { | |
3304 _assertTrue("true && (throw '');"); | |
3305 } | |
3306 | |
3307 void test_binaryExpression_ifNull() { | |
3308 _assertFalse("a ?? b;"); | |
3309 } | |
3310 | |
3311 void test_binaryExpression_ifNull_lhs() { | |
3312 _assertTrue("throw '' ?? b;"); | |
3313 } | |
3314 | |
3315 void test_binaryExpression_ifNull_rhs() { | |
3316 _assertFalse("a ?? (throw '');"); | |
3317 } | |
3318 | |
3319 void test_binaryExpression_ifNull_rhs2() { | |
3320 _assertFalse("null ?? (throw '');"); | |
3321 } | |
3322 | |
3323 void test_binaryExpression_or() { | |
3324 _assertFalse("a || b;"); | |
3325 } | |
3326 | |
3327 void test_binaryExpression_or_lhs() { | |
3328 _assertTrue("throw '' || b;"); | |
3329 } | |
3330 | |
3331 void test_binaryExpression_or_rhs() { | |
3332 _assertFalse("a || (throw '');"); | |
3333 } | |
3334 | |
3335 void test_binaryExpression_or_rhs2() { | |
3336 _assertFalse("true || (throw '');"); | |
3337 } | |
3338 | |
3339 void test_binaryExpression_or_rhs3() { | |
3340 _assertTrue("false || (throw '');"); | |
3341 } | |
3342 | |
3343 void test_block_empty() { | |
3344 _assertFalse("{}"); | |
3345 } | |
3346 | |
3347 void test_block_noReturn() { | |
3348 _assertFalse("{ int i = 0; }"); | |
3349 } | |
3350 | |
3351 void test_block_return() { | |
3352 _assertTrue("{ return 0; }"); | |
3353 } | |
3354 | |
3355 void test_block_returnNotLast() { | |
3356 _assertTrue("{ return 0; throw 'a'; }"); | |
3357 } | |
3358 | |
3359 void test_block_throwNotLast() { | |
3360 _assertTrue("{ throw 0; x = null; }"); | |
3361 } | |
3362 | |
3363 void test_cascadeExpression_argument() { | |
3364 _assertTrue("a..b(throw '');"); | |
3365 } | |
3366 | |
3367 void test_cascadeExpression_index() { | |
3368 _assertTrue("a..[throw ''];"); | |
3369 } | |
3370 | |
3371 void test_cascadeExpression_target() { | |
3372 _assertTrue("throw ''..b();"); | |
3373 } | |
3374 | |
3375 void test_conditional_ifElse_bothThrows() { | |
3376 _assertTrue("c ? throw '' : throw '';"); | |
3377 } | |
3378 | |
3379 void test_conditional_ifElse_elseThrows() { | |
3380 _assertFalse("c ? i : throw '';"); | |
3381 } | |
3382 | |
3383 void test_conditional_ifElse_noThrow() { | |
3384 _assertFalse("c ? i : j;"); | |
3385 } | |
3386 | |
3387 void test_conditional_ifElse_thenThrow() { | |
3388 _assertFalse("c ? throw '' : j;"); | |
3389 } | |
3390 | |
3391 void test_conditionalAccess() { | |
3392 _assertFalse("a?.b;"); | |
3393 } | |
3394 | |
3395 void test_conditionalAccess_lhs() { | |
3396 _assertTrue("(throw '')?.b;"); | |
3397 } | |
3398 | |
3399 void test_conditionalAccessAssign() { | |
3400 _assertFalse("a?.b = c;"); | |
3401 } | |
3402 | |
3403 void test_conditionalAccessAssign_lhs() { | |
3404 _assertTrue("(throw '')?.b = c;"); | |
3405 } | |
3406 | |
3407 void test_conditionalAccessAssign_rhs() { | |
3408 _assertFalse("a?.b = throw '';"); | |
3409 } | |
3410 | |
3411 void test_conditionalAccessAssign_rhs2() { | |
3412 _assertFalse("null?.b = throw '';"); | |
3413 } | |
3414 | |
3415 void test_conditionalAccessIfNullAssign() { | |
3416 _assertFalse("a?.b ??= c;"); | |
3417 } | |
3418 | |
3419 void test_conditionalAccessIfNullAssign_lhs() { | |
3420 _assertTrue("(throw '')?.b ??= c;"); | |
3421 } | |
3422 | |
3423 void test_conditionalAccessIfNullAssign_rhs() { | |
3424 _assertFalse("a?.b ??= throw '';"); | |
3425 } | |
3426 | |
3427 void test_conditionalAccessIfNullAssign_rhs2() { | |
3428 _assertFalse("null?.b ??= throw '';"); | |
3429 } | |
3430 | |
3431 void test_conditionalCall() { | |
3432 _assertFalse("a?.b(c);"); | |
3433 } | |
3434 | |
3435 void test_conditionalCall_lhs() { | |
3436 _assertTrue("(throw '')?.b(c);"); | |
3437 } | |
3438 | |
3439 void test_conditionalCall_rhs() { | |
3440 _assertFalse("a?.b(throw '');"); | |
3441 } | |
3442 | |
3443 void test_conditionalCall_rhs2() { | |
3444 _assertFalse("null?.b(throw '');"); | |
3445 } | |
3446 | |
3447 void test_creation() { | |
3448 expect(new ExitDetector(), isNotNull); | |
3449 } | |
3450 | |
3451 void test_doStatement_break_and_throw() { | |
3452 _assertFalse("{ do { if (1==1) break; throw 'T'; } while (0==1); }"); | |
3453 } | |
3454 | |
3455 void test_doStatement_continue_and_throw() { | |
3456 _assertFalse("{ do { if (1==1) continue; throw 'T'; } while (0==1); }"); | |
3457 } | |
3458 | |
3459 void test_doStatement_continueDoInSwitch_and_throw() { | |
3460 _assertFalse(''' | |
3461 { | |
3462 D: do { | |
3463 switch (1) { | |
3464 L: case 0: continue D; | |
3465 M: case 1: break; | |
3466 } | |
3467 throw 'T'; | |
3468 } while (0 == 1); | |
3469 }'''); | |
3470 } | |
3471 | |
3472 void test_doStatement_continueInSwitch_and_throw() { | |
3473 _assertFalse(''' | |
3474 { | |
3475 do { | |
3476 switch (1) { | |
3477 L: case 0: continue; | |
3478 M: case 1: break; | |
3479 } | |
3480 throw 'T'; | |
3481 } while (0 == 1); | |
3482 }'''); | |
3483 } | |
3484 | |
3485 void test_doStatement_return() { | |
3486 _assertTrue("{ do { return null; } while (1 == 2); }"); | |
3487 } | |
3488 | |
3489 void test_doStatement_throwCondition() { | |
3490 _assertTrue("{ do {} while (throw ''); }"); | |
3491 } | |
3492 | |
3493 void test_doStatement_true_break() { | |
3494 _assertFalse("{ do { break; } while (true); }"); | |
3495 } | |
3496 | |
3497 void test_doStatement_true_continue() { | |
3498 _assertTrue("{ do { continue; } while (true); }"); | |
3499 } | |
3500 | |
3501 void test_doStatement_true_continueWithLabel() { | |
3502 _assertTrue("{ x: do { continue x; } while (true); }"); | |
3503 } | |
3504 | |
3505 void test_doStatement_true_if_return() { | |
3506 _assertTrue("{ do { if (true) {return null;} } while (true); }"); | |
3507 } | |
3508 | |
3509 void test_doStatement_true_noBreak() { | |
3510 _assertTrue("{ do {} while (true); }"); | |
3511 } | |
3512 | |
3513 void test_doStatement_true_return() { | |
3514 _assertTrue("{ do { return null; } while (true); }"); | |
3515 } | |
3516 | |
3517 void test_emptyStatement() { | |
3518 _assertFalse(";"); | |
3519 } | |
3520 | |
3521 void test_forEachStatement() { | |
3522 _assertFalse("for (element in list) {}"); | |
3523 } | |
3524 | |
3525 void test_forEachStatement_throw() { | |
3526 _assertTrue("for (element in throw '') {}"); | |
3527 } | |
3528 | |
3529 void test_forStatement_condition() { | |
3530 _assertTrue("for (; throw 0;) {}"); | |
3531 } | |
3532 | |
3533 void test_forStatement_implicitTrue() { | |
3534 _assertTrue("for (;;) {}"); | |
3535 } | |
3536 | |
3537 void test_forStatement_implicitTrue_break() { | |
3538 _assertFalse("for (;;) { break; }"); | |
3539 } | |
3540 | |
3541 void test_forStatement_implicitTrue_if_break() { | |
3542 _assertFalse("{ for (;;) { if (1==2) { var a = 1; } else { break; } } }"); | |
3543 } | |
3544 | |
3545 void test_forStatement_initialization() { | |
3546 _assertTrue("for (i = throw 0;;) {}"); | |
3547 } | |
3548 | |
3549 void test_forStatement_true() { | |
3550 _assertTrue("for (; true; ) {}"); | |
3551 } | |
3552 | |
3553 void test_forStatement_true_break() { | |
3554 _assertFalse("{ for (; true; ) { break; } }"); | |
3555 } | |
3556 | |
3557 void test_forStatement_true_continue() { | |
3558 _assertTrue("{ for (; true; ) { continue; } }"); | |
3559 } | |
3560 | |
3561 void test_forStatement_true_if_return() { | |
3562 _assertTrue("{ for (; true; ) { if (true) {return null;} } }"); | |
3563 } | |
3564 | |
3565 void test_forStatement_true_noBreak() { | |
3566 _assertTrue("{ for (; true; ) {} }"); | |
3567 } | |
3568 | |
3569 void test_forStatement_updaters() { | |
3570 _assertTrue("for (;; i++, throw 0) {}"); | |
3571 } | |
3572 | |
3573 void test_forStatement_variableDeclaration() { | |
3574 _assertTrue("for (int i = throw 0;;) {}"); | |
3575 } | |
3576 | |
3577 void test_functionExpression() { | |
3578 _assertFalse("(){};"); | |
3579 } | |
3580 | |
3581 void test_functionExpression_bodyThrows() { | |
3582 _assertFalse("(int i) => throw '';"); | |
3583 } | |
3584 | |
3585 void test_functionExpressionInvocation() { | |
3586 _assertFalse("f(g);"); | |
3587 } | |
3588 | |
3589 void test_functionExpressionInvocation_argumentThrows() { | |
3590 _assertTrue("f(throw '');"); | |
3591 } | |
3592 | |
3593 void test_functionExpressionInvocation_targetThrows() { | |
3594 _assertTrue("throw ''(g);"); | |
3595 } | |
3596 | |
3597 void test_identifier_prefixedIdentifier() { | |
3598 _assertFalse("a.b;"); | |
3599 } | |
3600 | |
3601 void test_identifier_simpleIdentifier() { | |
3602 _assertFalse("a;"); | |
3603 } | |
3604 | |
3605 void test_if_false_else_return() { | |
3606 _assertTrue("if (false) {} else { return 0; }"); | |
3607 } | |
3608 | |
3609 void test_if_false_noReturn() { | |
3610 _assertFalse("if (false) {}"); | |
3611 } | |
3612 | |
3613 void test_if_false_return() { | |
3614 _assertFalse("if (false) { return 0; }"); | |
3615 } | |
3616 | |
3617 void test_if_noReturn() { | |
3618 _assertFalse("if (c) i++;"); | |
3619 } | |
3620 | |
3621 void test_if_return() { | |
3622 _assertFalse("if (c) return 0;"); | |
3623 } | |
3624 | |
3625 void test_if_true_noReturn() { | |
3626 _assertFalse("if (true) {}"); | |
3627 } | |
3628 | |
3629 void test_if_true_return() { | |
3630 _assertTrue("if (true) { return 0; }"); | |
3631 } | |
3632 | |
3633 void test_ifElse_bothReturn() { | |
3634 _assertTrue("if (c) return 0; else return 1;"); | |
3635 } | |
3636 | |
3637 void test_ifElse_elseReturn() { | |
3638 _assertFalse("if (c) i++; else return 1;"); | |
3639 } | |
3640 | |
3641 void test_ifElse_noReturn() { | |
3642 _assertFalse("if (c) i++; else j++;"); | |
3643 } | |
3644 | |
3645 void test_ifElse_thenReturn() { | |
3646 _assertFalse("if (c) return 0; else j++;"); | |
3647 } | |
3648 | |
3649 void test_ifNullAssign() { | |
3650 _assertFalse("a ??= b;"); | |
3651 } | |
3652 | |
3653 void test_ifNullAssign_rhs() { | |
3654 _assertFalse("a ??= throw '';"); | |
3655 } | |
3656 | |
3657 void test_indexExpression() { | |
3658 _assertFalse("a[b];"); | |
3659 } | |
3660 | |
3661 void test_indexExpression_index() { | |
3662 _assertTrue("a[throw ''];"); | |
3663 } | |
3664 | |
3665 void test_indexExpression_target() { | |
3666 _assertTrue("throw ''[b];"); | |
3667 } | |
3668 | |
3669 void test_instanceCreationExpression() { | |
3670 _assertFalse("new A(b);"); | |
3671 } | |
3672 | |
3673 void test_instanceCreationExpression_argumentThrows() { | |
3674 _assertTrue("new A(throw '');"); | |
3675 } | |
3676 | |
3677 void test_isExpression() { | |
3678 _assertFalse("A is B;"); | |
3679 } | |
3680 | |
3681 void test_isExpression_throws() { | |
3682 _assertTrue("throw '' is B;"); | |
3683 } | |
3684 | |
3685 void test_labeledStatement() { | |
3686 _assertFalse("label: a;"); | |
3687 } | |
3688 | |
3689 void test_labeledStatement_throws() { | |
3690 _assertTrue("label: throw '';"); | |
3691 } | |
3692 | |
3693 void test_literal_boolean() { | |
3694 _assertFalse("true;"); | |
3695 } | |
3696 | |
3697 void test_literal_double() { | |
3698 _assertFalse("1.1;"); | |
3699 } | |
3700 | |
3701 void test_literal_integer() { | |
3702 _assertFalse("1;"); | |
3703 } | |
3704 | |
3705 void test_literal_null() { | |
3706 _assertFalse("null;"); | |
3707 } | |
3708 | |
3709 void test_literal_String() { | |
3710 _assertFalse("'str';"); | |
3711 } | |
3712 | |
3713 void test_methodInvocation() { | |
3714 _assertFalse("a.b(c);"); | |
3715 } | |
3716 | |
3717 void test_methodInvocation_argument() { | |
3718 _assertTrue("a.b(throw '');"); | |
3719 } | |
3720 | |
3721 void test_methodInvocation_target() { | |
3722 _assertTrue("throw ''.b(c);"); | |
3723 } | |
3724 | |
3725 void test_parenthesizedExpression() { | |
3726 _assertFalse("(a);"); | |
3727 } | |
3728 | |
3729 void test_parenthesizedExpression_throw() { | |
3730 _assertTrue("(throw '');"); | |
3731 } | |
3732 | |
3733 void test_propertyAccess() { | |
3734 _assertFalse("new Object().a;"); | |
3735 } | |
3736 | |
3737 void test_propertyAccess_throws() { | |
3738 _assertTrue("(throw '').a;"); | |
3739 } | |
3740 | |
3741 void test_rethrow() { | |
3742 _assertTrue("rethrow;"); | |
3743 } | |
3744 | |
3745 void test_return() { | |
3746 _assertTrue("return 0;"); | |
3747 } | |
3748 | |
3749 void test_superExpression() { | |
3750 _assertFalse("super.a;"); | |
3751 } | |
3752 | |
3753 void test_switch_allReturn() { | |
3754 _assertTrue("switch (i) { case 0: return 0; default: return 1; }"); | |
3755 } | |
3756 | |
3757 void test_switch_defaultWithNoStatements() { | |
3758 _assertFalse("switch (i) { case 0: return 0; default: }"); | |
3759 } | |
3760 | |
3761 void test_switch_fallThroughToNotReturn() { | |
3762 _assertFalse("switch (i) { case 0: case 1: break; default: return 1; }"); | |
3763 } | |
3764 | |
3765 void test_switch_fallThroughToReturn() { | |
3766 _assertTrue("switch (i) { case 0: case 1: return 0; default: return 1; }"); | |
3767 } | |
3768 | |
3769 // The ExitDetector could conceivably follow switch continue labels and | |
3770 // determine that `case 0` exits, `case 1` continues to an exiting case, and | |
3771 // `default` exits, so the switch exits. | |
3772 @failingTest | |
3773 void test_switch_includesContinue() { | |
3774 _assertTrue(''' | |
3775 switch (i) { | |
3776 zero: case 0: return 0; | |
3777 case 1: continue zero; | |
3778 default: return 1; | |
3779 }'''); | |
3780 } | |
3781 | |
3782 void test_switch_noDefault() { | |
3783 _assertFalse("switch (i) { case 0: return 0; }"); | |
3784 } | |
3785 | |
3786 void test_switch_nonReturn() { | |
3787 _assertFalse("switch (i) { case 0: i++; default: return 1; }"); | |
3788 } | |
3789 | |
3790 void test_thisExpression() { | |
3791 _assertFalse("this.a;"); | |
3792 } | |
3793 | |
3794 void test_throwExpression() { | |
3795 _assertTrue("throw new Object();"); | |
3796 } | |
3797 | |
3798 void test_tryStatement_noReturn() { | |
3799 _assertFalse("try {} catch (e, s) {} finally {}"); | |
3800 } | |
3801 | |
3802 void test_tryStatement_noReturn_noFinally() { | |
3803 _assertFalse("try {} catch (e, s) {}"); | |
3804 } | |
3805 | |
3806 void test_tryStatement_return_catch() { | |
3807 _assertFalse("try {} catch (e, s) { return 1; } finally {}"); | |
3808 } | |
3809 | |
3810 void test_tryStatement_return_catch_noFinally() { | |
3811 _assertFalse("try {} catch (e, s) { return 1; }"); | |
3812 } | |
3813 | |
3814 void test_tryStatement_return_finally() { | |
3815 _assertTrue("try {} catch (e, s) {} finally { return 1; }"); | |
3816 } | |
3817 | |
3818 void test_tryStatement_return_try_noCatch() { | |
3819 _assertTrue("try { return 1; } finally {}"); | |
3820 } | |
3821 | |
3822 void test_tryStatement_return_try_oneCatchDoesNotExit() { | |
3823 _assertFalse("try { return 1; } catch (e, s) {} finally {}"); | |
3824 } | |
3825 | |
3826 void test_tryStatement_return_try_oneCatchDoesNotExit_noFinally() { | |
3827 _assertFalse("try { return 1; } catch (e, s) {}"); | |
3828 } | |
3829 | |
3830 void test_tryStatement_return_try_oneCatchExits() { | |
3831 _assertTrue("try { return 1; } catch (e, s) { return 1; } finally {}"); | |
3832 } | |
3833 | |
3834 void test_tryStatement_return_try_oneCatchExits_noFinally() { | |
3835 _assertTrue("try { return 1; } catch (e, s) { return 1; }"); | |
3836 } | |
3837 | |
3838 void test_tryStatement_return_try_twoCatchesDoExit() { | |
3839 _assertTrue(''' | |
3840 try { return 1; } | |
3841 on int catch (e, s) { return 1; } | |
3842 on String catch (e, s) { return 1; } | |
3843 finally {}'''); | |
3844 } | |
3845 | |
3846 void test_tryStatement_return_try_twoCatchesDoExit_noFinally() { | |
3847 _assertTrue(''' | |
3848 try { return 1; } | |
3849 on int catch (e, s) { return 1; } | |
3850 on String catch (e, s) { return 1; }'''); | |
3851 } | |
3852 | |
3853 void test_tryStatement_return_try_twoCatchesDoNotExit() { | |
3854 _assertFalse(''' | |
3855 try { return 1; } | |
3856 on int catch (e, s) {} | |
3857 on String catch (e, s) {} | |
3858 finally {}'''); | |
3859 } | |
3860 | |
3861 void test_tryStatement_return_try_twoCatchesDoNotExit_noFinally() { | |
3862 _assertFalse(''' | |
3863 try { return 1; } | |
3864 on int catch (e, s) {} | |
3865 on String catch (e, s) {}'''); | |
3866 } | |
3867 | |
3868 void test_tryStatement_return_try_twoCatchesMixed() { | |
3869 _assertFalse(''' | |
3870 try { return 1; } | |
3871 on int catch (e, s) {} | |
3872 on String catch (e, s) { return 1; } | |
3873 finally {}'''); | |
3874 } | |
3875 | |
3876 void test_tryStatement_return_try_twoCatchesMixed_noFinally() { | |
3877 _assertFalse(''' | |
3878 try { return 1; } | |
3879 on int catch (e, s) {} | |
3880 on String catch (e, s) { return 1; }'''); | |
3881 } | |
3882 | |
3883 void test_variableDeclarationStatement_noInitializer() { | |
3884 _assertFalse("int i;"); | |
3885 } | |
3886 | |
3887 void test_variableDeclarationStatement_noThrow() { | |
3888 _assertFalse("int i = 0;"); | |
3889 } | |
3890 | |
3891 void test_variableDeclarationStatement_throw() { | |
3892 _assertTrue("int i = throw new Object();"); | |
3893 } | |
3894 | |
3895 void test_whileStatement_false_nonReturn() { | |
3896 _assertFalse("{ while (false) {} }"); | |
3897 } | |
3898 | |
3899 void test_whileStatement_throwCondition() { | |
3900 _assertTrue("{ while (throw '') {} }"); | |
3901 } | |
3902 | |
3903 void test_whileStatement_true_break() { | |
3904 _assertFalse("{ while (true) { break; } }"); | |
3905 } | |
3906 | |
3907 void test_whileStatement_true_break_and_throw() { | |
3908 _assertFalse("{ while (true) { if (1==1) break; throw 'T'; } }"); | |
3909 } | |
3910 | |
3911 void test_whileStatement_true_continue() { | |
3912 _assertTrue("{ while (true) { continue; } }"); | |
3913 } | |
3914 | |
3915 void test_whileStatement_true_continueWithLabel() { | |
3916 _assertTrue("{ x: while (true) { continue x; } }"); | |
3917 } | |
3918 | |
3919 void test_whileStatement_true_doStatement_scopeRequired() { | |
3920 _assertTrue("{ while (true) { x: do { continue x; } while (true); } }"); | |
3921 } | |
3922 | |
3923 void test_whileStatement_true_if_return() { | |
3924 _assertTrue("{ while (true) { if (true) {return null;} } }"); | |
3925 } | |
3926 | |
3927 void test_whileStatement_true_noBreak() { | |
3928 _assertTrue("{ while (true) {} }"); | |
3929 } | |
3930 | |
3931 void test_whileStatement_true_return() { | |
3932 _assertTrue("{ while (true) { return null; } }"); | |
3933 } | |
3934 | |
3935 void test_whileStatement_true_throw() { | |
3936 _assertTrue("{ while (true) { throw ''; } }"); | |
3937 } | |
3938 | |
3939 void _assertFalse(String source) { | |
3940 _assertHasReturn(false, source); | |
3941 } | |
3942 | |
3943 void _assertHasReturn(bool expectedResult, String source) { | |
3944 Statement statement = ParserTestCase.parseStatement( | |
3945 source, [], enableLazyAssignmentOperators); | |
3946 expect(ExitDetector.exits(statement), expectedResult); | |
3947 } | |
3948 | |
3949 void _assertTrue(String source) { | |
3950 _assertHasReturn(true, source); | |
3951 } | |
3952 } | |
3953 | |
3954 /** | |
3955 * Tests for the [ExitDetector] that require that the AST be resolved. | |
3956 * | |
3957 * See [ExitDetectorTest] for tests that do not require the AST to be resolved. | |
3958 */ | |
3959 @reflectiveTest | |
3960 class ExitDetectorTest2 extends ResolverTestCase { | |
3961 void test_forStatement_implicitTrue_breakWithLabel() { | |
3962 Source source = addSource(r''' | |
3963 void f() { | |
3964 x: for (;;) { | |
3965 if (1 < 2) { | |
3966 break x; | |
3967 } | |
3968 return; | |
3969 } | |
3970 } | |
3971 '''); | |
3972 _assertNthStatementDoesNotExit(source, 0); | |
3973 } | |
3974 | |
3975 void test_switch_withEnum_false_noDefault() { | |
3976 Source source = addSource(r''' | |
3977 enum E { A, B } | |
3978 String f(E e) { | |
3979 var x; | |
3980 switch (e) { | |
3981 case A: | |
3982 x = 'A'; | |
3983 case B: | |
3984 x = 'B'; | |
3985 } | |
3986 return x; | |
3987 } | |
3988 '''); | |
3989 _assertNthStatementDoesNotExit(source, 1); | |
3990 } | |
3991 | |
3992 void test_switch_withEnum_false_withDefault() { | |
3993 Source source = addSource(r''' | |
3994 enum E { A, B } | |
3995 String f(E e) { | |
3996 var x; | |
3997 switch (e) { | |
3998 case A: | |
3999 x = 'A'; | |
4000 default: | |
4001 x = '?'; | |
4002 } | |
4003 return x; | |
4004 } | |
4005 '''); | |
4006 _assertNthStatementDoesNotExit(source, 1); | |
4007 } | |
4008 | |
4009 void test_switch_withEnum_true_noDefault() { | |
4010 Source source = addSource(r''' | |
4011 enum E { A, B } | |
4012 String f(E e) { | |
4013 switch (e) { | |
4014 case A: | |
4015 return 'A'; | |
4016 case B: | |
4017 return 'B'; | |
4018 } | |
4019 } | |
4020 '''); | |
4021 _assertNthStatementDoesNotExit(source, 0); | |
4022 } | |
4023 | |
4024 void test_switch_withEnum_true_withExitingDefault() { | |
4025 Source source = addSource(r''' | |
4026 enum E { A, B } | |
4027 String f(E e) { | |
4028 switch (e) { | |
4029 case A: | |
4030 return 'A'; | |
4031 default: | |
4032 return '?'; | |
4033 } | |
4034 } | |
4035 '''); | |
4036 _assertNthStatementExits(source, 0); | |
4037 } | |
4038 | |
4039 void test_switch_withEnum_true_withNonExitingDefault() { | |
4040 Source source = addSource(r''' | |
4041 enum E { A, B } | |
4042 String f(E e) { | |
4043 var x; | |
4044 switch (e) { | |
4045 case A: | |
4046 return 'A'; | |
4047 default: | |
4048 x = '?'; | |
4049 } | |
4050 } | |
4051 '''); | |
4052 _assertNthStatementDoesNotExit(source, 1); | |
4053 } | |
4054 | |
4055 void test_whileStatement_breakWithLabel() { | |
4056 Source source = addSource(r''' | |
4057 void f() { | |
4058 x: while (true) { | |
4059 if (1 < 2) { | |
4060 break x; | |
4061 } | |
4062 return; | |
4063 } | |
4064 } | |
4065 '''); | |
4066 _assertNthStatementDoesNotExit(source, 0); | |
4067 } | |
4068 | |
4069 void test_whileStatement_breakWithLabel_afterExiting() { | |
4070 Source source = addSource(r''' | |
4071 void f() { | |
4072 x: while (true) { | |
4073 return; | |
4074 if (1 < 2) { | |
4075 break x; | |
4076 } | |
4077 } | |
4078 } | |
4079 '''); | |
4080 _assertNthStatementExits(source, 0); | |
4081 } | |
4082 | |
4083 void test_whileStatement_switchWithBreakWithLabel() { | |
4084 Source source = addSource(r''' | |
4085 void f() { | |
4086 x: while (true) { | |
4087 switch (true) { | |
4088 case false: break; | |
4089 case true: break x; | |
4090 } | |
4091 } | |
4092 } | |
4093 '''); | |
4094 _assertNthStatementDoesNotExit(source, 0); | |
4095 } | |
4096 | |
4097 void test_yieldStatement_plain() { | |
4098 Source source = addSource(r''' | |
4099 void f() sync* { | |
4100 yield 1; | |
4101 } | |
4102 '''); | |
4103 _assertNthStatementDoesNotExit(source, 0); | |
4104 } | |
4105 | |
4106 void test_yieldStatement_star_plain() { | |
4107 Source source = addSource(r''' | |
4108 void f() sync* { | |
4109 yield* 1; | |
4110 } | |
4111 '''); | |
4112 _assertNthStatementDoesNotExit(source, 0); | |
4113 } | |
4114 | |
4115 void test_yieldStatement_star_throw() { | |
4116 Source source = addSource(r''' | |
4117 void f() sync* { | |
4118 yield* throw ''; | |
4119 } | |
4120 '''); | |
4121 _assertNthStatementExits(source, 0); | |
4122 } | |
4123 | |
4124 void test_yieldStatement_throw() { | |
4125 Source source = addSource(r''' | |
4126 void f() sync* { | |
4127 yield throw ''; | |
4128 } | |
4129 '''); | |
4130 _assertNthStatementExits(source, 0); | |
4131 } | |
4132 | |
4133 void _assertHasReturn(bool expectedResult, Source source, int n) { | |
4134 LibraryElement element = resolve2(source); | |
4135 CompilationUnit unit = resolveCompilationUnit(source, element); | |
4136 FunctionDeclaration function = unit.declarations.last; | |
4137 BlockFunctionBody body = function.functionExpression.body; | |
4138 Statement statement = body.block.statements[n]; | |
4139 expect(ExitDetector.exits(statement), expectedResult); | |
4140 } | |
4141 | |
4142 // Assert that the [n]th statement in the last function declaration of | |
4143 // [source] exits. | |
4144 void _assertNthStatementDoesNotExit(Source source, int n) { | |
4145 _assertHasReturn(false, source, n); | |
4146 } | |
4147 | |
4148 // Assert that the [n]th statement in the last function declaration of | |
4149 // [source] does not exit. | |
4150 void _assertNthStatementExits(Source source, int n) { | |
4151 _assertHasReturn(true, source, n); | |
4152 } | |
4153 } | |
4154 | |
4155 @reflectiveTest | |
4156 class FileBasedSourceTest { | |
4157 void test_equals_false_differentFiles() { | |
4158 JavaFile file1 = FileUtilities2.createFile("/does/not/exist1.dart"); | |
4159 JavaFile file2 = FileUtilities2.createFile("/does/not/exist2.dart"); | |
4160 FileBasedSource source1 = new FileBasedSource(file1); | |
4161 FileBasedSource source2 = new FileBasedSource(file2); | |
4162 expect(source1 == source2, isFalse); | |
4163 } | |
4164 | |
4165 void test_equals_false_null() { | |
4166 JavaFile file = FileUtilities2.createFile("/does/not/exist1.dart"); | |
4167 FileBasedSource source1 = new FileBasedSource(file); | |
4168 expect(source1 == null, isFalse); | |
4169 } | |
4170 | |
4171 void test_equals_true() { | |
4172 JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart"); | |
4173 JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart"); | |
4174 FileBasedSource source1 = new FileBasedSource(file1); | |
4175 FileBasedSource source2 = new FileBasedSource(file2); | |
4176 expect(source1 == source2, isTrue); | |
4177 } | |
4178 | |
4179 void test_fileReadMode() { | |
4180 expect(FileBasedSource.fileReadMode('a'), 'a'); | |
4181 expect(FileBasedSource.fileReadMode('a\n'), 'a\n'); | |
4182 expect(FileBasedSource.fileReadMode('ab'), 'ab'); | |
4183 expect(FileBasedSource.fileReadMode('abc'), 'abc'); | |
4184 expect(FileBasedSource.fileReadMode('a\nb'), 'a\nb'); | |
4185 expect(FileBasedSource.fileReadMode('a\rb'), 'a\rb'); | |
4186 expect(FileBasedSource.fileReadMode('a\r\nb'), 'a\r\nb'); | |
4187 } | |
4188 | |
4189 void test_fileReadMode_changed() { | |
4190 FileBasedSource.fileReadMode = (String s) => s + 'xyz'; | |
4191 expect(FileBasedSource.fileReadMode('a'), 'axyz'); | |
4192 expect(FileBasedSource.fileReadMode('a\n'), 'a\nxyz'); | |
4193 expect(FileBasedSource.fileReadMode('ab'), 'abxyz'); | |
4194 expect(FileBasedSource.fileReadMode('abc'), 'abcxyz'); | |
4195 FileBasedSource.fileReadMode = (String s) => s; | |
4196 } | |
4197 | |
4198 void test_fileReadMode_normalize_eol_always() { | |
4199 FileBasedSource.fileReadMode = | |
4200 PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS; | |
4201 expect(FileBasedSource.fileReadMode('a'), 'a'); | |
4202 | |
4203 // '\n' -> '\n' as first, last and only character | |
4204 expect(FileBasedSource.fileReadMode('\n'), '\n'); | |
4205 expect(FileBasedSource.fileReadMode('a\n'), 'a\n'); | |
4206 expect(FileBasedSource.fileReadMode('\na'), '\na'); | |
4207 | |
4208 // '\r\n' -> '\n' as first, last and only character | |
4209 expect(FileBasedSource.fileReadMode('\r\n'), '\n'); | |
4210 expect(FileBasedSource.fileReadMode('a\r\n'), 'a\n'); | |
4211 expect(FileBasedSource.fileReadMode('\r\na'), '\na'); | |
4212 | |
4213 // '\r' -> '\n' as first, last and only character | |
4214 expect(FileBasedSource.fileReadMode('\r'), '\n'); | |
4215 expect(FileBasedSource.fileReadMode('a\r'), 'a\n'); | |
4216 expect(FileBasedSource.fileReadMode('\ra'), '\na'); | |
4217 | |
4218 FileBasedSource.fileReadMode = (String s) => s; | |
4219 } | |
4220 | |
4221 void test_getEncoding() { | |
4222 SourceFactory factory = new SourceFactory( | |
4223 [new ResourceUriResolver(PhysicalResourceProvider.INSTANCE)]); | |
4224 String fullPath = "/does/not/exist.dart"; | |
4225 JavaFile file = FileUtilities2.createFile(fullPath); | |
4226 FileBasedSource source = new FileBasedSource(file); | |
4227 expect(factory.fromEncoding(source.encoding), source); | |
4228 } | |
4229 | |
4230 void test_getFullName() { | |
4231 String fullPath = "/does/not/exist.dart"; | |
4232 JavaFile file = FileUtilities2.createFile(fullPath); | |
4233 FileBasedSource source = new FileBasedSource(file); | |
4234 expect(source.fullName, file.getAbsolutePath()); | |
4235 } | |
4236 | |
4237 void test_getShortName() { | |
4238 JavaFile file = FileUtilities2.createFile("/does/not/exist.dart"); | |
4239 FileBasedSource source = new FileBasedSource(file); | |
4240 expect(source.shortName, "exist.dart"); | |
4241 } | |
4242 | |
4243 void test_hashCode() { | |
4244 JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart"); | |
4245 JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart"); | |
4246 FileBasedSource source1 = new FileBasedSource(file1); | |
4247 FileBasedSource source2 = new FileBasedSource(file2); | |
4248 expect(source2.hashCode, source1.hashCode); | |
4249 } | |
4250 | |
4251 void test_isInSystemLibrary_contagious() { | |
4252 DartSdk sdk = _createSdk(); | |
4253 UriResolver resolver = new DartUriResolver(sdk); | |
4254 SourceFactory factory = new SourceFactory([resolver]); | |
4255 // resolve dart:core | |
4256 Source result = resolver.resolveAbsolute(Uri.parse("dart:core")); | |
4257 expect(result, isNotNull); | |
4258 expect(result.isInSystemLibrary, isTrue); | |
4259 // system libraries reference only other system libraries | |
4260 Source partSource = factory.resolveUri(result, "num.dart"); | |
4261 expect(partSource, isNotNull); | |
4262 expect(partSource.isInSystemLibrary, isTrue); | |
4263 } | |
4264 | |
4265 void test_isInSystemLibrary_false() { | |
4266 JavaFile file = FileUtilities2.createFile("/does/not/exist.dart"); | |
4267 FileBasedSource source = new FileBasedSource(file); | |
4268 expect(source, isNotNull); | |
4269 expect(source.fullName, file.getAbsolutePath()); | |
4270 expect(source.isInSystemLibrary, isFalse); | |
4271 } | |
4272 | |
4273 void test_issue14500() { | |
4274 // see https://code.google.com/p/dart/issues/detail?id=14500 | |
4275 FileBasedSource source = new FileBasedSource( | |
4276 FileUtilities2.createFile("/some/packages/foo:bar.dart")); | |
4277 expect(source, isNotNull); | |
4278 expect(source.exists(), isFalse); | |
4279 } | |
4280 | |
4281 void test_resolveRelative_file_fileName() { | |
4282 if (OSUtilities.isWindows()) { | |
4283 // On Windows, the URI that is produced includes a drive letter, | |
4284 // which I believe is not consistent across all machines that might run | |
4285 // this test. | |
4286 return; | |
4287 } | |
4288 JavaFile file = FileUtilities2.createFile("/a/b/test.dart"); | |
4289 FileBasedSource source = new FileBasedSource(file); | |
4290 expect(source, isNotNull); | |
4291 Uri relative = resolveRelativeUri(source.uri, Uri.parse("lib.dart")); | |
4292 expect(relative, isNotNull); | |
4293 expect(relative.toString(), "file:///a/b/lib.dart"); | |
4294 } | |
4295 | |
4296 void test_resolveRelative_file_filePath() { | |
4297 if (OSUtilities.isWindows()) { | |
4298 // On Windows, the URI that is produced includes a drive letter, | |
4299 // which I believe is not consistent across all machines that might run | |
4300 // this test. | |
4301 return; | |
4302 } | |
4303 JavaFile file = FileUtilities2.createFile("/a/b/test.dart"); | |
4304 FileBasedSource source = new FileBasedSource(file); | |
4305 expect(source, isNotNull); | |
4306 Uri relative = resolveRelativeUri(source.uri, Uri.parse("c/lib.dart")); | |
4307 expect(relative, isNotNull); | |
4308 expect(relative.toString(), "file:///a/b/c/lib.dart"); | |
4309 } | |
4310 | |
4311 void test_resolveRelative_file_filePathWithParent() { | |
4312 if (OSUtilities.isWindows()) { | |
4313 // On Windows, the URI that is produced includes a drive letter, which I | |
4314 // believe is not consistent across all machines that might run this test. | |
4315 return; | |
4316 } | |
4317 JavaFile file = FileUtilities2.createFile("/a/b/test.dart"); | |
4318 FileBasedSource source = new FileBasedSource(file); | |
4319 expect(source, isNotNull); | |
4320 Uri relative = resolveRelativeUri(source.uri, Uri.parse("../c/lib.dart")); | |
4321 expect(relative, isNotNull); | |
4322 expect(relative.toString(), "file:///a/c/lib.dart"); | |
4323 } | |
4324 | |
4325 void test_system() { | |
4326 JavaFile file = FileUtilities2.createFile("/does/not/exist.dart"); | |
4327 FileBasedSource source = new FileBasedSource(file, Uri.parse("dart:core")); | |
4328 expect(source, isNotNull); | |
4329 expect(source.fullName, file.getAbsolutePath()); | |
4330 expect(source.isInSystemLibrary, isTrue); | |
4331 } | |
4332 } | |
4333 | |
4334 @reflectiveTest | |
4335 class ResolveRelativeUriTest { | |
4336 void test_resolveRelative_dart_dartUri() { | |
4337 _assertResolve('dart:foo', 'dart:bar', 'dart:bar'); | |
4338 } | |
4339 | |
4340 void test_resolveRelative_dart_fileName() { | |
4341 _assertResolve('dart:test', 'lib.dart', 'dart:test/lib.dart'); | |
4342 } | |
4343 | |
4344 void test_resolveRelative_dart_filePath() { | |
4345 _assertResolve('dart:test', 'c/lib.dart', 'dart:test/c/lib.dart'); | |
4346 } | |
4347 | |
4348 void test_resolveRelative_dart_filePathWithParent() { | |
4349 _assertResolve( | |
4350 'dart:test/b/test.dart', '../c/lib.dart', 'dart:test/c/lib.dart'); | |
4351 } | |
4352 | |
4353 void test_resolveRelative_package_dartUri() { | |
4354 _assertResolve('package:foo/bar.dart', 'dart:test', 'dart:test'); | |
4355 } | |
4356 | |
4357 void test_resolveRelative_package_emptyPath() { | |
4358 _assertResolve('package:foo/bar.dart', '', 'package:foo/bar.dart'); | |
4359 } | |
4360 | |
4361 void test_resolveRelative_package_fileName() { | |
4362 _assertResolve('package:b/test.dart', 'lib.dart', 'package:b/lib.dart'); | |
4363 } | |
4364 | |
4365 void test_resolveRelative_package_fileNameWithoutPackageName() { | |
4366 _assertResolve('package:test.dart', 'lib.dart', 'package:lib.dart'); | |
4367 } | |
4368 | |
4369 void test_resolveRelative_package_filePath() { | |
4370 _assertResolve('package:b/test.dart', 'c/lib.dart', 'package:b/c/lib.dart'); | |
4371 } | |
4372 | |
4373 void test_resolveRelative_package_filePathWithParent() { | |
4374 _assertResolve( | |
4375 'package:a/b/test.dart', '../c/lib.dart', 'package:a/c/lib.dart'); | |
4376 } | |
4377 | |
4378 void _assertResolve(String baseStr, String containedStr, String expectedStr) { | |
4379 Uri base = Uri.parse(baseStr); | |
4380 Uri contained = Uri.parse(containedStr); | |
4381 Uri result = resolveRelativeUri(base, contained); | |
4382 expect(result, isNotNull); | |
4383 expect(result.toString(), expectedStr); | |
4384 } | |
4385 } | |
4386 | |
4387 @deprecated | |
4388 @reflectiveTest | |
4389 class SDKLibrariesReaderTest extends EngineTestCase { | |
4390 void test_readFrom_dart2js() { | |
4391 LibraryMap libraryMap = new SdkLibrariesReader(true).readFromFile( | |
4392 FileUtilities2.createFile("/libs.dart"), | |
4393 r''' | |
4394 final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> { | |
4395 'first' : const LibraryInfo( | |
4396 'first/first.dart', | |
4397 categories: 'Client', | |
4398 documented: true, | |
4399 platforms: VM_PLATFORM, | |
4400 dart2jsPath: 'first/first_dart2js.dart'), | |
4401 };'''); | |
4402 expect(libraryMap, isNotNull); | |
4403 expect(libraryMap.size(), 1); | |
4404 SdkLibrary first = libraryMap.getLibrary("dart:first"); | |
4405 expect(first, isNotNull); | |
4406 expect(first.category, "Client"); | |
4407 expect(first.path, "first/first_dart2js.dart"); | |
4408 expect(first.shortName, "dart:first"); | |
4409 expect(first.isDart2JsLibrary, false); | |
4410 expect(first.isDocumented, true); | |
4411 expect(first.isImplementation, false); | |
4412 expect(first.isVmLibrary, true); | |
4413 } | |
4414 | |
4415 void test_readFrom_empty() { | |
4416 LibraryMap libraryMap = new SdkLibrariesReader(false) | |
4417 .readFromFile(FileUtilities2.createFile("/libs.dart"), ""); | |
4418 expect(libraryMap, isNotNull); | |
4419 expect(libraryMap.size(), 0); | |
4420 } | |
4421 | |
4422 void test_readFrom_normal() { | |
4423 LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile( | |
4424 FileUtilities2.createFile("/libs.dart"), | |
4425 r''' | |
4426 final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> { | |
4427 'first' : const LibraryInfo( | |
4428 'first/first.dart', | |
4429 categories: 'Client', | |
4430 documented: true, | |
4431 platforms: VM_PLATFORM), | |
4432 | |
4433 'second' : const LibraryInfo( | |
4434 'second/second.dart', | |
4435 categories: 'Server', | |
4436 documented: false, | |
4437 implementation: true, | |
4438 platforms: 0), | |
4439 };'''); | |
4440 expect(libraryMap, isNotNull); | |
4441 expect(libraryMap.size(), 2); | |
4442 SdkLibrary first = libraryMap.getLibrary("dart:first"); | |
4443 expect(first, isNotNull); | |
4444 expect(first.category, "Client"); | |
4445 expect(first.path, "first/first.dart"); | |
4446 expect(first.shortName, "dart:first"); | |
4447 expect(first.isDart2JsLibrary, false); | |
4448 expect(first.isDocumented, true); | |
4449 expect(first.isImplementation, false); | |
4450 expect(first.isVmLibrary, true); | |
4451 SdkLibrary second = libraryMap.getLibrary("dart:second"); | |
4452 expect(second, isNotNull); | |
4453 expect(second.category, "Server"); | |
4454 expect(second.path, "second/second.dart"); | |
4455 expect(second.shortName, "dart:second"); | |
4456 expect(second.isDart2JsLibrary, false); | |
4457 expect(second.isDocumented, false); | |
4458 expect(second.isImplementation, true); | |
4459 expect(second.isVmLibrary, false); | |
4460 } | |
4461 } | |
4462 | |
4463 @reflectiveTest | |
4464 class UriKindTest { | |
4465 void test_fromEncoding() { | |
4466 expect(UriKind.fromEncoding(0x64), same(UriKind.DART_URI)); | |
4467 expect(UriKind.fromEncoding(0x66), same(UriKind.FILE_URI)); | |
4468 expect(UriKind.fromEncoding(0x70), same(UriKind.PACKAGE_URI)); | |
4469 expect(UriKind.fromEncoding(0x58), same(null)); | |
4470 } | |
4471 | |
4472 void test_getEncoding() { | |
4473 expect(UriKind.DART_URI.encoding, 0x64); | |
4474 expect(UriKind.FILE_URI.encoding, 0x66); | |
4475 expect(UriKind.PACKAGE_URI.encoding, 0x70); | |
4476 } | |
4477 } | |
OLD | NEW |