| 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'; | 7 import 'dart:convert'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/constant/value.dart'; | 10 import 'package:analyzer/dart/constant/value.dart'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 import 'package:analyzer/src/summary/summarize_elements.dart'; | 26 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 27 import 'package:unittest/unittest.dart'; | 27 import 'package:unittest/unittest.dart'; |
| 28 | 28 |
| 29 import '../../generated/test_support.dart'; | 29 import '../../generated/test_support.dart'; |
| 30 import '../../reflective_tests.dart'; | 30 import '../../reflective_tests.dart'; |
| 31 import '../abstract_single_unit.dart'; | 31 import '../abstract_single_unit.dart'; |
| 32 import 'summary_common.dart' show canonicalize; | 32 import 'summary_common.dart' show canonicalize; |
| 33 | 33 |
| 34 main() { | 34 main() { |
| 35 groupSep = ' | '; | 35 groupSep = ' | '; |
| 36 runReflectiveTests(ResynthTest); | 36 runReflectiveTests(ResynthesizeElementTest); |
| 37 } | 37 } |
| 38 | 38 |
| 39 @reflectiveTest | 39 @reflectiveTest |
| 40 class ResynthTest extends AbstractSingleUnitTest { | 40 class ResynthesizeElementTest extends ResynthesizeTest { |
| 41 @override |
| 42 void checkLibrary(String text, |
| 43 {bool allowErrors: false, bool dumpSummaries: false}) { |
| 44 Source source = addTestSource(text); |
| 45 LibraryElementImpl original = context.computeLibraryElement(source); |
| 46 LibraryElementImpl resynthesized = resynthesizeLibraryElement( |
| 47 encodeLibrary(original, |
| 48 allowErrors: allowErrors, dumpSummaries: dumpSummaries), |
| 49 source.uri.toString(), |
| 50 original); |
| 51 checkLibraryElements(original, resynthesized); |
| 52 } |
| 53 |
| 54 @override |
| 55 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) { |
| 56 LibraryElement libraryElement = |
| 57 context.computeLibraryElement(librarySource); |
| 58 return encodeLibrary(libraryElement); |
| 59 } |
| 60 |
| 61 /** |
| 62 * Serialize the given [library] into a summary. Then create a |
| 63 * [TestSummaryResynthesizer] which can deserialize it, along with any |
| 64 * references it makes to `dart:core`. |
| 65 * |
| 66 * Errors will lead to a test failure unless [allowErrors] is `true`. |
| 67 */ |
| 68 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, |
| 69 {bool allowErrors: false, bool dumpSummaries: false}) { |
| 70 if (!allowErrors) { |
| 71 assertNoErrors(library.source); |
| 72 } |
| 73 addLibrary('dart:core'); |
| 74 addLibrary('dart:async'); |
| 75 addLibrary('dart:math'); |
| 76 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); |
| 77 } |
| 78 |
| 79 /** |
| 80 * Convert the library element [library] into a summary, and then create a |
| 81 * [TestSummaryResynthesizer] which can deserialize it. |
| 82 * |
| 83 * Caller is responsible for checking the library for errors, and adding any |
| 84 * dependent libraries using [addLibrary]. |
| 85 */ |
| 86 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, |
| 87 {bool dumpSummaries: false}) { |
| 88 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; |
| 89 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { |
| 90 LibrarySerializationResult serialized = serializeLibrary( |
| 91 lib, context.typeProvider, context.analysisOptions.strongMode); |
| 92 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { |
| 93 unlinkedSummaries[serialized.unitUris[i]] = |
| 94 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); |
| 95 } |
| 96 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); |
| 97 } |
| 98 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ |
| 99 library.source.uri.toString(): getLinkedSummaryFor(library) |
| 100 }; |
| 101 for (Source source in otherLibrarySources) { |
| 102 LibraryElement original = context.computeLibraryElement(source); |
| 103 String uri = source.uri.toString(); |
| 104 linkedSummaries[uri] = getLinkedSummaryFor(original); |
| 105 } |
| 106 if (dumpSummaries) { |
| 107 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { |
| 108 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); |
| 109 }); |
| 110 linkedSummaries.forEach((String path, LinkedLibrary lib) { |
| 111 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); |
| 112 }); |
| 113 } |
| 114 return new TestSummaryResynthesizer(null, context, unlinkedSummaries, |
| 115 linkedSummaries); |
| 116 } |
| 117 |
| 118 /** |
| 119 * Resynthesize the library element associated with [uri] using |
| 120 * [resynthesizer], and verify that it only had to consult one summary in |
| 121 * order to do so. [original] is consulted merely to verify that no |
| 122 * unnecessary resynthesis work was performed. |
| 123 */ |
| 124 LibraryElementImpl resynthesizeLibraryElement( |
| 125 TestSummaryResynthesizer resynthesizer, |
| 126 String uri, |
| 127 LibraryElement original) { |
| 128 LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri); |
| 129 checkMinimalResynthesisWork(resynthesizer, original); |
| 130 return resynthesized; |
| 131 } |
| 132 |
| 133 test_core() { |
| 134 addLibrary('dart:async'); |
| 135 addLibrary('dart:math'); |
| 136 String uri = 'dart:core'; |
| 137 LibraryElementImpl original = |
| 138 context.computeLibraryElement(context.sourceFactory.forUri(uri)); |
| 139 LibraryElementImpl resynthesized = resynthesizeLibraryElement( |
| 140 encodeLibraryElement(original), uri, original); |
| 141 checkLibraryElements(original, resynthesized); |
| 142 } |
| 143 } |
| 144 |
| 145 @reflectiveTest |
| 146 abstract class ResynthesizeTest extends AbstractSingleUnitTest { |
| 41 Set<Source> otherLibrarySources = new Set<Source>(); | 147 Set<Source> otherLibrarySources = new Set<Source>(); |
| 42 bool constantInitializersAreInvalid = false; | 148 bool constantInitializersAreInvalid = false; |
| 43 | 149 |
| 150 bool get checkPropagatedTypes => true; |
| 151 |
| 44 void addLibrary(String uri) { | 152 void addLibrary(String uri) { |
| 45 otherLibrarySources.add(context.sourceFactory.forUri(uri)); | 153 otherLibrarySources.add(context.sourceFactory.forUri(uri)); |
| 46 } | 154 } |
| 47 | 155 |
| 48 void addLibrarySource(String filePath, String contents) { | 156 void addLibrarySource(String filePath, String contents) { |
| 49 otherLibrarySources.add(addSource(filePath, contents)); | 157 otherLibrarySources.add(addSource(filePath, contents)); |
| 50 } | 158 } |
| 51 | 159 |
| 52 void assertNoErrors(Source source) { | 160 void assertNoErrors(Source source) { |
| 53 GatheringErrorListener errorListener = new GatheringErrorListener(); | 161 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 73 */ | 181 */ |
| 74 void checkElidablePrefix(SimpleIdentifier prefix) { | 182 void checkElidablePrefix(SimpleIdentifier prefix) { |
| 75 if (prefix.staticElement is! PrefixElement && | 183 if (prefix.staticElement is! PrefixElement && |
| 76 prefix.staticElement is! ClassElement) { | 184 prefix.staticElement is! ClassElement) { |
| 77 fail('Prefix of type ${prefix.staticElement.runtimeType}' | 185 fail('Prefix of type ${prefix.staticElement.runtimeType}' |
| 78 ' should not have been elided'); | 186 ' should not have been elided'); |
| 79 } | 187 } |
| 80 } | 188 } |
| 81 | 189 |
| 82 void checkLibrary(String text, | 190 void checkLibrary(String text, |
| 83 {bool allowErrors: false, bool dumpSummaries: false}) { | 191 {bool allowErrors: false, bool dumpSummaries: false}); |
| 84 Source source = addTestSource(text); | |
| 85 LibraryElementImpl original = context.computeLibraryElement(source); | |
| 86 LibraryElementImpl resynthesized = resynthesizeLibraryElement( | |
| 87 encodeLibrary(original, | |
| 88 allowErrors: allowErrors, dumpSummaries: dumpSummaries), | |
| 89 source.uri.toString(), | |
| 90 original); | |
| 91 checkLibraryElements(original, resynthesized); | |
| 92 } | |
| 93 | 192 |
| 94 void checkLibraryElements( | 193 void checkLibraryElements( |
| 95 LibraryElementImpl original, LibraryElementImpl resynthesized) { | 194 LibraryElementImpl original, LibraryElementImpl resynthesized) { |
| 96 compareElements(resynthesized, original, '(library)'); | 195 compareElements(resynthesized, original, '(library)'); |
| 97 expect(resynthesized.displayName, original.displayName); | 196 expect(resynthesized.displayName, original.displayName); |
| 98 expect(original.enclosingElement, isNull); | 197 expect(original.enclosingElement, isNull); |
| 99 expect(resynthesized.enclosingElement, isNull); | 198 expect(resynthesized.enclosingElement, isNull); |
| 100 expect(resynthesized.hasExtUri, original.hasExtUri); | 199 expect(resynthesized.hasExtUri, original.hasExtUri); |
| 101 compareCompilationUnitElements(resynthesized.definingCompilationUnit, | 200 compareCompilationUnitElements(resynthesized.definingCompilationUnit, |
| 102 original.definingCompilationUnit); | 201 original.definingCompilationUnit); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 '(loadLibraryFunction)'); | 234 '(loadLibraryFunction)'); |
| 136 } | 235 } |
| 137 expect(resynthesized.libraryCycle.toSet(), original.libraryCycle.toSet()); | 236 expect(resynthesized.libraryCycle.toSet(), original.libraryCycle.toSet()); |
| 138 } | 237 } |
| 139 | 238 |
| 140 /** | 239 /** |
| 141 * Verify that the [resynthesizer] didn't do any unnecessary work when | 240 * Verify that the [resynthesizer] didn't do any unnecessary work when |
| 142 * resynthesizing [library]. | 241 * resynthesizing [library]. |
| 143 */ | 242 */ |
| 144 void checkMinimalResynthesisWork( | 243 void checkMinimalResynthesisWork( |
| 145 _TestSummaryResynthesizer resynthesizer, LibraryElement library) { | 244 TestSummaryResynthesizer resynthesizer, LibraryElement library) { |
| 146 // Check that no other summaries needed to be resynthesized to resynthesize | 245 // Check that no other summaries needed to be resynthesized to resynthesize |
| 147 // the library element. | 246 // the library element. |
| 148 expect(resynthesizer.resynthesisCount, 1); | 247 expect(resynthesizer.resynthesisCount, 1); |
| 149 // Check that the only linked summary consulted was that for [uri]. | 248 // Check that the only linked summary consulted was that for [uri]. |
| 150 expect(resynthesizer.linkedSummariesRequested, hasLength(1)); | 249 expect(resynthesizer.linkedSummariesRequested, hasLength(1)); |
| 151 expect(resynthesizer.linkedSummariesRequested.first, | 250 expect(resynthesizer.linkedSummariesRequested.first, |
| 152 library.source.uri.toString()); | 251 library.source.uri.toString()); |
| 153 // Check that the only unlinked summaries consulted were those for the | 252 // Check that the only unlinked summaries consulted were those for the |
| 154 // library in question. | 253 // library in question. |
| 155 Set<String> expectedCompilationUnitUris = library.units | 254 Set<String> expectedCompilationUnitUris = library.units |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 expect(rImpl, isNot(new isInstanceOf<Member>()), reason: desc); | 758 expect(rImpl, isNot(new isInstanceOf<Member>()), reason: desc); |
| 660 } | 759 } |
| 661 } | 760 } |
| 662 | 761 |
| 663 void compareExecutableElements( | 762 void compareExecutableElements( |
| 664 ExecutableElement resynthesized, ExecutableElement original, String desc, | 763 ExecutableElement resynthesized, ExecutableElement original, String desc, |
| 665 {bool shallow: false}) { | 764 {bool shallow: false}) { |
| 666 compareElements(resynthesized, original, desc); | 765 compareElements(resynthesized, original, desc); |
| 667 compareParameterElementLists( | 766 compareParameterElementLists( |
| 668 resynthesized.parameters, original.parameters, desc); | 767 resynthesized.parameters, original.parameters, desc); |
| 669 compareTypes( | 768 if (checkPropagatedTypes || !original.hasImplicitReturnType) { |
| 670 resynthesized.returnType, original.returnType, '$desc return type'); | 769 compareTypes( |
| 770 resynthesized.returnType, original.returnType, '$desc return type'); |
| 771 } |
| 671 if (!shallow) { | 772 if (!shallow) { |
| 672 compareTypes(resynthesized.type, original.type, desc); | 773 compareTypes(resynthesized.type, original.type, desc); |
| 673 } | 774 } |
| 674 expect(resynthesized.typeParameters.length, original.typeParameters.length); | 775 expect(resynthesized.typeParameters.length, original.typeParameters.length); |
| 675 for (int i = 0; i < resynthesized.typeParameters.length; i++) { | 776 for (int i = 0; i < resynthesized.typeParameters.length; i++) { |
| 676 compareTypeParameterElements( | 777 compareTypeParameterElements( |
| 677 resynthesized.typeParameters[i], | 778 resynthesized.typeParameters[i], |
| 678 original.typeParameters[i], | 779 original.typeParameters[i], |
| 679 '$desc type parameter ${original.typeParameters[i].name}'); | 780 '$desc type parameter ${original.typeParameters[i].name}'); |
| 680 } | 781 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 compareExecutableElements(resynthesized, original, desc); | 986 compareExecutableElements(resynthesized, original, desc); |
| 886 expect(resynthesized.variable, isNotNull); | 987 expect(resynthesized.variable, isNotNull); |
| 887 expect(resynthesized.variable.location, original.variable.location); | 988 expect(resynthesized.variable.location, original.variable.location); |
| 888 } | 989 } |
| 889 | 990 |
| 890 void comparePropertyInducingElements( | 991 void comparePropertyInducingElements( |
| 891 PropertyInducingElementImpl resynthesized, | 992 PropertyInducingElementImpl resynthesized, |
| 892 PropertyInducingElementImpl original, | 993 PropertyInducingElementImpl original, |
| 893 String desc) { | 994 String desc) { |
| 894 compareVariableElements(resynthesized, original, desc); | 995 compareVariableElements(resynthesized, original, desc); |
| 895 compareTypes(resynthesized.propagatedType, original.propagatedType, desc); | 996 if (checkPropagatedTypes) { |
| 997 compareTypes(resynthesized.propagatedType, original.propagatedType, desc); |
| 998 } |
| 896 if (original.getter == null) { | 999 if (original.getter == null) { |
| 897 expect(resynthesized.getter, isNull); | 1000 expect(resynthesized.getter, isNull); |
| 898 } else { | 1001 } else { |
| 899 expect(resynthesized.getter, isNotNull); | 1002 expect(resynthesized.getter, isNotNull); |
| 900 expect(resynthesized.getter.location, original.getter.location); | 1003 expect(resynthesized.getter.location, original.getter.location); |
| 901 } | 1004 } |
| 902 if (original.setter == null) { | 1005 if (original.setter == null) { |
| 903 expect(resynthesized.setter, isNull); | 1006 expect(resynthesized.setter, isNull); |
| 904 } else { | 1007 } else { |
| 905 expect(resynthesized.setter, isNotNull); | 1008 expect(resynthesized.setter, isNotNull); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 checkPossibleLocalElements(resynthesized, original); | 1148 checkPossibleLocalElements(resynthesized, original); |
| 1046 } | 1149 } |
| 1047 | 1150 |
| 1048 /** | 1151 /** |
| 1049 * Determine the analysis options that should be used for this test. | 1152 * Determine the analysis options that should be used for this test. |
| 1050 */ | 1153 */ |
| 1051 AnalysisOptionsImpl createOptions() => | 1154 AnalysisOptionsImpl createOptions() => |
| 1052 new AnalysisOptionsImpl()..enableGenericMethods = true; | 1155 new AnalysisOptionsImpl()..enableGenericMethods = true; |
| 1053 | 1156 |
| 1054 /** | 1157 /** |
| 1158 * Return a [SummaryResynthesizer] to resynthesize the library with the |
| 1159 * given [librarySource]. |
| 1160 */ |
| 1161 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource); |
| 1162 |
| 1163 /** |
| 1055 * Serialize the given [library] into a summary. Then create a | 1164 * Serialize the given [library] into a summary. Then create a |
| 1056 * [_TestSummaryResynthesizer] which can deserialize it, along with any | 1165 * [TestSummaryResynthesizer] which can deserialize it, along with any |
| 1057 * references it makes to `dart:core`. | 1166 * references it makes to `dart:core`. |
| 1058 * | 1167 * |
| 1059 * Errors will lead to a test failure unless [allowErrors] is `true`. | 1168 * Errors will lead to a test failure unless [allowErrors] is `true`. |
| 1060 */ | 1169 */ |
| 1061 _TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, | 1170 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, |
| 1062 {bool allowErrors: false, bool dumpSummaries: false}) { | 1171 {bool allowErrors: false, bool dumpSummaries: false}) { |
| 1063 if (!allowErrors) { | 1172 if (!allowErrors) { |
| 1064 assertNoErrors(library.source); | 1173 assertNoErrors(library.source); |
| 1065 } | 1174 } |
| 1066 addLibrary('dart:core'); | 1175 addLibrary('dart:core'); |
| 1067 addLibrary('dart:async'); | 1176 addLibrary('dart:async'); |
| 1068 addLibrary('dart:math'); | 1177 addLibrary('dart:math'); |
| 1069 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); | 1178 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); |
| 1070 } | 1179 } |
| 1071 | 1180 |
| 1072 /** | 1181 /** |
| 1073 * Convert the library element [library] into a summary, and then create a | 1182 * Convert the library element [library] into a summary, and then create a |
| 1074 * [_TestSummaryResynthesizer] which can deserialize it. | 1183 * [TestSummaryResynthesizer] which can deserialize it. |
| 1075 * | 1184 * |
| 1076 * Caller is responsible for checking the library for errors, and adding any | 1185 * Caller is responsible for checking the library for errors, and adding any |
| 1077 * dependent libraries using [addLibrary]. | 1186 * dependent libraries using [addLibrary]. |
| 1078 */ | 1187 */ |
| 1079 _TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, | 1188 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, |
| 1080 {bool dumpSummaries: false}) { | 1189 {bool dumpSummaries: false}) { |
| 1081 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; | 1190 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; |
| 1082 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { | 1191 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { |
| 1083 LibrarySerializationResult serialized = serializeLibrary( | 1192 LibrarySerializationResult serialized = serializeLibrary( |
| 1084 lib, context.typeProvider, context.analysisOptions.strongMode); | 1193 lib, context.typeProvider, context.analysisOptions.strongMode); |
| 1085 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { | 1194 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { |
| 1086 unlinkedSummaries[serialized.unitUris[i]] = | 1195 unlinkedSummaries[serialized.unitUris[i]] = |
| 1087 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); | 1196 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); |
| 1088 } | 1197 } |
| 1089 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); | 1198 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); |
| 1090 } | 1199 } |
| 1091 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ | 1200 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ |
| 1092 library.source.uri.toString(): getLinkedSummaryFor(library) | 1201 library.source.uri.toString(): getLinkedSummaryFor(library) |
| 1093 }; | 1202 }; |
| 1094 for (Source source in otherLibrarySources) { | 1203 for (Source source in otherLibrarySources) { |
| 1095 LibraryElement original = context.computeLibraryElement(source); | 1204 LibraryElement original = context.computeLibraryElement(source); |
| 1096 String uri = source.uri.toString(); | 1205 String uri = source.uri.toString(); |
| 1097 linkedSummaries[uri] = getLinkedSummaryFor(original); | 1206 linkedSummaries[uri] = getLinkedSummaryFor(original); |
| 1098 } | 1207 } |
| 1099 if (dumpSummaries) { | 1208 if (dumpSummaries) { |
| 1100 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { | 1209 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { |
| 1101 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); | 1210 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); |
| 1102 }); | 1211 }); |
| 1103 linkedSummaries.forEach((String path, LinkedLibrary lib) { | 1212 linkedSummaries.forEach((String path, LinkedLibrary lib) { |
| 1104 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); | 1213 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); |
| 1105 }); | 1214 }); |
| 1106 } | 1215 } |
| 1107 return new _TestSummaryResynthesizer( | 1216 return new TestSummaryResynthesizer(null, context, unlinkedSummaries, |
| 1108 null, | 1217 linkedSummaries); |
| 1109 context, | |
| 1110 context.typeProvider, | |
| 1111 context.sourceFactory, | |
| 1112 unlinkedSummaries, | |
| 1113 linkedSummaries, | |
| 1114 createOptions().strongMode); | |
| 1115 } | 1218 } |
| 1116 | 1219 |
| 1117 fail_library_hasExtUri() { | 1220 fail_library_hasExtUri() { |
| 1118 checkLibrary('import "dart-ext:doesNotExist.dart";'); | 1221 checkLibrary('import "dart-ext:doesNotExist.dart";'); |
| 1119 } | 1222 } |
| 1120 | 1223 |
| 1121 ElementImpl getActualElement(Element element, String desc) { | 1224 ElementImpl getActualElement(Element element, String desc) { |
| 1122 if (element == null) { | 1225 if (element == null) { |
| 1123 return null; | 1226 return null; |
| 1124 } else if (element is ElementImpl) { | 1227 } else if (element is ElementImpl) { |
| 1125 return element; | 1228 return element; |
| 1126 } else if (element is ElementHandle) { | 1229 } else if (element is ElementHandle) { |
| 1127 Element actualElement = element.actualElement; | 1230 Element actualElement = element.actualElement; |
| 1128 // A handle should never point to a member, because if it did, then | 1231 // A handle should never point to a member, because if it did, then |
| 1129 // "is Member" checks on the handle would produce the wrong result. | 1232 // "is Member" checks on the handle would produce the wrong result. |
| 1130 expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc); | 1233 expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc); |
| 1131 return getActualElement(actualElement, desc); | 1234 return getActualElement(actualElement, desc); |
| 1132 } else if (element is Member) { | 1235 } else if (element is Member) { |
| 1133 return getActualElement(element.baseElement, desc); | 1236 return getActualElement(element.baseElement, desc); |
| 1134 } else { | 1237 } else { |
| 1135 fail('Unexpected type for resynthesized ($desc):' | 1238 fail('Unexpected type for resynthesized ($desc):' |
| 1136 ' ${element.runtimeType}'); | 1239 ' ${element.runtimeType}'); |
| 1137 return null; | 1240 return null; |
| 1138 } | 1241 } |
| 1139 } | 1242 } |
| 1140 | 1243 |
| 1141 /** | |
| 1142 * Resynthesize the library element associated with [uri] using | |
| 1143 * [resynthesizer], and verify that it only had to consult one summary in | |
| 1144 * order to do so. [original] is consulted merely to verify that no | |
| 1145 * unnecessary resynthesis work was performed. | |
| 1146 */ | |
| 1147 LibraryElementImpl resynthesizeLibraryElement( | |
| 1148 _TestSummaryResynthesizer resynthesizer, | |
| 1149 String uri, | |
| 1150 LibraryElement original) { | |
| 1151 LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri); | |
| 1152 checkMinimalResynthesisWork(resynthesizer, original); | |
| 1153 return resynthesized; | |
| 1154 } | |
| 1155 | |
| 1156 @override | 1244 @override |
| 1157 void setUp() { | 1245 void setUp() { |
| 1158 super.setUp(); | 1246 super.setUp(); |
| 1159 prepareAnalysisContext(createOptions()); | 1247 prepareAnalysisContext(createOptions()); |
| 1160 } | 1248 } |
| 1161 | 1249 |
| 1162 test_class_abstract() { | 1250 test_class_abstract() { |
| 1163 checkLibrary('abstract class C {}'); | 1251 checkLibrary('abstract class C {}'); |
| 1164 } | 1252 } |
| 1165 | 1253 |
| (...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2555 final x; | 2643 final x; |
| 2556 C() : x = new D(); | 2644 C() : x = new D(); |
| 2557 } | 2645 } |
| 2558 class D { | 2646 class D { |
| 2559 final x; | 2647 final x; |
| 2560 D() : x = new C(); | 2648 D() : x = new C(); |
| 2561 } | 2649 } |
| 2562 '''); | 2650 '''); |
| 2563 } | 2651 } |
| 2564 | 2652 |
| 2565 test_core() { | |
| 2566 addLibrary('dart:async'); | |
| 2567 addLibrary('dart:math'); | |
| 2568 String uri = 'dart:core'; | |
| 2569 LibraryElementImpl original = | |
| 2570 context.computeLibraryElement(context.sourceFactory.forUri(uri)); | |
| 2571 LibraryElementImpl resynthesized = resynthesizeLibraryElement( | |
| 2572 encodeLibraryElement(original), uri, original); | |
| 2573 checkLibraryElements(original, resynthesized); | |
| 2574 } | |
| 2575 | |
| 2576 test_enum_documented() { | 2653 test_enum_documented() { |
| 2577 checkLibrary(''' | 2654 checkLibrary(''' |
| 2578 // Extra comment so doc comment offset != 0 | 2655 // Extra comment so doc comment offset != 0 |
| 2579 /** | 2656 /** |
| 2580 * Docs | 2657 * Docs |
| 2581 */ | 2658 */ |
| 2582 enum E { v }'''); | 2659 enum E { v }'''); |
| 2583 } | 2660 } |
| 2584 | 2661 |
| 2585 test_enum_value_documented() { | 2662 test_enum_value_documented() { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2842 class C<T, U> { | 2919 class C<T, U> { |
| 2843 static void m<V, W>(V v, W w) { | 2920 static void m<V, W>(V v, W w) { |
| 2844 void f<X, Y>(V v, W w, X x, Y y) { | 2921 void f<X, Y>(V v, W w, X x, Y y) { |
| 2845 } | 2922 } |
| 2846 } | 2923 } |
| 2847 } | 2924 } |
| 2848 '''); | 2925 '''); |
| 2849 } | 2926 } |
| 2850 | 2927 |
| 2851 test_getElement_constructor_named() { | 2928 test_getElement_constructor_named() { |
| 2929 String text = 'class C { C.named(); }'; |
| 2852 ConstructorElement original = context | 2930 ConstructorElement original = context |
| 2853 .computeLibraryElement(addTestSource('class C { C.named(); }')) | 2931 .computeLibraryElement(addTestSource(text)) |
| 2854 .getType('C') | 2932 .getType('C') |
| 2855 .getNamedConstructor('named'); | 2933 .getNamedConstructor('named'); |
| 2856 expect(original, isNotNull); | 2934 expect(original, isNotNull); |
| 2857 ConstructorElement resynthesized = validateGetElement(original); | 2935 ConstructorElement resynthesized = validateGetElement(text, original); |
| 2858 compareConstructorElements(resynthesized, original, 'C.constructor named'); | 2936 compareConstructorElements(resynthesized, original, 'C.constructor named'); |
| 2859 } | 2937 } |
| 2860 | 2938 |
| 2861 test_getElement_constructor_unnamed() { | 2939 test_getElement_constructor_unnamed() { |
| 2940 String text = 'class C { C(); }'; |
| 2862 ConstructorElement original = context | 2941 ConstructorElement original = context |
| 2863 .computeLibraryElement(addTestSource('class C { C(); }')) | 2942 .computeLibraryElement(addTestSource(text)) |
| 2864 .getType('C') | 2943 .getType('C') |
| 2865 .unnamedConstructor; | 2944 .unnamedConstructor; |
| 2866 expect(original, isNotNull); | 2945 expect(original, isNotNull); |
| 2867 ConstructorElement resynthesized = validateGetElement(original); | 2946 ConstructorElement resynthesized = validateGetElement(text, original); |
| 2868 compareConstructorElements(resynthesized, original, 'C.constructor'); | 2947 compareConstructorElements(resynthesized, original, 'C.constructor'); |
| 2869 } | 2948 } |
| 2870 | 2949 |
| 2871 test_getElement_field() { | 2950 test_getElement_field() { |
| 2951 String text = 'class C { var f; }'; |
| 2872 FieldElement original = context | 2952 FieldElement original = context |
| 2873 .computeLibraryElement(addTestSource('class C { var f; }')) | 2953 .computeLibraryElement(addTestSource(text)) |
| 2874 .getType('C') | 2954 .getType('C') |
| 2875 .getField('f'); | 2955 .getField('f'); |
| 2876 expect(original, isNotNull); | 2956 expect(original, isNotNull); |
| 2877 FieldElement resynthesized = validateGetElement(original); | 2957 FieldElement resynthesized = validateGetElement(text, original); |
| 2878 compareFieldElements(resynthesized, original, 'C.field f'); | 2958 compareFieldElements(resynthesized, original, 'C.field f'); |
| 2879 } | 2959 } |
| 2880 | 2960 |
| 2881 test_getElement_getter() { | 2961 test_getElement_getter() { |
| 2962 String text = 'class C { get f => null; }'; |
| 2882 PropertyAccessorElement original = context | 2963 PropertyAccessorElement original = context |
| 2883 .computeLibraryElement(addTestSource('class C { get f => null; }')) | 2964 .computeLibraryElement(addTestSource(text)) |
| 2884 .getType('C') | 2965 .getType('C') |
| 2885 .getGetter('f'); | 2966 .getGetter('f'); |
| 2886 expect(original, isNotNull); | 2967 expect(original, isNotNull); |
| 2887 PropertyAccessorElement resynthesized = validateGetElement(original); | 2968 PropertyAccessorElement resynthesized = validateGetElement(text, original); |
| 2888 comparePropertyAccessorElements(resynthesized, original, 'C.getter f'); | 2969 comparePropertyAccessorElements(resynthesized, original, 'C.getter f'); |
| 2889 } | 2970 } |
| 2890 | 2971 |
| 2891 test_getElement_method() { | 2972 test_getElement_method() { |
| 2973 String text = 'class C { f() {} }'; |
| 2892 MethodElement original = context | 2974 MethodElement original = context |
| 2893 .computeLibraryElement(addTestSource('class C { f() {} }')) | 2975 .computeLibraryElement(addTestSource(text)) |
| 2894 .getType('C') | 2976 .getType('C') |
| 2895 .getMethod('f'); | 2977 .getMethod('f'); |
| 2896 expect(original, isNotNull); | 2978 expect(original, isNotNull); |
| 2897 MethodElement resynthesized = validateGetElement(original); | 2979 MethodElement resynthesized = validateGetElement(text, original); |
| 2898 compareMethodElements(resynthesized, original, 'C.method f'); | 2980 compareMethodElements(resynthesized, original, 'C.method f'); |
| 2899 } | 2981 } |
| 2900 | 2982 |
| 2901 test_getElement_operator() { | 2983 test_getElement_operator() { |
| 2984 String text = 'class C { operator+(x) => null; }'; |
| 2902 MethodElement original = context | 2985 MethodElement original = context |
| 2903 .computeLibraryElement( | 2986 .computeLibraryElement(addTestSource(text)) |
| 2904 addTestSource('class C { operator+(x) => null; }')) | |
| 2905 .getType('C') | 2987 .getType('C') |
| 2906 .getMethod('+'); | 2988 .getMethod('+'); |
| 2907 expect(original, isNotNull); | 2989 expect(original, isNotNull); |
| 2908 MethodElement resynthesized = validateGetElement(original); | 2990 MethodElement resynthesized = validateGetElement(text, original); |
| 2909 compareMethodElements(resynthesized, original, 'C.operator+'); | 2991 compareMethodElements(resynthesized, original, 'C.operator+'); |
| 2910 } | 2992 } |
| 2911 | 2993 |
| 2912 test_getElement_setter() { | 2994 test_getElement_setter() { |
| 2995 String text = 'class C { void set f(value) {} }'; |
| 2913 PropertyAccessorElement original = context | 2996 PropertyAccessorElement original = context |
| 2914 .computeLibraryElement( | 2997 .computeLibraryElement(addTestSource(text)) |
| 2915 addTestSource('class C { void set f(value) {} }')) | |
| 2916 .getType('C') | 2998 .getType('C') |
| 2917 .getSetter('f'); | 2999 .getSetter('f'); |
| 2918 expect(original, isNotNull); | 3000 expect(original, isNotNull); |
| 2919 PropertyAccessorElement resynthesized = validateGetElement(original); | 3001 PropertyAccessorElement resynthesized = validateGetElement(text, original); |
| 2920 comparePropertyAccessorElements(resynthesized, original, 'C.setter f'); | 3002 comparePropertyAccessorElements(resynthesized, original, 'C.setter f'); |
| 2921 } | 3003 } |
| 2922 | 3004 |
| 2923 test_getElement_unit() { | 3005 test_getElement_unit() { |
| 2924 Source source = addTestSource('class C { f() {} }'); | 3006 String text = 'class C { f() {} }'; |
| 3007 Source source = addTestSource(text); |
| 2925 CompilationUnitElement original = | 3008 CompilationUnitElement original = |
| 2926 context.computeLibraryElement(source).definingCompilationUnit; | 3009 context.computeLibraryElement(source).definingCompilationUnit; |
| 2927 expect(original, isNotNull); | 3010 expect(original, isNotNull); |
| 2928 CompilationUnitElement resynthesized = validateGetElement(original); | 3011 CompilationUnitElement resynthesized = validateGetElement(text, original); |
| 2929 compareCompilationUnitElements(resynthesized, original); | 3012 compareCompilationUnitElements(resynthesized, original); |
| 2930 } | 3013 } |
| 2931 | 3014 |
| 2932 test_getter_documented() { | 3015 test_getter_documented() { |
| 2933 checkLibrary(''' | 3016 checkLibrary(''' |
| 2934 // Extra comment so doc comment offset != 0 | 3017 // Extra comment so doc comment offset != 0 |
| 2935 /** | 3018 /** |
| 2936 * Docs | 3019 * Docs |
| 2937 */ | 3020 */ |
| 2938 get x => null;'''); | 3021 get x => null;'''); |
| (...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4055 addSource('/b.dart', 'part of my.lib; int get x => 42;'); | 4138 addSource('/b.dart', 'part of my.lib; int get x => 42;'); |
| 4056 checkLibrary('library my.lib; part "a.dart"; part "b.dart";'); | 4139 checkLibrary('library my.lib; part "a.dart"; part "b.dart";'); |
| 4057 } | 4140 } |
| 4058 | 4141 |
| 4059 test_variables() { | 4142 test_variables() { |
| 4060 checkLibrary('int i; int j;'); | 4143 checkLibrary('int i; int j;'); |
| 4061 } | 4144 } |
| 4062 | 4145 |
| 4063 /** | 4146 /** |
| 4064 * Encode the library containing [original] into a summary and then use | 4147 * Encode the library containing [original] into a summary and then use |
| 4065 * [_TestSummaryResynthesizer.getElement] to retrieve just the original | 4148 * [TestSummaryResynthesizer.getElement] to retrieve just the original |
| 4066 * element from the resynthesized summary. | 4149 * element from the resynthesized summary. |
| 4067 */ | 4150 */ |
| 4068 Element validateGetElement(Element original) { | 4151 Element validateGetElement(String text, Element original) { |
| 4069 _TestSummaryResynthesizer resynthesizer = encodeLibrary(original.library); | 4152 SummaryResynthesizer resynthesizer = |
| 4153 encodeDecodeLibrarySource(original.library.source); |
| 4070 ElementLocationImpl location = original.location; | 4154 ElementLocationImpl location = original.location; |
| 4071 Element result = resynthesizer.getElement(location); | 4155 Element result = resynthesizer.getElement(location); |
| 4072 checkMinimalResynthesisWork(resynthesizer, original.library); | 4156 checkMinimalResynthesisWork(resynthesizer, original.library); |
| 4073 // Check that no other summaries needed to be resynthesized to resynthesize | 4157 // Check that no other summaries needed to be resynthesized to resynthesize |
| 4074 // the library element. | 4158 // the library element. |
| 4075 expect(resynthesizer.resynthesisCount, 1); | 4159 expect(resynthesizer.resynthesisCount, 1); |
| 4076 expect(result.location, location); | 4160 expect(result.location, location); |
| 4077 return result; | 4161 return result; |
| 4078 } | 4162 } |
| 4079 | 4163 |
| 4080 void _assertUnresolvedIdentifier(Expression initializer, String desc) { | 4164 void _assertUnresolvedIdentifier(Expression initializer, String desc) { |
| 4081 expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc); | 4165 expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc); |
| 4082 SimpleIdentifier identifier = initializer; | 4166 SimpleIdentifier identifier = initializer; |
| 4083 expect(identifier.staticElement, isNull, reason: desc); | 4167 expect(identifier.staticElement, isNull, reason: desc); |
| 4084 } | 4168 } |
| 4085 } | 4169 } |
| 4086 | 4170 |
| 4087 class _TestSummaryResynthesizer extends SummaryResynthesizer { | 4171 class TestSummaryResynthesizer extends SummaryResynthesizer { |
| 4088 final Map<String, UnlinkedUnit> unlinkedSummaries; | 4172 final Map<String, UnlinkedUnit> unlinkedSummaries; |
| 4089 final Map<String, LinkedLibrary> linkedSummaries; | 4173 final Map<String, LinkedLibrary> linkedSummaries; |
| 4090 | 4174 |
| 4091 /** | 4175 /** |
| 4092 * The set of uris for which unlinked summaries have been requested using | 4176 * The set of uris for which unlinked summaries have been requested using |
| 4093 * [getUnlinkedSummary]. | 4177 * [getUnlinkedSummary]. |
| 4094 */ | 4178 */ |
| 4095 final Set<String> unlinkedSummariesRequested = new Set<String>(); | 4179 final Set<String> unlinkedSummariesRequested = new Set<String>(); |
| 4096 | 4180 |
| 4097 /** | 4181 /** |
| 4098 * The set of uris for which linked summaries have been requested using | 4182 * The set of uris for which linked summaries have been requested using |
| 4099 * [getLinkedSummary]. | 4183 * [getLinkedSummary]. |
| 4100 */ | 4184 */ |
| 4101 final Set<String> linkedSummariesRequested = new Set<String>(); | 4185 final Set<String> linkedSummariesRequested = new Set<String>(); |
| 4102 | 4186 |
| 4103 _TestSummaryResynthesizer( | 4187 TestSummaryResynthesizer(SummaryResynthesizer parent, AnalysisContext context, |
| 4104 SummaryResynthesizer parent, | 4188 this.unlinkedSummaries, this.linkedSummaries) |
| 4105 AnalysisContext context, | 4189 : super(parent, context, context.typeProvider, context.sourceFactory, |
| 4106 TypeProvider typeProvider, | 4190 context.analysisOptions.strongMode); |
| 4107 SourceFactory sourceFactory, | |
| 4108 this.unlinkedSummaries, | |
| 4109 this.linkedSummaries, | |
| 4110 bool strongMode) | |
| 4111 : super(parent, context, typeProvider, sourceFactory, strongMode); | |
| 4112 | 4191 |
| 4113 @override | 4192 @override |
| 4114 LinkedLibrary getLinkedSummary(String uri) { | 4193 LinkedLibrary getLinkedSummary(String uri) { |
| 4115 linkedSummariesRequested.add(uri); | 4194 linkedSummariesRequested.add(uri); |
| 4116 LinkedLibrary serializedLibrary = linkedSummaries[uri]; | 4195 LinkedLibrary serializedLibrary = linkedSummaries[uri]; |
| 4117 if (serializedLibrary == null) { | 4196 if (serializedLibrary == null) { |
| 4118 fail('Unexpectedly tried to get linked summary for $uri'); | 4197 fail('Unexpectedly tried to get linked summary for $uri'); |
| 4119 } | 4198 } |
| 4120 return serializedLibrary; | 4199 return serializedLibrary; |
| 4121 } | 4200 } |
| 4122 | 4201 |
| 4123 @override | 4202 @override |
| 4124 UnlinkedUnit getUnlinkedSummary(String uri) { | 4203 UnlinkedUnit getUnlinkedSummary(String uri) { |
| 4125 unlinkedSummariesRequested.add(uri); | 4204 unlinkedSummariesRequested.add(uri); |
| 4126 UnlinkedUnit serializedUnit = unlinkedSummaries[uri]; | 4205 UnlinkedUnit serializedUnit = unlinkedSummaries[uri]; |
| 4127 if (serializedUnit == null) { | 4206 if (serializedUnit == null) { |
| 4128 fail('Unexpectedly tried to get unlinked summary for $uri'); | 4207 fail('Unexpectedly tried to get unlinked summary for $uri'); |
| 4129 } | 4208 } |
| 4130 return serializedUnit; | 4209 return serializedUnit; |
| 4131 } | 4210 } |
| 4132 | 4211 |
| 4133 @override | 4212 @override |
| 4134 bool hasLibrarySummary(String uri) { | 4213 bool hasLibrarySummary(String uri) { |
| 4135 return true; | 4214 return true; |
| 4136 } | 4215 } |
| 4137 } | 4216 } |
| OLD | NEW |