Chromium Code Reviews| 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 analyzer.test.src.summary.summary_test; | 5 library analyzer.test.src.summary.summary_test; |
| 6 | 6 |
| 7 import 'package:analyzer/dart/element/element.dart'; | 7 import 'package:analyzer/dart/element/element.dart'; |
| 8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
| 9 import 'package:analyzer/src/generated/engine.dart'; | 9 import 'package:analyzer/src/generated/engine.dart'; |
| 10 import 'package:analyzer/src/generated/error.dart'; | 10 import 'package:analyzer/src/generated/error.dart'; |
| 11 import 'package:analyzer/src/generated/java_engine_io.dart'; | 11 import 'package:analyzer/src/generated/java_engine_io.dart'; |
| 12 import 'package:analyzer/src/generated/parser.dart'; | 12 import 'package:analyzer/src/generated/parser.dart'; |
| 13 import 'package:analyzer/src/generated/scanner.dart'; | 13 import 'package:analyzer/src/generated/scanner.dart'; |
| 14 import 'package:analyzer/src/generated/source.dart'; | 14 import 'package:analyzer/src/generated/source.dart'; |
| 15 import 'package:analyzer/src/generated/source_io.dart'; | 15 import 'package:analyzer/src/generated/source_io.dart'; |
| 16 import 'package:analyzer/src/summary/base.dart'; | 16 import 'package:analyzer/src/summary/base.dart'; |
| 17 import 'package:analyzer/src/summary/format.dart'; | 17 import 'package:analyzer/src/summary/format.dart'; |
| 18 import 'package:analyzer/src/summary/prelink.dart'; | |
| 18 import 'package:analyzer/src/summary/public_namespace_computer.dart' | 19 import 'package:analyzer/src/summary/public_namespace_computer.dart' |
| 19 as public_namespace; | 20 as public_namespace; |
| 20 import 'package:analyzer/src/summary/summarize_elements.dart' | 21 import 'package:analyzer/src/summary/summarize_elements.dart' |
| 21 as summarize_elements; | 22 as summarize_elements; |
| 22 import 'package:unittest/unittest.dart'; | 23 import 'package:unittest/unittest.dart'; |
| 23 | 24 |
| 24 import '../../generated/resolver_test.dart'; | 25 import '../../generated/resolver_test.dart'; |
| 25 import '../../reflective_tests.dart'; | 26 import '../../reflective_tests.dart'; |
| 26 | 27 |
| 27 main() { | 28 main() { |
| 28 groupSep = ' | '; | 29 groupSep = ' | '; |
| 29 runReflectiveTests(SummarizeElementsTest); | 30 runReflectiveTests(SummarizeElementsTest); |
| 31 runReflectiveTests(PrelinkerTest); | |
| 30 } | 32 } |
| 31 | 33 |
| 32 /** | 34 /** |
| 35 * Convert a summary object (or a portion of one) into a canonical form that | |
| 36 * can be easily compared using [expect]. If [orderByName] is true, and the | |
| 37 * object is a [List], it is sorted by the `name` field of its elements. | |
| 38 */ | |
| 39 Object canonicalize(Object obj, {bool orderByName: false}) { | |
| 40 if (obj is SummaryClass) { | |
| 41 Map<String, Object> result = <String, Object>{}; | |
| 42 obj.toMap().forEach((String key, Object value) { | |
| 43 bool orderByName = false; | |
| 44 if (obj is UnlinkedPublicNamespace && key == 'names') { | |
| 45 orderByName = true; | |
| 46 } | |
| 47 result[key] = canonicalize(value, orderByName: orderByName); | |
| 48 }); | |
| 49 return result; | |
| 50 } else if (obj is List) { | |
| 51 List<Object> result = <Object>[]; | |
| 52 for (Object item in obj) { | |
| 53 result.add(canonicalize(item)); | |
| 54 } | |
| 55 if (orderByName) { | |
| 56 result.sort((Object a, Object b) { | |
| 57 if (a is Map && b is Map) { | |
| 58 return Comparable.compare(a['name'], b['name']); | |
| 59 } else { | |
| 60 return 0; | |
| 61 } | |
| 62 }); | |
| 63 } | |
| 64 return result; | |
| 65 } else if (obj is String || obj is num || obj is bool) { | |
| 66 return obj; | |
| 67 } else { | |
| 68 return obj.toString(); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 UnlinkedPublicNamespace computePublicNamespaceFromText( | |
| 73 String text, Source source) { | |
| 74 CharacterReader reader = new CharSequenceReader(text); | |
| 75 Scanner scanner = | |
| 76 new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER); | |
| 77 Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); | |
| 78 parser.parseGenericMethods = true; | |
| 79 CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize()); | |
| 80 UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer( | |
| 81 public_namespace | |
| 82 .computePublicNamespace(new BuilderContext(), unit) | |
| 83 .toBuffer()); | |
| 84 return namespace; | |
| 85 } | |
| 86 | |
| 87 /** | |
| 88 * Override of [SummaryTest] which verifies the correctness of the prelinker by | |
| 89 * creating summaries from the element model, discarding their prelinked | |
| 90 * information, and then recreating it using the prelinker. | |
| 91 */ | |
| 92 @reflectiveTest | |
| 93 class PrelinkerTest extends SummarizeElementsTest { | |
| 94 /** | |
| 95 * The public namespaces of the sdk are computed once so that we don't bog | |
| 96 * down the test. Structured as a map from absolute URI to the corresponding | |
| 97 * public namespace. | |
| 98 * | |
| 99 * Note: should an exception occur during computation of this variable, it | |
| 100 * will silently be set to null to allow other tests to run. | |
| 101 */ | |
| 102 static final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () { | |
| 103 try { | |
| 104 AnalysisContext analysisContext = | |
| 105 AnalysisContextFactory.contextWithCore(); | |
| 106 Map<String, UnlinkedPublicNamespace> uriToNamespace = | |
| 107 <String, UnlinkedPublicNamespace>{}; | |
| 108 List<LibraryElement> libraries = [ | |
| 109 analysisContext.typeProvider.objectType.element.library, | |
| 110 analysisContext.typeProvider.futureType.element.library | |
| 111 ]; | |
| 112 for (LibraryElement library in libraries) { | |
| 113 summarize_elements.LibrarySerializationResult serializedLibrary = | |
| 114 summarize_elements.serializeLibrary( | |
| 115 new BuilderContext(), library, analysisContext.typeProvider); | |
| 116 for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) { | |
| 117 uriToNamespace[ | |
| 118 serializedLibrary.unitUris[i]] = new UnlinkedUnit.fromBuffer( | |
| 119 serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace; | |
| 120 } | |
| 121 } | |
| 122 return uriToNamespace; | |
| 123 } catch (_) { | |
| 124 return null; | |
| 125 } | |
| 126 }(); | |
| 127 | |
| 128 final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace = | |
| 129 <String, UnlinkedPublicNamespace>{}; | |
| 130 | |
| 131 @override | |
| 132 bool get expectAbsoluteUrisInDependencies => false; | |
| 133 | |
| 134 @override | |
| 135 Source addNamedSource(String filePath, String contents) { | |
| 136 Source source = super.addNamedSource(filePath, contents); | |
| 137 uriToPublicNamespace[absUri(filePath)] = | |
| 138 computePublicNamespaceFromText(contents, source); | |
| 139 return source; | |
| 140 } | |
| 141 | |
| 142 String resolveAbsoluteUri(LibraryElement library, String relativeUri) { | |
|
scheglov
2016/01/10 05:15:12
resolveToAbsoluteUri would be better maybe?
Paul Berry
2016/01/10 22:15:17
Done.
| |
| 143 Source resolvedSource = | |
| 144 analysisContext.sourceFactory.resolveUri(library.source, relativeUri); | |
| 145 if (resolvedSource == null) { | |
| 146 fail('Failed to resolve relative uri "$relativeUri"'); | |
| 147 } | |
| 148 String absoluteUri = resolvedSource.uri.toString(); | |
| 149 return absoluteUri; | |
|
scheglov
2016/01/10 05:15:12
Could be inlined.
Paul Berry
2016/01/10 22:15:17
Done.
| |
| 150 } | |
| 151 | |
| 152 @override | |
| 153 void serializeLibraryElement(LibraryElement library) { | |
| 154 super.serializeLibraryElement(library); | |
| 155 Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{}; | |
| 156 expect(unlinkedUnits.length, unitUris.length); | |
| 157 for (int i = 1; i < unlinkedUnits.length; i++) { | |
| 158 uriToUnit[unitUris[i]] = unlinkedUnits[i]; | |
| 159 } | |
| 160 UnlinkedUnit getPart(String relativeUri) { | |
| 161 String absoluteUri = resolveAbsoluteUri(library, relativeUri); | |
| 162 UnlinkedUnit unit = uriToUnit[absoluteUri]; | |
| 163 if (unit == null) { | |
| 164 fail('Prelinker unexpectedly requested unit for "$relativeUri"' | |
| 165 ' (resolves to "$absoluteUri").'); | |
| 166 } | |
| 167 return unit; | |
| 168 } | |
| 169 UnlinkedPublicNamespace getImport(String relativeUri) { | |
| 170 String absoluteUri = resolveAbsoluteUri(library, relativeUri); | |
| 171 UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri]; | |
| 172 if (namespace == null) { | |
| 173 namespace = uriToPublicNamespace[absoluteUri]; | |
| 174 } | |
| 175 if (namespace == null && !allowMissingFiles) { | |
| 176 fail('Prelinker unexpectedly requested namespace for "$relativeUri"' | |
| 177 ' (resolves to "$absoluteUri").' | |
| 178 ' Namespaces available: ${uriToPublicNamespace.keys}'); | |
| 179 } | |
| 180 return namespace; | |
| 181 } | |
| 182 prelinked = new PrelinkedLibrary.fromBuffer( | |
| 183 prelink(builderContext, unlinkedUnits[0], getPart, getImport) | |
| 184 .toBuffer()); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 /** | |
| 33 * Override of [SummaryTest] which creates summaries from the element model. | 189 * Override of [SummaryTest] which creates summaries from the element model. |
| 34 */ | 190 */ |
| 35 @reflectiveTest | 191 @reflectiveTest |
| 36 class SummarizeElementsTest extends ResolverTestCase with SummaryTest { | 192 class SummarizeElementsTest extends ResolverTestCase with SummaryTest { |
| 37 final BuilderContext builderContext = new BuilderContext(); | 193 final BuilderContext builderContext = new BuilderContext(); |
| 38 | 194 |
| 39 /** | 195 /** |
| 40 * The list of absolute unit URIs corresponding to the compilation units in | 196 * The list of absolute unit URIs corresponding to the compilation units in |
| 41 * [unlinkedUnits]. | 197 * [unlinkedUnits]. |
| 42 */ | 198 */ |
| 43 List<String> unitUris; | 199 List<String> unitUris; |
| 44 | 200 |
| 45 @override | 201 @override |
| 46 bool get checkAstDerivedData => false; | 202 bool get checkAstDerivedData => false; |
| 47 | 203 |
| 48 /** | 204 @override |
| 49 * Convert a summary object (or a portion of one) into a canonical form that | 205 bool get expectAbsoluteUrisInDependencies => true; |
| 50 * can be easily compared using [expect]. If [orderByName] is true, and the | |
| 51 * object is a [List], it is sorted by the `name` field of its elements. | |
| 52 */ | |
| 53 Object canonicalize(Object obj, {bool orderByName: false}) { | |
| 54 if (obj is SummaryClass) { | |
| 55 Map<String, Object> result = <String, Object>{}; | |
| 56 obj.toMap().forEach((String key, Object value) { | |
| 57 bool orderByName = false; | |
| 58 if (obj is UnlinkedPublicNamespace && key == 'names') { | |
| 59 orderByName = true; | |
| 60 } | |
| 61 result[key] = canonicalize(value, orderByName: orderByName); | |
| 62 }); | |
| 63 return result; | |
| 64 } else if (obj is List) { | |
| 65 List<Object> result = <Object>[]; | |
| 66 for (Object item in obj) { | |
| 67 result.add(canonicalize(item)); | |
| 68 } | |
| 69 if (orderByName) { | |
| 70 result.sort((Object a, Object b) { | |
| 71 if (a is Map && b is Map) { | |
| 72 return Comparable.compare(a['name'], b['name']); | |
| 73 } else { | |
| 74 return 0; | |
| 75 } | |
| 76 }); | |
| 77 } | |
| 78 return result; | |
| 79 } else { | |
| 80 return obj; | |
| 81 } | |
| 82 } | |
| 83 | 206 |
| 84 /** | 207 /** |
| 85 * Serialize the library containing the given class [element], then | 208 * Serialize the library containing the given class [element], then |
| 86 * deserialize it and return the summary of the class. | 209 * deserialize it and return the summary of the class. |
| 87 */ | 210 */ |
| 88 UnlinkedClass serializeClassElement(ClassElement element) { | 211 UnlinkedClass serializeClassElement(ClassElement element) { |
| 89 serializeLibraryElement(element.library); | 212 serializeLibraryElement(element.library); |
| 90 return findClass(element.name, failIfAbsent: true); | 213 return findClass(element.name, failIfAbsent: true); |
| 91 } | 214 } |
| 92 | 215 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 } | 265 } |
| 143 | 266 |
| 144 /** | 267 /** |
| 145 * Verify that [public_namespace.computePublicNamespace] produces data that's | 268 * Verify that [public_namespace.computePublicNamespace] produces data that's |
| 146 * equivalent to that produced by [summarize_elements.serializeLibrary]. | 269 * equivalent to that produced by [summarize_elements.serializeLibrary]. |
| 147 */ | 270 */ |
| 148 void verifyPublicNamespace() { | 271 void verifyPublicNamespace() { |
| 149 for (int i = 0; i < unlinkedUnits.length; i++) { | 272 for (int i = 0; i < unlinkedUnits.length; i++) { |
| 150 Source source = analysisContext.sourceFactory.forUri(unitUris[i]); | 273 Source source = analysisContext.sourceFactory.forUri(unitUris[i]); |
| 151 String text = analysisContext.getContents(source).data; | 274 String text = analysisContext.getContents(source).data; |
| 152 CharacterReader reader = new CharSequenceReader(text); | |
| 153 Scanner scanner = | |
| 154 new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER); | |
| 155 Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); | |
| 156 parser.parseGenericMethods = true; | |
| 157 CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize()); | |
| 158 UnlinkedPublicNamespace namespace = | 275 UnlinkedPublicNamespace namespace = |
| 159 new UnlinkedPublicNamespace.fromBuffer(public_namespace | 276 computePublicNamespaceFromText(text, source); |
| 160 .computePublicNamespace(builderContext, unit) | |
| 161 .toBuffer()); | |
| 162 expect(canonicalize(namespace), | 277 expect(canonicalize(namespace), |
| 163 canonicalize(unlinkedUnits[i].publicNamespace), | 278 canonicalize(unlinkedUnits[i].publicNamespace), |
| 164 reason: 'publicNamespace(${unitUris[i]})'); | 279 reason: 'publicNamespace(${unitUris[i]})'); |
| 165 } | 280 } |
| 166 } | 281 } |
| 167 } | 282 } |
| 168 | 283 |
| 169 /** | 284 /** |
| 170 * Base class containing most summary tests. This allows summary tests to be | 285 * Base class containing most summary tests. This allows summary tests to be |
| 171 * re-used to exercise all the different ways in which summaries can be | 286 * re-used to exercise all the different ways in which summaries can be |
| 172 * generated (e.g. direct from the AST, from the element model, from a | 287 * generated (e.g. direct from the AST, from the element model, from a |
| 173 * "relinking" process, etc.) | 288 * "relinking" process, etc.) |
| 174 */ | 289 */ |
| 175 abstract class SummaryTest { | 290 abstract class SummaryTest { |
| 176 /** | 291 /** |
| 177 * Prelinked summary that results from serializing and then deserializing the | 292 * Prelinked summary that results from serializing and then deserializing the |
| 178 * library under test. | 293 * library under test. |
| 179 */ | 294 */ |
| 180 PrelinkedLibrary prelinked; | 295 PrelinkedLibrary prelinked; |
| 181 | 296 |
| 182 /** | 297 /** |
| 183 * Unlinked compilation unit summaries that result from serializing and | 298 * Unlinked compilation unit summaries that result from serializing and |
| 184 * deserializing the library under test. | 299 * deserializing the library under test. |
| 185 */ | 300 */ |
| 186 List<UnlinkedUnit> unlinkedUnits; | 301 List<UnlinkedUnit> unlinkedUnits; |
| 187 | 302 |
| 188 /** | 303 /** |
| 304 * A test will set this to `true` if it contains `import`, `export`, or | |
| 305 * `part` declarations that deliberately refer to non-existent files. | |
| 306 */ | |
| 307 bool allowMissingFiles = false; | |
| 308 | |
| 309 /** | |
| 189 * `true` if the summary was created directly from the AST (and hence | 310 * `true` if the summary was created directly from the AST (and hence |
| 190 * contains information that is not obtainable from the element model alone). | 311 * contains information that is not obtainable from the element model alone). |
| 191 * TODO(paulberry): modify the element model so that it contains all the data | 312 * TODO(paulberry): modify the element model so that it contains all the data |
| 192 * that summaries need, so that this flag is no longer needed. | 313 * that summaries need, so that this flag is no longer needed. |
| 193 */ | 314 */ |
| 194 bool get checkAstDerivedData; | 315 bool get checkAstDerivedData; |
| 195 | 316 |
| 196 /** | 317 /** |
| 197 * Get access to the prelinked defining compilation unit. | 318 * Get access to the prelinked defining compilation unit. |
| 198 */ | 319 */ |
| 199 PrelinkedUnit get definingUnit => prelinked.units[0]; | 320 PrelinkedUnit get definingUnit => prelinked.units[0]; |
| 200 | 321 |
| 201 /** | 322 /** |
| 323 * `true` if the prelinked portion of the summary is expected to contain | |
| 324 * absolute URIs. This happens because the element model doesn't (yet) store | |
| 325 * enough information to recover relative URIs, TODO(paulberry): fix this. | |
| 326 */ | |
| 327 bool get expectAbsoluteUrisInDependencies; | |
| 328 | |
| 329 /** | |
| 202 * Convert [path] to a suitably formatted absolute path URI for the current | 330 * Convert [path] to a suitably formatted absolute path URI for the current |
| 203 * platform. | 331 * platform. |
| 204 */ | 332 */ |
| 205 String absUri(String path) { | 333 String absUri(String path) { |
| 206 return FileUtilities2.createFile(path).toURI().toString(); | 334 return FileUtilities2.createFile(path).toURI().toString(); |
| 207 } | 335 } |
| 208 | 336 |
| 209 /** | 337 /** |
| 210 * Add the given source file so that it may be referenced by the file under | 338 * Add the given source file so that it may be referenced by the file under |
| 211 * test. | 339 * test. |
| 212 */ | 340 */ |
| 213 addNamedSource(String filePath, String contents); | 341 Source addNamedSource(String filePath, String contents); |
| 214 | 342 |
| 215 /** | 343 /** |
| 216 * Verify that the [dependency]th element of the dependency table represents | 344 * Verify that the [dependency]th element of the dependency table represents |
| 217 * a file reachable via the given [absoluteUri] and [relativeUri]. | 345 * a file reachable via the given [absoluteUri] and [relativeUri]. |
| 218 */ | 346 */ |
| 219 void checkDependency(int dependency, String absoluteUri, String relativeUri) { | 347 void checkDependency(int dependency, String absoluteUri, String relativeUri) { |
| 220 if (!checkAstDerivedData) { | 348 if (expectAbsoluteUrisInDependencies) { |
| 221 // The element model doesn't (yet) store enough information to recover | 349 // The element model doesn't (yet) store enough information to recover |
| 222 // relative URIs, so we have to use the absolute URI. | 350 // relative URIs, so we have to use the absolute URI. |
| 223 // TODO(paulberry): fix this. | 351 // TODO(paulberry): fix this. |
| 224 relativeUri = absoluteUri; | 352 relativeUri = absoluteUri; |
| 225 } | 353 } |
| 226 expect(dependency, new isInstanceOf<int>()); | 354 expect(dependency, new isInstanceOf<int>()); |
| 227 expect(prelinked.dependencies[dependency].uri, relativeUri); | 355 expect(prelinked.dependencies[dependency].uri, relativeUri); |
| 228 } | 356 } |
| 229 | 357 |
| 230 /** | 358 /** |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 255 */ | 383 */ |
| 256 void checkDynamicTypeRef(UnlinkedTypeRef typeRef) { | 384 void checkDynamicTypeRef(UnlinkedTypeRef typeRef) { |
| 257 checkTypeRef(typeRef, null, null, null); | 385 checkTypeRef(typeRef, null, null, null); |
| 258 } | 386 } |
| 259 | 387 |
| 260 /** | 388 /** |
| 261 * Verify that the dependency table contains an entry for a file reachable | 389 * Verify that the dependency table contains an entry for a file reachable |
| 262 * via the given [absoluteUri] and [relativeUri]. | 390 * via the given [absoluteUri] and [relativeUri]. |
| 263 */ | 391 */ |
| 264 void checkHasDependency(String absoluteUri, String relativeUri) { | 392 void checkHasDependency(String absoluteUri, String relativeUri) { |
| 265 if (!checkAstDerivedData) { | 393 if (expectAbsoluteUrisInDependencies) { |
| 266 // The element model doesn't (yet) store enough information to recover | 394 // The element model doesn't (yet) store enough information to recover |
| 267 // relative URIs, so we have to use the absolute URI. | 395 // relative URIs, so we have to use the absolute URI. |
| 268 // TODO(paulberry): fix this. | 396 // TODO(paulberry): fix this. |
| 269 relativeUri = absoluteUri; | 397 relativeUri = absoluteUri; |
| 270 } | 398 } |
| 399 List<String> found = <String>[]; | |
| 271 for (PrelinkedDependency dep in prelinked.dependencies) { | 400 for (PrelinkedDependency dep in prelinked.dependencies) { |
| 272 if (dep.uri == relativeUri) { | 401 if (dep.uri == relativeUri) { |
| 273 return; | 402 return; |
| 274 } | 403 } |
| 404 found.add(dep.uri); | |
| 275 } | 405 } |
| 276 fail('Did not find dependency $absoluteUri'); | 406 fail('Did not find dependency $relativeUri. Found: $found'); |
| 277 } | 407 } |
| 278 | 408 |
| 279 /** | 409 /** |
| 280 * Verify that the dependency table *does not* contain any entries for a file | 410 * Verify that the dependency table *does not* contain any entries for a file |
| 281 * reachable via the given [absoluteUri] and [relativeUri]. | 411 * reachable via the given [absoluteUri] and [relativeUri]. |
| 282 */ | 412 */ |
| 283 void checkLacksDependency(String absoluteUri, String relativeUri) { | 413 void checkLacksDependency(String absoluteUri, String relativeUri) { |
| 284 if (!checkAstDerivedData) { | 414 if (expectAbsoluteUrisInDependencies) { |
| 285 // The element model doesn't (yet) store enough information to recover | 415 // The element model doesn't (yet) store enough information to recover |
| 286 // relative URIs, so we have to use the absolute URI. | 416 // relative URIs, so we have to use the absolute URI. |
| 287 // TODO(paulberry): fix this. | 417 // TODO(paulberry): fix this. |
| 288 relativeUri = absoluteUri; | 418 relativeUri = absoluteUri; |
| 289 } | 419 } |
| 290 for (PrelinkedDependency dep in prelinked.dependencies) { | 420 for (PrelinkedDependency dep in prelinked.dependencies) { |
| 291 if (dep.uri == relativeUri) { | 421 if (dep.uri == relativeUri) { |
| 292 fail('Unexpected dependency found: $relativeUri'); | 422 fail('Unexpected dependency found: $relativeUri'); |
| 293 } | 423 } |
| 294 } | 424 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 expect(reference.prefixReference, 0); | 486 expect(reference.prefixReference, 0); |
| 357 } | 487 } |
| 358 if (absoluteUri == null) { | 488 if (absoluteUri == null) { |
| 359 expect(referenceResolution.dependency, 0); | 489 expect(referenceResolution.dependency, 0); |
| 360 } else { | 490 } else { |
| 361 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); | 491 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); |
| 362 } | 492 } |
| 363 if (!allowTypeParameters) { | 493 if (!allowTypeParameters) { |
| 364 expect(typeRef.typeArguments, isEmpty); | 494 expect(typeRef.typeArguments, isEmpty); |
| 365 } | 495 } |
| 366 if (expectedName == null) { | 496 if (expectedKind == PrelinkedReferenceKind.unresolved) { |
| 497 // summarize_elements.dart isn't yet able to record the name of | |
| 498 // unresolved references. TODO(paulberry): fix this. | |
| 499 expect(reference.name, '*unresolved*'); | |
| 500 } else if (expectedName == null) { | |
| 367 expect(reference.name, isEmpty); | 501 expect(reference.name, isEmpty); |
| 368 } else { | 502 } else { |
| 369 expect(reference.name, expectedName); | 503 expect(reference.name, expectedName); |
| 370 } | 504 } |
| 371 if (expectedPrefix == null) { | 505 if (expectedPrefix == null) { |
| 372 expect(reference.prefixReference, 0); | 506 expect(reference.prefixReference, 0); |
| 373 } else { | 507 } else { |
| 374 checkPrefix(reference.prefixReference, expectedPrefix); | 508 checkPrefix(reference.prefixReference, expectedPrefix); |
| 375 } | 509 } |
| 376 expect(referenceResolution.kind, expectedKind); | 510 expect(referenceResolution.kind, expectedKind); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 403 UnlinkedEnumValue value = serializeEnumText(text).values[0]; | 537 UnlinkedEnumValue value = serializeEnumText(text).values[0]; |
| 404 expect(value.documentationComment, isNotNull); | 538 expect(value.documentationComment, isNotNull); |
| 405 checkDocumentationComment(value.documentationComment, text); | 539 checkDocumentationComment(value.documentationComment, text); |
| 406 } | 540 } |
| 407 | 541 |
| 408 fail_test_import_missing() { | 542 fail_test_import_missing() { |
| 409 // TODO(paulberry): At the moment unresolved imports are not included in | 543 // TODO(paulberry): At the moment unresolved imports are not included in |
| 410 // the element model, so we can't pass this test. | 544 // the element model, so we can't pass this test. |
| 411 // Unresolved imports are included since this is necessary for proper | 545 // Unresolved imports are included since this is necessary for proper |
| 412 // dependency tracking. | 546 // dependency tracking. |
| 547 allowMissingFiles = true; | |
| 413 serializeLibraryText('import "foo.dart";', allowErrors: true); | 548 serializeLibraryText('import "foo.dart";', allowErrors: true); |
| 414 // Second import is the implicit import of dart:core | 549 // Second import is the implicit import of dart:core |
| 415 expect(unlinkedUnits[0].imports, hasLength(2)); | 550 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 416 checkDependency( | 551 checkDependency( |
| 417 prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); | 552 prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 418 } | 553 } |
| 419 | 554 |
| 420 fail_type_reference_to_nonexistent_file_via_prefix() { | 555 fail_type_reference_to_nonexistent_file_via_prefix() { |
| 421 // TODO(paulberry): this test currently fails because there is not enough | 556 // TODO(paulberry): this test currently fails because there is not enough |
| 422 // information in the element model to figure out that the unresolved | 557 // information in the element model to figure out that the unresolved |
| 423 // reference `p.C` uses the prefix `p`. | 558 // reference `p.C` uses the prefix `p`. |
| 559 allowMissingFiles = true; | |
| 424 UnlinkedTypeRef typeRef = serializeTypeText('p.C', | 560 UnlinkedTypeRef typeRef = serializeTypeText('p.C', |
| 425 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); | 561 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); |
| 426 checkUnresolvedTypeRef(typeRef, 'p', 'C'); | 562 checkUnresolvedTypeRef(typeRef, 'p', 'C'); |
| 427 } | 563 } |
| 428 | 564 |
| 429 fail_type_reference_to_type_visible_via_multiple_import_prefixes() { | 565 fail_type_reference_to_type_visible_via_multiple_import_prefixes() { |
| 430 // TODO(paulberry): this test currently fails because the element model | 566 // TODO(paulberry): this test currently fails because the element model |
| 431 // doesn't record enough information to track which prefix is used to refer | 567 // doesn't record enough information to track which prefix is used to refer |
| 432 // to a type. | 568 // to a type. |
| 433 addNamedSource('/lib1.dart', 'class C'); | 569 addNamedSource('/lib1.dart', 'class C'); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 | 764 |
| 629 /** | 765 /** |
| 630 * Serialize a type declaration using the given [text] as a type name, and | 766 * Serialize a type declaration using the given [text] as a type name, and |
| 631 * return a summary of the corresponding [UnlinkedTypeRef]. If the type | 767 * return a summary of the corresponding [UnlinkedTypeRef]. If the type |
| 632 * declaration needs to refer to types that are not available in core, those | 768 * declaration needs to refer to types that are not available in core, those |
| 633 * types may be declared in [otherDeclarations]. | 769 * types may be declared in [otherDeclarations]. |
| 634 */ | 770 */ |
| 635 UnlinkedTypeRef serializeTypeText(String text, | 771 UnlinkedTypeRef serializeTypeText(String text, |
| 636 {String otherDeclarations: '', bool allowErrors: false}) { | 772 {String otherDeclarations: '', bool allowErrors: false}) { |
| 637 return serializeVariableText('$otherDeclarations\n$text v;', | 773 return serializeVariableText('$otherDeclarations\n$text v;', |
| 638 allowErrors: allowErrors) | 774 allowErrors: allowErrors).type; |
| 639 .type; | |
| 640 } | 775 } |
| 641 | 776 |
| 642 /** | 777 /** |
| 643 * Serialize the given library [text] and return the summary of the variable | 778 * Serialize the given library [text] and return the summary of the variable |
| 644 * with the given [variableName]. | 779 * with the given [variableName]. |
| 645 */ | 780 */ |
| 646 UnlinkedVariable serializeVariableText(String text, | 781 UnlinkedVariable serializeVariableText(String text, |
| 647 {String variableName: 'v', bool allowErrors: false}) { | 782 {String variableName: 'v', bool allowErrors: false}) { |
| 648 serializeLibraryText(text, allowErrors: allowErrors); | 783 serializeLibraryText(text, allowErrors: allowErrors); |
| 649 return findVariable(variableName, failIfAbsent: true); | 784 return findVariable(variableName, failIfAbsent: true); |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1308 } | 1443 } |
| 1309 | 1444 |
| 1310 test_dependencies_import_to_export_in_subdirs_absolute_export() { | 1445 test_dependencies_import_to_export_in_subdirs_absolute_export() { |
| 1311 addNamedSource('/a/a.dart', | 1446 addNamedSource('/a/a.dart', |
| 1312 'library a; export "${absUri('/a/b/b.dart')}"; class A {}'); | 1447 'library a; export "${absUri('/a/b/b.dart')}"; class A {}'); |
| 1313 addNamedSource('/a/b/b.dart', 'library b;'); | 1448 addNamedSource('/a/b/b.dart', 'library b;'); |
| 1314 serializeLibraryText('import "a/a.dart"; A a;'); | 1449 serializeLibraryText('import "a/a.dart"; A a;'); |
| 1315 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart'); | 1450 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart'); |
| 1316 // The main test library depends on b.dart, because names defined in | 1451 // The main test library depends on b.dart, because names defined in |
| 1317 // b.dart are exported by a.dart. | 1452 // b.dart are exported by a.dart. |
| 1318 checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart'); | 1453 checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart')); |
| 1319 } | 1454 } |
| 1320 | 1455 |
| 1321 test_dependencies_import_to_export_in_subdirs_absolute_import() { | 1456 test_dependencies_import_to_export_in_subdirs_absolute_import() { |
| 1322 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); | 1457 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 1323 addNamedSource('/a/b/b.dart', 'library b;'); | 1458 addNamedSource('/a/b/b.dart', 'library b;'); |
| 1324 serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;'); | 1459 serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;'); |
| 1325 checkHasDependency(absUri('/a/a.dart'), '/a/a.dart'); | 1460 checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart')); |
| 1326 // The main test library depends on b.dart, because names defined in | 1461 // The main test library depends on b.dart, because names defined in |
| 1327 // b.dart are exported by a.dart. | 1462 // b.dart are exported by a.dart. |
| 1328 checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart'); | 1463 checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart')); |
| 1329 } | 1464 } |
| 1330 | 1465 |
| 1331 test_dependencies_import_to_export_in_subdirs_relative() { | 1466 test_dependencies_import_to_export_in_subdirs_relative() { |
| 1332 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); | 1467 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 1333 addNamedSource('/a/b/b.dart', 'library b;'); | 1468 addNamedSource('/a/b/b.dart', 'library b;'); |
| 1334 serializeLibraryText('import "a/a.dart"; A a;'); | 1469 serializeLibraryText('import "a/a.dart"; A a;'); |
| 1335 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart'); | 1470 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart'); |
| 1336 // The main test library depends on b.dart, because names defined in | 1471 // The main test library depends on b.dart, because names defined in |
| 1337 // b.dart are exported by a.dart. | 1472 // b.dart are exported by a.dart. |
| 1338 checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart'); | 1473 checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart'); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1655 expect(executable.isConst, false); | 1790 expect(executable.isConst, false); |
| 1656 expect(executable.isFactory, false); | 1791 expect(executable.isFactory, false); |
| 1657 expect(executable.isStatic, false); | 1792 expect(executable.isStatic, false); |
| 1658 expect(executable.parameters, hasLength(1)); | 1793 expect(executable.parameters, hasLength(1)); |
| 1659 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool'); | 1794 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool'); |
| 1660 expect(executable.typeParameters, isEmpty); | 1795 expect(executable.typeParameters, isEmpty); |
| 1661 } | 1796 } |
| 1662 | 1797 |
| 1663 test_executable_operator_index_set() { | 1798 test_executable_operator_index_set() { |
| 1664 UnlinkedExecutable executable = serializeClassText( | 1799 UnlinkedExecutable executable = serializeClassText( |
| 1665 'class C { void operator[]=(int i, bool v) => null; }') | 1800 'class C { void operator[]=(int i, bool v) => null; }').executables[0]; |
| 1666 .executables[0]; | |
| 1667 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); | 1801 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 1668 expect(executable.name, '[]='); | 1802 expect(executable.name, '[]='); |
| 1669 expect(executable.hasImplicitReturnType, false); | 1803 expect(executable.hasImplicitReturnType, false); |
| 1670 expect(executable.isAbstract, false); | 1804 expect(executable.isAbstract, false); |
| 1671 expect(executable.isConst, false); | 1805 expect(executable.isConst, false); |
| 1672 expect(executable.isFactory, false); | 1806 expect(executable.isFactory, false); |
| 1673 expect(executable.isStatic, false); | 1807 expect(executable.isStatic, false); |
| 1674 expect(executable.parameters, hasLength(2)); | 1808 expect(executable.parameters, hasLength(2)); |
| 1675 expect(executable.returnType, isNull); | 1809 expect(executable.returnType, isNull); |
| 1676 expect(executable.typeParameters, isEmpty); | 1810 expect(executable.typeParameters, isEmpty); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2095 | 2229 |
| 2096 test_import_non_deferred() { | 2230 test_import_non_deferred() { |
| 2097 serializeLibraryText( | 2231 serializeLibraryText( |
| 2098 'import "dart:async" as a; main() { print(a.Future); }'); | 2232 'import "dart:async" as a; main() { print(a.Future); }'); |
| 2099 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse); | 2233 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse); |
| 2100 } | 2234 } |
| 2101 | 2235 |
| 2102 test_import_of_file_with_missing_part() { | 2236 test_import_of_file_with_missing_part() { |
| 2103 // Other references in foo.dart should be resolved even though foo.dart's | 2237 // Other references in foo.dart should be resolved even though foo.dart's |
| 2104 // part declaration for bar.dart refers to a non-existent file. | 2238 // part declaration for bar.dart refers to a non-existent file. |
| 2239 allowMissingFiles = true; | |
| 2105 addNamedSource('/foo.dart', 'part "bar.dart"; class C {}'); | 2240 addNamedSource('/foo.dart', 'part "bar.dart"; class C {}'); |
| 2106 serializeLibraryText('import "foo.dart"; C x;'); | 2241 serializeLibraryText('import "foo.dart"; C x;'); |
| 2107 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); | 2242 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); |
| 2108 } | 2243 } |
| 2109 | 2244 |
| 2110 test_import_of_missing_export() { | 2245 test_import_of_missing_export() { |
| 2111 // Other references in foo.dart should be resolved even though foo.dart's | 2246 // Other references in foo.dart should be resolved even though foo.dart's |
| 2112 // re-export of bar.dart refers to a non-existent file. | 2247 // re-export of bar.dart refers to a non-existent file. |
| 2248 allowMissingFiles = true; | |
| 2113 addNamedSource('/foo.dart', 'export "bar.dart"; class C {}'); | 2249 addNamedSource('/foo.dart', 'export "bar.dart"; class C {}'); |
| 2114 serializeLibraryText('import "foo.dart"; C x;'); | 2250 serializeLibraryText('import "foo.dart"; C x;'); |
| 2115 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); | 2251 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); |
| 2116 } | 2252 } |
| 2117 | 2253 |
| 2118 test_import_offset() { | 2254 test_import_offset() { |
| 2119 String libraryText = ' import "dart:async"; Future x;'; | 2255 String libraryText = ' import "dart:async"; Future x;'; |
| 2120 serializeLibraryText(libraryText); | 2256 serializeLibraryText(libraryText); |
| 2121 expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import')); | 2257 expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import')); |
| 2122 expect(unlinkedUnits[0].imports[0].uriOffset, | 2258 expect(unlinkedUnits[0].imports[0].uriOffset, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2147 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v='); | 2283 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v='); |
| 2148 } | 2284 } |
| 2149 | 2285 |
| 2150 test_import_prefix_reference() { | 2286 test_import_prefix_reference() { |
| 2151 UnlinkedVariable variable = | 2287 UnlinkedVariable variable = |
| 2152 serializeVariableText('import "dart:async" as a; a.Future v;'); | 2288 serializeVariableText('import "dart:async" as a; a.Future v;'); |
| 2153 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', | 2289 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', |
| 2154 expectedPrefix: 'a', numTypeParameters: 1); | 2290 expectedPrefix: 'a', numTypeParameters: 1); |
| 2155 } | 2291 } |
| 2156 | 2292 |
| 2293 test_import_prefixes_take_precedence_over_imported_names() { | |
| 2294 addNamedSource('/a.dart', 'class b {} class A'); | |
| 2295 addNamedSource('/b.dart', 'class Cls {}'); | |
| 2296 addNamedSource('/c.dart', 'class Cls {}'); | |
| 2297 addNamedSource('/d.dart', 'class c {} class D'); | |
| 2298 serializeLibraryText(''' | |
| 2299 import 'a.dart'; | |
| 2300 import 'b.dart' as b; | |
| 2301 import 'c.dart' as c; | |
| 2302 import 'd.dart'; | |
| 2303 A aCls; | |
| 2304 b.Cls bCls; | |
| 2305 c.Cls cCls; | |
| 2306 D dCls; | |
| 2307 '''); | |
| 2308 checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A'); | |
| 2309 checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls', | |
| 2310 expectedPrefix: 'b'); | |
| 2311 checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls', | |
| 2312 expectedPrefix: 'c'); | |
| 2313 checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D'); | |
| 2314 } | |
| 2315 | |
| 2157 test_import_reference() { | 2316 test_import_reference() { |
| 2158 UnlinkedVariable variable = | 2317 UnlinkedVariable variable = |
| 2159 serializeVariableText('import "dart:async"; Future v;'); | 2318 serializeVariableText('import "dart:async"; Future v;'); |
| 2160 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', | 2319 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', |
| 2161 numTypeParameters: 1); | 2320 numTypeParameters: 1); |
| 2162 } | 2321 } |
| 2163 | 2322 |
| 2164 test_import_reference_merged_no_prefix() { | 2323 test_import_reference_merged_no_prefix() { |
| 2165 serializeLibraryText(''' | 2324 serializeLibraryText(''' |
| 2166 import "dart:async" show Future; | 2325 import "dart:async" show Future; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2182 | 2341 |
| 2183 a.Future f; | 2342 a.Future f; |
| 2184 a.Stream s; | 2343 a.Stream s; |
| 2185 '''); | 2344 '''); |
| 2186 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future', | 2345 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future', |
| 2187 expectedPrefix: 'a', numTypeParameters: 1); | 2346 expectedPrefix: 'a', numTypeParameters: 1); |
| 2188 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream', | 2347 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream', |
| 2189 expectedPrefix: 'a', numTypeParameters: 1); | 2348 expectedPrefix: 'a', numTypeParameters: 1); |
| 2190 } | 2349 } |
| 2191 | 2350 |
| 2351 test_import_reference_merged_prefixed_separate_libraries() { | |
| 2352 addNamedSource('/a.dart', 'class A {}'); | |
| 2353 addNamedSource('/b.dart', 'class B {}'); | |
| 2354 serializeLibraryText(''' | |
| 2355 import 'a.dart' as p; | |
| 2356 import 'b.dart' as p; | |
| 2357 | |
| 2358 p.A a; | |
| 2359 p.B b; | |
| 2360 '''); | |
| 2361 checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A', | |
| 2362 expectedPrefix: 'p'); | |
| 2363 checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B', | |
| 2364 expectedPrefix: 'p'); | |
| 2365 } | |
| 2366 | |
| 2192 test_import_show_order() { | 2367 test_import_show_order() { |
| 2193 String libraryText = | 2368 String libraryText = |
| 2194 'import "dart:async" show Future, Stream; Future x; Stream y;'; | 2369 'import "dart:async" show Future, Stream; Future x; Stream y;'; |
| 2195 serializeLibraryText(libraryText); | 2370 serializeLibraryText(libraryText); |
| 2196 // Second import is the implicit import of dart:core | 2371 // Second import is the implicit import of dart:core |
| 2197 expect(unlinkedUnits[0].imports, hasLength(2)); | 2372 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 2198 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1)); | 2373 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1)); |
| 2199 expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2)); | 2374 expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2)); |
| 2200 expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty); | 2375 expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty); |
| 2201 expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future'); | 2376 expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future'); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2240 expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length); | 2415 expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length); |
| 2241 } | 2416 } |
| 2242 | 2417 |
| 2243 test_library_unnamed() { | 2418 test_library_unnamed() { |
| 2244 serializeLibraryText(''); | 2419 serializeLibraryText(''); |
| 2245 expect(unlinkedUnits[0].libraryName, isEmpty); | 2420 expect(unlinkedUnits[0].libraryName, isEmpty); |
| 2246 expect(unlinkedUnits[0].libraryNameOffset, 0); | 2421 expect(unlinkedUnits[0].libraryNameOffset, 0); |
| 2247 expect(unlinkedUnits[0].libraryNameLength, 0); | 2422 expect(unlinkedUnits[0].libraryNameLength, 0); |
| 2248 } | 2423 } |
| 2249 | 2424 |
| 2425 test_local_names_take_precedence_over_imported_names() { | |
| 2426 addNamedSource('/a.dart', 'class C {} class D {}'); | |
| 2427 serializeLibraryText(''' | |
| 2428 import 'a.dart'; | |
| 2429 class C {} | |
| 2430 C c; | |
| 2431 D d;'''); | |
| 2432 checkTypeRef(findVariable('c').type, null, null, 'C'); | |
| 2433 checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D'); | |
| 2434 } | |
| 2435 | |
| 2250 test_method_documented() { | 2436 test_method_documented() { |
| 2251 String text = ''' | 2437 String text = ''' |
| 2252 class C { | 2438 class C { |
| 2253 /** | 2439 /** |
| 2254 * Docs | 2440 * Docs |
| 2255 */ | 2441 */ |
| 2256 f() {} | 2442 f() {} |
| 2257 }'''; | 2443 }'''; |
| 2258 UnlinkedExecutable executable = serializeClassText(text).executables[0]; | 2444 UnlinkedExecutable executable = serializeClassText(text).executables[0]; |
| 2259 expect(executable.documentationComment, isNotNull); | 2445 expect(executable.documentationComment, isNotNull); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2688 UnlinkedVariable variable = | 2874 UnlinkedVariable variable = |
| 2689 serializeVariableText('int i;', variableName: 'i'); | 2875 serializeVariableText('int i;', variableName: 'i'); |
| 2690 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); | 2876 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); |
| 2691 } | 2877 } |
| 2692 | 2878 |
| 2693 test_varible_private() { | 2879 test_varible_private() { |
| 2694 serializeVariableText('int _i;', variableName: '_i'); | 2880 serializeVariableText('int _i;', variableName: '_i'); |
| 2695 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); | 2881 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 2696 } | 2882 } |
| 2697 } | 2883 } |
| OLD | NEW |