OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 test.src.serialization.elements_test; | 5 library test.src.serialization.elements_test; |
6 | 6 |
7 import 'dart:convert'; | |
8 | |
9 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/constant/value.dart'; | 8 import 'package:analyzer/dart/constant/value.dart'; |
11 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
12 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
13 import 'package:analyzer/error/error.dart'; | 11 import 'package:analyzer/error/error.dart'; |
14 import 'package:analyzer/src/dart/ast/ast.dart'; | 12 import 'package:analyzer/src/dart/ast/ast.dart'; |
15 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
16 import 'package:analyzer/src/dart/element/handle.dart'; | 14 import 'package:analyzer/src/dart/element/handle.dart'; |
17 import 'package:analyzer/src/dart/element/member.dart'; | 15 import 'package:analyzer/src/dart/element/member.dart'; |
18 import 'package:analyzer/src/dart/element/type.dart'; | 16 import 'package:analyzer/src/dart/element/type.dart'; |
19 import 'package:analyzer/src/error/codes.dart'; | 17 import 'package:analyzer/src/error/codes.dart'; |
20 import 'package:analyzer/src/generated/engine.dart'; | 18 import 'package:analyzer/src/generated/engine.dart'; |
21 import 'package:analyzer/src/generated/resolver.dart' show Namespace; | 19 import 'package:analyzer/src/generated/resolver.dart' show Namespace; |
22 import 'package:analyzer/src/generated/sdk.dart'; | 20 import 'package:analyzer/src/generated/sdk.dart'; |
23 import 'package:analyzer/src/generated/source.dart'; | 21 import 'package:analyzer/src/generated/source.dart'; |
24 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 22 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
25 import 'package:analyzer/src/summary/idl.dart'; | 23 import 'package:analyzer/src/summary/idl.dart'; |
26 import 'package:analyzer/src/summary/resynthesize.dart'; | 24 import 'package:analyzer/src/summary/resynthesize.dart'; |
27 import 'package:analyzer/src/summary/summarize_elements.dart'; | |
28 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 25 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
29 import 'package:unittest/unittest.dart'; | 26 import 'package:unittest/unittest.dart'; |
30 | 27 |
31 import '../../generated/test_support.dart'; | 28 import '../../generated/test_support.dart'; |
32 import '../abstract_single_unit.dart'; | 29 import '../abstract_single_unit.dart'; |
33 import '../context/abstract_context.dart'; | 30 import '../context/abstract_context.dart'; |
34 import 'summary_common.dart' show canonicalize; | |
35 | |
36 main() { | |
37 groupSep = ' | '; | |
38 defineReflectiveTests(ResynthesizeElementTest); | |
39 } | |
40 | 31 |
41 /** | 32 /** |
42 * Abstract base class for resynthesizing and comparing elements. | 33 * Abstract base class for resynthesizing and comparing elements. |
43 */ | 34 */ |
44 abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest { | 35 abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest { |
45 Set<Source> otherLibrarySources = new Set<Source>(); | 36 Set<Source> otherLibrarySources = new Set<Source>(); |
46 | 37 |
47 /** | 38 /** |
48 * Names of variables which have initializers that are not valid constants, | 39 * Names of variables which have initializers that are not valid constants, |
49 * so they are not resynthesized. | 40 * so they are not resynthesized. |
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 } | 1119 } |
1129 | 1120 |
1130 DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK; | 1121 DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK; |
1131 | 1122 |
1132 /** | 1123 /** |
1133 * Determine the analysis options that should be used for this test. | 1124 * Determine the analysis options that should be used for this test. |
1134 */ | 1125 */ |
1135 AnalysisOptionsImpl createOptions() => | 1126 AnalysisOptionsImpl createOptions() => |
1136 new AnalysisOptionsImpl()..enableGenericMethods = true; | 1127 new AnalysisOptionsImpl()..enableGenericMethods = true; |
1137 | 1128 |
1138 /** | |
1139 * Serialize the given [library] into a summary. Then create a | |
1140 * [TestSummaryResynthesizer] which can deserialize it, along with any | |
1141 * references it makes to `dart:core`. | |
1142 * | |
1143 * Errors will lead to a test failure unless [allowErrors] is `true`. | |
1144 */ | |
1145 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, | |
1146 {bool allowErrors: false, bool dumpSummaries: false}) { | |
1147 if (!allowErrors) { | |
1148 assertNoErrors(library.source); | |
1149 } | |
1150 addLibrary('dart:core'); | |
1151 addLibrary('dart:async'); | |
1152 addLibrary('dart:math'); | |
1153 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); | |
1154 } | |
1155 | |
1156 /** | |
1157 * Convert the library element [library] into a summary, and then create a | |
1158 * [TestSummaryResynthesizer] which can deserialize it. | |
1159 * | |
1160 * Caller is responsible for checking the library for errors, and adding any | |
1161 * dependent libraries using [addLibrary]. | |
1162 */ | |
1163 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, | |
1164 {bool dumpSummaries: false}) { | |
1165 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; | |
1166 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { | |
1167 LibrarySerializationResult serialized = serializeLibrary( | |
1168 lib, context.typeProvider, context.analysisOptions.strongMode); | |
1169 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { | |
1170 unlinkedSummaries[serialized.unitUris[i]] = | |
1171 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); | |
1172 } | |
1173 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); | |
1174 } | |
1175 | |
1176 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ | |
1177 library.source.uri.toString(): getLinkedSummaryFor(library) | |
1178 }; | |
1179 for (Source source in otherLibrarySources) { | |
1180 LibraryElement original = context.computeLibraryElement(source); | |
1181 String uri = source.uri.toString(); | |
1182 linkedSummaries[uri] = getLinkedSummaryFor(original); | |
1183 } | |
1184 if (dumpSummaries) { | |
1185 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { | |
1186 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); | |
1187 }); | |
1188 linkedSummaries.forEach((String path, LinkedLibrary lib) { | |
1189 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); | |
1190 }); | |
1191 } | |
1192 return new TestSummaryResynthesizer( | |
1193 null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles); | |
1194 } | |
1195 | |
1196 ElementImpl getActualElement(Element element, String desc) { | 1129 ElementImpl getActualElement(Element element, String desc) { |
1197 if (element == null) { | 1130 if (element == null) { |
1198 return null; | 1131 return null; |
1199 } else if (element is ElementImpl) { | 1132 } else if (element is ElementImpl) { |
1200 return element; | 1133 return element; |
1201 } else if (element is ElementHandle) { | 1134 } else if (element is ElementHandle) { |
1202 Element actualElement = element.actualElement; | 1135 Element actualElement = element.actualElement; |
1203 // A handle should never point to a member, because if it did, then | 1136 // A handle should never point to a member, because if it did, then |
1204 // "is Member" checks on the handle would produce the wrong result. | 1137 // "is Member" checks on the handle would produce the wrong result. |
1205 expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc); | 1138 expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 return false; | 1270 return false; |
1338 } else if (modifier == Modifier.SYNTHETIC) { | 1271 } else if (modifier == Modifier.SYNTHETIC) { |
1339 return element.isSynthetic; | 1272 return element.isSynthetic; |
1340 } | 1273 } |
1341 throw new UnimplementedError( | 1274 throw new UnimplementedError( |
1342 'Modifier $modifier for ${element?.runtimeType}'); | 1275 'Modifier $modifier for ${element?.runtimeType}'); |
1343 } | 1276 } |
1344 } | 1277 } |
1345 | 1278 |
1346 @reflectiveTest | 1279 @reflectiveTest |
1347 class ResynthesizeElementTest extends ResynthesizeTest { | |
1348 @override | |
1349 LibraryElementImpl checkLibrary(String text, | |
1350 {bool allowErrors: false, bool dumpSummaries: false}) { | |
1351 Source source = addTestSource(text); | |
1352 LibraryElementImpl original = context.computeLibraryElement(source); | |
1353 LibraryElementImpl resynthesized = resynthesizeLibraryElement( | |
1354 encodeLibrary(original, | |
1355 allowErrors: allowErrors, dumpSummaries: dumpSummaries), | |
1356 source.uri.toString(), | |
1357 original); | |
1358 checkLibraryElements(original, resynthesized); | |
1359 return resynthesized; | |
1360 } | |
1361 | |
1362 @override | |
1363 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) { | |
1364 LibraryElement libraryElement = | |
1365 context.computeLibraryElement(librarySource); | |
1366 return encodeLibrary(libraryElement); | |
1367 } | |
1368 | |
1369 /** | |
1370 * Serialize the given [library] into a summary. Then create a | |
1371 * [TestSummaryResynthesizer] which can deserialize it, along with any | |
1372 * references it makes to `dart:core`. | |
1373 * | |
1374 * Errors will lead to a test failure unless [allowErrors] is `true`. | |
1375 */ | |
1376 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, | |
1377 {bool allowErrors: false, bool dumpSummaries: false}) { | |
1378 if (!allowErrors) { | |
1379 assertNoErrors(library.source); | |
1380 } | |
1381 addLibrary('dart:core'); | |
1382 addLibrary('dart:async'); | |
1383 addLibrary('dart:math'); | |
1384 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); | |
1385 } | |
1386 | |
1387 /** | |
1388 * Convert the library element [library] into a summary, and then create a | |
1389 * [TestSummaryResynthesizer] which can deserialize it. | |
1390 * | |
1391 * Caller is responsible for checking the library for errors, and adding any | |
1392 * dependent libraries using [addLibrary]. | |
1393 */ | |
1394 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, | |
1395 {bool dumpSummaries: false}) { | |
1396 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; | |
1397 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { | |
1398 LibrarySerializationResult serialized = serializeLibrary( | |
1399 lib, context.typeProvider, context.analysisOptions.strongMode); | |
1400 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { | |
1401 unlinkedSummaries[serialized.unitUris[i]] = | |
1402 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); | |
1403 } | |
1404 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); | |
1405 } | |
1406 | |
1407 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ | |
1408 library.source.uri.toString(): getLinkedSummaryFor(library) | |
1409 }; | |
1410 for (Source source in otherLibrarySources) { | |
1411 LibraryElement original = context.computeLibraryElement(source); | |
1412 String uri = source.uri.toString(); | |
1413 linkedSummaries[uri] = getLinkedSummaryFor(original); | |
1414 } | |
1415 if (dumpSummaries) { | |
1416 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { | |
1417 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); | |
1418 }); | |
1419 linkedSummaries.forEach((String path, LinkedLibrary lib) { | |
1420 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); | |
1421 }); | |
1422 } | |
1423 return new TestSummaryResynthesizer( | |
1424 null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles); | |
1425 } | |
1426 | |
1427 /** | |
1428 * Resynthesize the library element associated with [uri] using | |
1429 * [resynthesizer], and verify that it only had to consult one summary in | |
1430 * order to do so. [original] is consulted merely to verify that no | |
1431 * unnecessary resynthesis work was performed. | |
1432 */ | |
1433 LibraryElementImpl resynthesizeLibraryElement( | |
1434 TestSummaryResynthesizer resynthesizer, | |
1435 String uri, | |
1436 LibraryElement original) { | |
1437 LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri); | |
1438 checkMinimalResynthesisWork(resynthesizer, original); | |
1439 return resynthesized; | |
1440 } | |
1441 | |
1442 test_core() { | |
1443 addLibrary('dart:async'); | |
1444 addLibrary('dart:math'); | |
1445 String uri = 'dart:core'; | |
1446 LibraryElementImpl original = | |
1447 context.computeLibraryElement(context.sourceFactory.forUri(uri)); | |
1448 LibraryElementImpl resynthesized = resynthesizeLibraryElement( | |
1449 encodeLibraryElement(original), uri, original); | |
1450 checkLibraryElements(original, resynthesized); | |
1451 } | |
1452 } | |
1453 | |
1454 @reflectiveTest | |
1455 abstract class ResynthesizeTest extends AbstractResynthesizeTest { | 1280 abstract class ResynthesizeTest extends AbstractResynthesizeTest { |
1456 LibraryElementImpl checkLibrary(String text, | 1281 LibraryElementImpl checkLibrary(String text, |
1457 {bool allowErrors: false, bool dumpSummaries: false}); | 1282 {bool allowErrors: false, bool dumpSummaries: false}); |
1458 | 1283 |
1459 /** | 1284 /** |
1460 * Return a [SummaryResynthesizer] to resynthesize the library with the | 1285 * Return a [SummaryResynthesizer] to resynthesize the library with the |
1461 * given [librarySource]. | 1286 * given [librarySource]. |
1462 */ | 1287 */ |
1463 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource); | 1288 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource); |
1464 | 1289 |
(...skipping 3335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4800 fail('Unexpectedly tried to get unlinked summary for $uri'); | 4625 fail('Unexpectedly tried to get unlinked summary for $uri'); |
4801 } | 4626 } |
4802 return serializedUnit; | 4627 return serializedUnit; |
4803 } | 4628 } |
4804 | 4629 |
4805 @override | 4630 @override |
4806 bool hasLibrarySummary(String uri) { | 4631 bool hasLibrarySummary(String uri) { |
4807 return true; | 4632 return true; |
4808 } | 4633 } |
4809 } | 4634 } |
OLD | NEW |