OLD | NEW |
| (Empty) |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 import 'dart:async'; | |
6 | |
7 import 'package:analyzer/dart/ast/ast.dart'; | |
8 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | |
9 import 'package:analyzer/dart/element/element.dart'; | |
10 import 'package:analyzer/file_system/physical_file_system.dart'; | |
11 import 'package:analyzer/src/dart/sdk/sdk.dart'; | |
12 import 'package:front_end/compiler_options.dart'; | |
13 import 'package:front_end/incremental_resolved_ast_generator.dart'; | |
14 import 'package:front_end/memory_file_system.dart'; | |
15 import 'package:test/test.dart'; | |
16 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
17 | |
18 main() { | |
19 defineReflectiveSuite(() { | |
20 defineReflectiveTests(IncrementalResolvedAstGeneratorTest); | |
21 }); | |
22 } | |
23 | |
24 final _sdkSummary = _readSdkSummary(); | |
25 | |
26 List<int> _readSdkSummary() { | |
27 var resourceProvider = PhysicalResourceProvider.INSTANCE; | |
28 var sdk = new FolderBasedDartSdk(resourceProvider, | |
29 FolderBasedDartSdk.defaultSdkDirectory(resourceProvider)) | |
30 ..useSummary = true; | |
31 var path = resourceProvider.pathContext | |
32 .join(sdk.directory.path, 'lib', '_internal', 'strong.sum'); | |
33 return resourceProvider.getFile(path).readAsBytesSync(); | |
34 } | |
35 | |
36 @reflectiveTest | |
37 class IncrementalResolvedAstGeneratorTest { | |
38 static final sdkSummaryUri = Uri.parse('special:sdk_summary'); | |
39 | |
40 /// Virtual filesystem for testing. | |
41 final fileSystem = new MemoryFileSystem(Uri.parse('file:///')); | |
42 | |
43 /// The object under test. | |
44 IncrementalResolvedAstGenerator incrementalResolvedAstGenerator; | |
45 | |
46 Future<Map<Uri, Map<Uri, CompilationUnit>>> getInitialProgram( | |
47 Uri startingUri) async { | |
48 fileSystem.entityForUri(sdkSummaryUri).writeAsBytesSync(_sdkSummary); | |
49 incrementalResolvedAstGenerator = new IncrementalResolvedAstGenerator( | |
50 startingUri, | |
51 new CompilerOptions() | |
52 ..fileSystem = fileSystem | |
53 ..chaseDependencies = true | |
54 ..sdkSummary = sdkSummaryUri | |
55 ..packagesFileUri = new Uri()); | |
56 return (await incrementalResolvedAstGenerator.computeDelta()).newState; | |
57 } | |
58 | |
59 test_incrementalUpdate_referenceToCore() async { | |
60 writeFiles({'/foo.dart': 'main() { print(1); }'}); | |
61 var fooUri = Uri.parse('file:///foo.dart'); | |
62 var initialProgram = await getInitialProgram(fooUri); | |
63 expect(initialProgram.keys, unorderedEquals([fooUri])); | |
64 | |
65 void _checkMain(CompilationUnit unit, int expectedArgument) { | |
66 var mainStatements = _getFunctionStatements(_getFunction(unit, 'main')); | |
67 expect(mainStatements, hasLength(1)); | |
68 _checkPrintLiteralInt(mainStatements[0], expectedArgument); | |
69 } | |
70 | |
71 _checkMain(initialProgram[fooUri][fooUri], 1); | |
72 writeFiles({'/foo.dart': 'main() { print(2); }'}); | |
73 // Verify that the file isn't actually reread until invalidate is called. | |
74 var deltaProgram1 = await incrementalResolvedAstGenerator.computeDelta(); | |
75 // TODO(paulberry): since there is no delta, computeDelta should return an | |
76 // empty map. | |
77 // expect(deltaProgram1.newState, isEmpty); | |
78 expect(deltaProgram1.newState.keys, unorderedEquals([fooUri])); | |
79 _checkMain(deltaProgram1.newState[fooUri][fooUri], 1); | |
80 incrementalResolvedAstGenerator.invalidateAll(); | |
81 var deltaProgram2 = await incrementalResolvedAstGenerator.computeDelta(); | |
82 expect(deltaProgram2.newState.keys, unorderedEquals([fooUri])); | |
83 _checkMain(deltaProgram2.newState[fooUri][fooUri], 2); | |
84 } | |
85 | |
86 test_invalidateAllBeforeInitialProgram() async { | |
87 incrementalResolvedAstGenerator = new IncrementalResolvedAstGenerator( | |
88 Uri.parse('file:///foo.dart'), | |
89 new CompilerOptions() | |
90 ..fileSystem = fileSystem | |
91 ..chaseDependencies = true | |
92 ..packagesFileUri = new Uri()); | |
93 incrementalResolvedAstGenerator.invalidateAll(); | |
94 } | |
95 | |
96 test_part() async { | |
97 writeFiles({ | |
98 '/foo.dart': 'library foo; part "bar.dart"; main() { print(1); f(); }', | |
99 '/bar.dart': 'part of foo; f() { print(2); }' | |
100 }); | |
101 var fooUri = Uri.parse('file:///foo.dart'); | |
102 var barUri = Uri.parse('file:///bar.dart'); | |
103 var initialProgram = await getInitialProgram(fooUri); | |
104 expect(initialProgram.keys, unorderedEquals([fooUri])); | |
105 expect(initialProgram[fooUri].keys, unorderedEquals([fooUri, barUri])); | |
106 var mainStatements = _getFunctionStatements( | |
107 _getFunction(initialProgram[fooUri][fooUri], 'main')); | |
108 var fDeclaration = _getFunction(initialProgram[fooUri][barUri], 'f'); | |
109 var fStatements = _getFunctionStatements(fDeclaration); | |
110 expect(mainStatements, hasLength(2)); | |
111 _checkPrintLiteralInt(mainStatements[0], 1); | |
112 _checkFunctionCall(mainStatements[1], | |
113 resolutionMap.elementDeclaredByFunctionDeclaration(fDeclaration)); | |
114 expect(fStatements, hasLength(1)); | |
115 _checkPrintLiteralInt(fStatements[0], 2); | |
116 // TODO(paulberry): now test incremental updates | |
117 } | |
118 | |
119 /// Write the given file contents to the virtual filesystem. | |
120 void writeFiles(Map<String, String> contents) { | |
121 contents.forEach((path, text) { | |
122 fileSystem | |
123 .entityForUri(Uri.parse('file://$path')) | |
124 .writeAsStringSync(text); | |
125 }); | |
126 } | |
127 | |
128 void _checkFunctionCall(Statement statement, Element expectedTarget) { | |
129 expect(statement, new isInstanceOf<ExpressionStatement>()); | |
130 var expressionStatement = statement as ExpressionStatement; | |
131 expect( | |
132 expressionStatement.expression, new isInstanceOf<MethodInvocation>()); | |
133 var methodInvocation = expressionStatement.expression as MethodInvocation; | |
134 expect( | |
135 resolutionMap.staticElementForIdentifier(methodInvocation.methodName), | |
136 expectedTarget); | |
137 } | |
138 | |
139 void _checkPrintLiteralInt(Statement statement, int expectedArgument) { | |
140 expect(statement, new isInstanceOf<ExpressionStatement>()); | |
141 var expressionStatement = statement as ExpressionStatement; | |
142 expect( | |
143 expressionStatement.expression, new isInstanceOf<MethodInvocation>()); | |
144 var methodInvocation = expressionStatement.expression as MethodInvocation; | |
145 expect(methodInvocation.methodName.name, 'print'); | |
146 var printElement = | |
147 resolutionMap.staticElementForIdentifier(methodInvocation.methodName); | |
148 expect(printElement, isNotNull); | |
149 expect(printElement.library.source.uri, Uri.parse('dart:core')); | |
150 expect(methodInvocation.argumentList.arguments, hasLength(1)); | |
151 expect(methodInvocation.argumentList.arguments[0], | |
152 new isInstanceOf<IntegerLiteral>()); | |
153 var integerLiteral = | |
154 methodInvocation.argumentList.arguments[0] as IntegerLiteral; | |
155 expect(integerLiteral.value, expectedArgument); | |
156 } | |
157 | |
158 FunctionDeclaration _getFunction(CompilationUnit unit, String name) { | |
159 for (var declaration in unit.declarations) { | |
160 if (declaration is FunctionDeclaration && declaration.name.name == name) { | |
161 return declaration; | |
162 } | |
163 } | |
164 throw fail('No function declaration found with name "$name"'); | |
165 } | |
166 | |
167 NodeList<Statement> _getFunctionStatements(FunctionDeclaration function) { | |
168 var body = function.functionExpression.body; | |
169 expect(body, new isInstanceOf<BlockFunctionBody>()); | |
170 return (body as BlockFunctionBody).block.statements; | |
171 } | |
172 } | |
OLD | NEW |