OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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.resynthesize_kernel_test; | 5 library analyzer.test.src.summary.resynthesize_kernel_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; | 10 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; |
11 import 'package:analyzer/dart/ast/token.dart'; | 11 import 'package:analyzer/dart/ast/token.dart'; |
12 import 'package:analyzer/dart/element/element.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
13 import 'package:analyzer/dart/element/type.dart'; | 13 import 'package:analyzer/dart/element/type.dart'; |
14 import 'package:analyzer/file_system/file_system.dart'; | 14 import 'package:analyzer/file_system/file_system.dart'; |
15 import 'package:analyzer/file_system/memory_file_system.dart'; | 15 import 'package:analyzer/file_system/memory_file_system.dart'; |
16 import 'package:analyzer/src/dart/element/element.dart'; | 16 import 'package:analyzer/src/dart/element/element.dart'; |
17 import 'package:analyzer/src/dart/element/type.dart'; | 17 import 'package:analyzer/src/dart/element/type.dart'; |
18 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 18 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
19 import 'package:analyzer/src/generated/source.dart'; | 19 import 'package:analyzer/src/generated/source.dart'; |
20 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; | 20 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; |
21 import 'package:analyzer/src/summary/resynthesize.dart'; | 21 import 'package:analyzer/src/summary/resynthesize.dart'; |
22 import 'package:front_end/file_system.dart'; | 22 import 'package:front_end/file_system.dart'; |
23 import 'package:front_end/src/base/performace_logger.dart'; | 23 import 'package:front_end/src/base/performace_logger.dart'; |
24 import 'package:front_end/src/fasta/uri_translator_impl.dart'; | 24 import 'package:front_end/src/fasta/uri_translator_impl.dart'; |
25 import 'package:front_end/src/incremental/byte_store.dart'; | 25 import 'package:front_end/src/incremental/byte_store.dart'; |
26 import 'package:front_end/src/incremental/kernel_driver.dart'; | 26 import 'package:front_end/src/incremental/kernel_driver.dart'; |
27 import 'package:kernel/kernel.dart' as kernel; | 27 import 'package:kernel/kernel.dart' as kernel; |
28 import 'package:kernel/target/targets.dart'; | 28 import 'package:kernel/target/targets.dart'; |
| 29 import 'package:kernel/type_environment.dart' as kernel; |
29 import 'package:package_config/packages.dart'; | 30 import 'package:package_config/packages.dart'; |
30 import 'package:path/path.dart' as pathos; | 31 import 'package:path/path.dart' as pathos; |
31 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 32 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
32 | 33 |
33 import '../context/mock_sdk.dart'; | 34 import '../context/mock_sdk.dart'; |
34 import 'resynthesize_common.dart'; | 35 import 'resynthesize_common.dart'; |
35 | 36 |
36 main() { | 37 main() { |
37 defineReflectiveSuite(() { | 38 defineReflectiveSuite(() { |
38 defineReflectiveTests(ResynthesizeKernelStrongTest); | 39 defineReflectiveTests(ResynthesizeKernelStrongTest); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 KernelResult kernelResult = await driver.getKernel(testUri); | 90 KernelResult kernelResult = await driver.getKernel(testUri); |
90 | 91 |
91 var libraryMap = <String, kernel.Library>{}; | 92 var libraryMap = <String, kernel.Library>{}; |
92 for (var cycleResult in kernelResult.results) { | 93 for (var cycleResult in kernelResult.results) { |
93 for (var library in cycleResult.kernelLibraries) { | 94 for (var library in cycleResult.kernelLibraries) { |
94 String uriStr = library.importUri.toString(); | 95 String uriStr = library.importUri.toString(); |
95 libraryMap[uriStr] = library; | 96 libraryMap[uriStr] = library; |
96 } | 97 } |
97 } | 98 } |
98 | 99 |
99 var resynthesizer = new _KernelResynthesizer(context, libraryMap); | 100 var resynthesizer = |
| 101 new _KernelResynthesizer(context, kernelResult.types, libraryMap); |
100 return resynthesizer.getLibrary(testUriStr); | 102 return resynthesizer.getLibrary(testUriStr); |
101 } | 103 } |
102 | 104 |
103 @override | 105 @override |
104 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) { | 106 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) { |
105 // TODO(scheglov): implement encodeDecodeLibrarySource | 107 // TODO(scheglov): implement encodeDecodeLibrarySource |
106 throw new UnimplementedError(); | 108 throw new UnimplementedError(); |
107 } | 109 } |
108 | 110 |
109 @failingTest | 111 @failingTest |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 test_const_reference_topLevelFunction_imported() async { | 488 test_const_reference_topLevelFunction_imported() async { |
487 await super.test_const_reference_topLevelFunction_imported(); | 489 await super.test_const_reference_topLevelFunction_imported(); |
488 } | 490 } |
489 | 491 |
490 @failingTest | 492 @failingTest |
491 test_const_reference_topLevelFunction_imported_withPrefix() async { | 493 test_const_reference_topLevelFunction_imported_withPrefix() async { |
492 await super.test_const_reference_topLevelFunction_imported_withPrefix(); | 494 await super.test_const_reference_topLevelFunction_imported_withPrefix(); |
493 } | 495 } |
494 | 496 |
495 @failingTest | 497 @failingTest |
496 test_const_reference_topLevelVariable() async { | |
497 await super.test_const_reference_topLevelVariable(); | |
498 } | |
499 | |
500 @failingTest | |
501 test_const_reference_topLevelVariable_imported() async { | 498 test_const_reference_topLevelVariable_imported() async { |
502 await super.test_const_reference_topLevelVariable_imported(); | 499 await super.test_const_reference_topLevelVariable_imported(); |
503 } | 500 } |
504 | 501 |
505 @failingTest | 502 @failingTest |
506 test_const_reference_topLevelVariable_imported_withPrefix() async { | 503 test_const_reference_topLevelVariable_imported_withPrefix() async { |
507 await super.test_const_reference_topLevelVariable_imported_withPrefix(); | 504 await super.test_const_reference_topLevelVariable_imported_withPrefix(); |
508 } | 505 } |
509 | 506 |
510 @failingTest | 507 @failingTest |
(...skipping 30 matching lines...) Expand all Loading... |
541 test_const_reference_unresolved_prefix1() async { | 538 test_const_reference_unresolved_prefix1() async { |
542 await super.test_const_reference_unresolved_prefix1(); | 539 await super.test_const_reference_unresolved_prefix1(); |
543 } | 540 } |
544 | 541 |
545 @failingTest | 542 @failingTest |
546 test_const_reference_unresolved_prefix2() async { | 543 test_const_reference_unresolved_prefix2() async { |
547 await super.test_const_reference_unresolved_prefix2(); | 544 await super.test_const_reference_unresolved_prefix2(); |
548 } | 545 } |
549 | 546 |
550 @failingTest | 547 @failingTest |
551 test_const_topLevel_binary() async { | 548 solo_test_const_topLevel_ifNull() async { |
552 await super.test_const_topLevel_binary(); | |
553 } | |
554 | |
555 @failingTest | |
556 test_const_topLevel_conditional() async { | |
557 await super.test_const_topLevel_conditional(); | |
558 } | |
559 | |
560 @failingTest | |
561 test_const_topLevel_identical() async { | |
562 await super.test_const_topLevel_identical(); | |
563 } | |
564 | |
565 @failingTest | |
566 test_const_topLevel_ifNull() async { | |
567 await super.test_const_topLevel_ifNull(); | 549 await super.test_const_topLevel_ifNull(); |
568 } | 550 } |
569 | 551 |
570 @failingTest | 552 @failingTest |
571 test_const_topLevel_prefix() async { | |
572 await super.test_const_topLevel_prefix(); | |
573 } | |
574 | |
575 @failingTest | |
576 test_const_topLevel_super() async { | 553 test_const_topLevel_super() async { |
577 await super.test_const_topLevel_super(); | 554 await super.test_const_topLevel_super(); |
578 } | 555 } |
579 | 556 |
580 @failingTest | 557 @failingTest |
581 test_const_topLevel_this() async { | 558 test_const_topLevel_this() async { |
582 await super.test_const_topLevel_this(); | 559 await super.test_const_topLevel_this(); |
583 } | 560 } |
584 | 561 |
585 @failingTest | 562 @failingTest |
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2182 return _buildIdentifier(expr.targetReference, isGet: true); | 2159 return _buildIdentifier(expr.targetReference, isGet: true); |
2183 } | 2160 } |
2184 | 2161 |
2185 if (expr is kernel.PropertyGet) { | 2162 if (expr is kernel.PropertyGet) { |
2186 Expression target = build(expr.receiver); | 2163 Expression target = build(expr.receiver); |
2187 kernel.Reference reference = expr.interfaceTargetReference; | 2164 kernel.Reference reference = expr.interfaceTargetReference; |
2188 SimpleIdentifier identifier = _buildSimpleIdentifier(reference); | 2165 SimpleIdentifier identifier = _buildSimpleIdentifier(reference); |
2189 return AstTestFactory.propertyAccess(target, identifier); | 2166 return AstTestFactory.propertyAccess(target, identifier); |
2190 } | 2167 } |
2191 | 2168 |
| 2169 if (expr is kernel.ConditionalExpression) { |
| 2170 var condition = build(expr.condition); |
| 2171 var then = build(expr.then); |
| 2172 var otherwise = build(expr.otherwise); |
| 2173 return AstTestFactory.conditionalExpression(condition, then, otherwise); |
| 2174 } |
| 2175 |
| 2176 if (expr is kernel.Not) { |
| 2177 kernel.Expression kernelOperand = expr.operand; |
| 2178 var operand = build(kernelOperand); |
| 2179 return AstTestFactory.prefixExpression(TokenType.BANG, operand); |
| 2180 } |
| 2181 |
| 2182 if (expr is kernel.LogicalExpression) { |
| 2183 var operator = _toBinaryOperatorTokenType(expr.operator); |
| 2184 var left = build(expr.left); |
| 2185 var right = build(expr.right); |
| 2186 return AstTestFactory.binaryExpression(left, operator, right); |
| 2187 } |
| 2188 |
| 2189 if (expr is kernel.MethodInvocation) { |
| 2190 kernel.Member member = expr.interfaceTarget; |
| 2191 if (member is kernel.Procedure) { |
| 2192 if (member.kind == kernel.ProcedureKind.Operator) { |
| 2193 var left = build(expr.receiver); |
| 2194 String operatorName = expr.name.name; |
| 2195 List<kernel.Expression> args = expr.arguments.positional; |
| 2196 if (args.isEmpty) { |
| 2197 if (operatorName == 'unary-') { |
| 2198 return AstTestFactory.prefixExpression(TokenType.MINUS, left); |
| 2199 } |
| 2200 if (operatorName == '~') { |
| 2201 return AstTestFactory.prefixExpression(TokenType.TILDE, left); |
| 2202 } |
| 2203 } else if (args.length == 1) { |
| 2204 var operator = _toBinaryOperatorTokenType(operatorName); |
| 2205 var right = build(args.single); |
| 2206 return AstTestFactory.binaryExpression(left, operator, right); |
| 2207 } |
| 2208 } |
| 2209 } |
| 2210 } |
| 2211 |
2192 // TODO(scheglov): complete getExpression | 2212 // TODO(scheglov): complete getExpression |
2193 throw new UnimplementedError('kernel: (${expr.runtimeType}) $expr'); | 2213 throw new UnimplementedError('kernel: (${expr.runtimeType}) $expr'); |
2194 } | 2214 } |
2195 | 2215 |
2196 Expression _buildIdentifier(kernel.Reference reference, {bool isGet: false}) { | 2216 Expression _buildIdentifier(kernel.Reference reference, {bool isGet: false}) { |
2197 Element element = _getElement(reference); | 2217 Element element = _getElement(reference); |
2198 if (isGet && element is PropertyInducingElement) { | 2218 if (isGet && element is PropertyInducingElement) { |
2199 element = (element as PropertyInducingElement).getter; | 2219 element = (element as PropertyInducingElement).getter; |
2200 } | 2220 } |
2201 SimpleIdentifier property = AstTestFactory.identifier3(element.displayName) | 2221 SimpleIdentifier property = AstTestFactory.identifier3(element.displayName) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 return _context._getElement(reference?.canonicalName); | 2277 return _context._getElement(reference?.canonicalName); |
2258 } | 2278 } |
2259 | 2279 |
2260 InterpolationElement _newInterpolationElement(Expression expr) { | 2280 InterpolationElement _newInterpolationElement(Expression expr) { |
2261 if (expr is SimpleStringLiteral) { | 2281 if (expr is SimpleStringLiteral) { |
2262 return astFactory.interpolationString(expr.literal, expr.value); | 2282 return astFactory.interpolationString(expr.literal, expr.value); |
2263 } else { | 2283 } else { |
2264 return AstTestFactory.interpolationExpression(expr); | 2284 return AstTestFactory.interpolationExpression(expr); |
2265 } | 2285 } |
2266 } | 2286 } |
| 2287 |
| 2288 /// Return the [TokenType] for the given operator [name]. |
| 2289 TokenType _toBinaryOperatorTokenType(String name) { |
| 2290 if (name == '==') return TokenType.EQ_EQ; |
| 2291 if (name == '&&') return TokenType.AMPERSAND_AMPERSAND; |
| 2292 if (name == '||') return TokenType.BAR_BAR; |
| 2293 if (name == '^') return TokenType.CARET; |
| 2294 if (name == '&') return TokenType.AMPERSAND; |
| 2295 if (name == '|') return TokenType.BAR; |
| 2296 if (name == '>>') return TokenType.GT_GT; |
| 2297 if (name == '<<') return TokenType.LT_LT; |
| 2298 if (name == '+') return TokenType.PLUS; |
| 2299 if (name == '-') return TokenType.MINUS; |
| 2300 if (name == '*') return TokenType.STAR; |
| 2301 if (name == '/') return TokenType.SLASH; |
| 2302 if (name == '~/') return TokenType.TILDE_SLASH; |
| 2303 if (name == '%') return TokenType.PERCENT; |
| 2304 if (name == '>') return TokenType.GT; |
| 2305 if (name == '<') return TokenType.LT; |
| 2306 if (name == '>=') return TokenType.GT_EQ; |
| 2307 if (name == '<=') return TokenType.LT_EQ; |
| 2308 if (name == 'unary-') return TokenType.MINUS; |
| 2309 throw new ArgumentError(name); |
| 2310 } |
2267 } | 2311 } |
2268 | 2312 |
2269 class _FileSystemAdaptor implements FileSystem { | 2313 class _FileSystemAdaptor implements FileSystem { |
2270 final ResourceProvider provider; | 2314 final ResourceProvider provider; |
2271 | 2315 |
2272 _FileSystemAdaptor(this.provider); | 2316 _FileSystemAdaptor(this.provider); |
2273 | 2317 |
2274 @override | 2318 @override |
2275 FileSystemEntity entityForUri(Uri uri) { | 2319 FileSystemEntity entityForUri(Uri uri) { |
2276 if (uri.isScheme('file')) { | 2320 if (uri.isScheme('file')) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2352 | 2396 |
2353 // If the parent is the root, then this name is a library. | 2397 // If the parent is the root, then this name is a library. |
2354 if (parentName.isRoot) { | 2398 if (parentName.isRoot) { |
2355 return _resynthesizer.getLibrary(name.name); | 2399 return _resynthesizer.getLibrary(name.name); |
2356 } | 2400 } |
2357 | 2401 |
2358 // Skip qualifiers. | 2402 // Skip qualifiers. |
2359 bool isGetter = false; | 2403 bool isGetter = false; |
2360 bool isSetter = false; | 2404 bool isSetter = false; |
2361 bool isField = false; | 2405 bool isField = false; |
| 2406 bool isMethod = false; |
2362 if (parentName.name == '@getters') { | 2407 if (parentName.name == '@getters') { |
2363 isGetter = true; | 2408 isGetter = true; |
2364 parentName = parentName.parent; | 2409 parentName = parentName.parent; |
2365 } else if (parentName.name == '@setters') { | 2410 } else if (parentName.name == '@setters') { |
2366 isSetter = true; | 2411 isSetter = true; |
2367 parentName = parentName.parent; | 2412 parentName = parentName.parent; |
2368 } else if (parentName.name == '@fields') { | 2413 } else if (parentName.name == '@fields') { |
2369 isField = true; | 2414 isField = true; |
2370 parentName = parentName.parent; | 2415 parentName = parentName.parent; |
| 2416 } else if (parentName.name == '@methods') { |
| 2417 isMethod = true; |
| 2418 parentName = parentName.parent; |
2371 } | 2419 } |
2372 | 2420 |
2373 ElementImpl parentElement = _getElement(parentName); | 2421 ElementImpl parentElement = _getElement(parentName); |
2374 if (parentElement == null) return null; | 2422 if (parentElement == null) return null; |
2375 | 2423 |
2376 // Search in units of the library. | 2424 // Search in units of the library. |
2377 if (parentElement is LibraryElementImpl) { | 2425 if (parentElement is LibraryElementImpl) { |
2378 for (CompilationUnitElement unit in parentElement.units) { | 2426 for (CompilationUnitElement unit in parentElement.units) { |
2379 CompilationUnitElementImpl unitImpl = unit; | 2427 CompilationUnitElementImpl unitImpl = unit; |
2380 ElementImpl child = unitImpl.getChild(name.name); | 2428 ElementImpl child = unitImpl.getChild(name.name); |
2381 if (child != null) { | 2429 if (child != null) { |
2382 return child; | 2430 return child; |
2383 } | 2431 } |
2384 } | 2432 } |
2385 return null; | 2433 return null; |
2386 } | 2434 } |
2387 | 2435 |
2388 // Search in the class. | 2436 // Search in the class. |
2389 if (parentElement is ClassElementImpl) { | 2437 if (parentElement is ClassElementImpl) { |
2390 if (isGetter) { | 2438 if (isGetter) { |
2391 return parentElement.getGetter(name.name) as ElementImpl; | 2439 return parentElement.getGetter(name.name) as ElementImpl; |
2392 } else if (isSetter) { | 2440 } else if (isSetter) { |
2393 return parentElement.getSetter(name.name) as ElementImpl; | 2441 return parentElement.getSetter(name.name) as ElementImpl; |
2394 } else if (isField) { | 2442 } else if (isField) { |
2395 return parentElement.getField(name.name) as ElementImpl; | 2443 return parentElement.getField(name.name) as ElementImpl; |
| 2444 } else if (isMethod) { |
| 2445 return parentElement.getMethod(name.name) as ElementImpl; |
2396 } | 2446 } |
2397 return null; | 2447 return null; |
2398 } | 2448 } |
2399 | 2449 |
2400 throw new UnimplementedError('Should not be reached.'); | 2450 throw new UnimplementedError('Should not be reached.'); |
2401 } | 2451 } |
2402 | 2452 |
2403 InterfaceType _getInterfaceType( | 2453 InterfaceType _getInterfaceType( |
2404 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) { | 2454 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) { |
2405 var libraryName = className.parent; | 2455 var libraryName = className.parent; |
2406 var libraryElement = _resynthesizer.getLibrary(libraryName.name); | 2456 var libraryElement = _resynthesizer.getLibrary(libraryName.name); |
2407 ClassElementImpl classElement = libraryElement.getType(className.name); | 2457 ClassElementImpl classElement = libraryElement.getType(className.name); |
2408 | 2458 |
2409 if (kernelArguments.isEmpty) { | 2459 if (kernelArguments.isEmpty) { |
2410 return classElement.type; | 2460 return classElement.type; |
2411 } | 2461 } |
2412 | 2462 |
2413 return new InterfaceTypeImpl.elementWithNameAndArgs( | 2463 return new InterfaceTypeImpl.elementWithNameAndArgs( |
2414 classElement, classElement.name, () { | 2464 classElement, classElement.name, () { |
2415 List<DartType> arguments = kernelArguments | 2465 List<DartType> arguments = kernelArguments |
2416 .map((kernel.DartType k) => getType(classElement, k)) | 2466 .map((kernel.DartType k) => getType(classElement, k)) |
2417 .toList(growable: false); | 2467 .toList(growable: false); |
2418 return arguments; | 2468 return arguments; |
2419 }); | 2469 }); |
2420 } | 2470 } |
2421 } | 2471 } |
2422 | 2472 |
2423 class _KernelResynthesizer { | 2473 class _KernelResynthesizer { |
2424 final AnalysisContext _analysisContext; | 2474 final AnalysisContext _analysisContext; |
| 2475 final kernel.TypeEnvironment types; |
2425 final Map<String, kernel.Library> _kernelMap; | 2476 final Map<String, kernel.Library> _kernelMap; |
2426 final Map<String, LibraryElementImpl> _libraryMap = {}; | 2477 final Map<String, LibraryElementImpl> _libraryMap = {}; |
2427 | 2478 |
2428 /** | 2479 /** |
2429 * Cache of [Source] objects that have already been converted from URIs. | 2480 * Cache of [Source] objects that have already been converted from URIs. |
2430 */ | 2481 */ |
2431 final Map<String, Source> _sources = <String, Source>{}; | 2482 final Map<String, Source> _sources = <String, Source>{}; |
2432 | 2483 |
2433 _KernelResynthesizer(this._analysisContext, this._kernelMap); | 2484 _KernelResynthesizer(this._analysisContext, this.types, this._kernelMap); |
2434 | 2485 |
2435 LibraryElementImpl getLibrary(String uriStr) { | 2486 LibraryElementImpl getLibrary(String uriStr) { |
2436 return _libraryMap.putIfAbsent(uriStr, () { | 2487 return _libraryMap.putIfAbsent(uriStr, () { |
2437 var kernel = _kernelMap[uriStr]; | 2488 var kernel = _kernelMap[uriStr]; |
2438 if (kernel == null) return null; | 2489 if (kernel == null) return null; |
2439 | 2490 |
2440 var libraryContext = | 2491 var libraryContext = |
2441 new _KernelLibraryResynthesizerContextImpl(this, kernel); | 2492 new _KernelLibraryResynthesizerContextImpl(this, kernel); |
2442 Source librarySource = _getSource(uriStr); | 2493 Source librarySource = _getSource(uriStr); |
2443 LibraryElementImpl libraryElement = | 2494 LibraryElementImpl libraryElement = |
2444 new LibraryElementImpl.forKernel(_analysisContext, libraryContext); | 2495 new LibraryElementImpl.forKernel(_analysisContext, libraryContext); |
2445 CompilationUnitElementImpl definingUnit = | 2496 CompilationUnitElementImpl definingUnit = |
2446 libraryElement.definingCompilationUnit; | 2497 libraryElement.definingCompilationUnit; |
2447 definingUnit.source = librarySource; | 2498 definingUnit.source = librarySource; |
2448 definingUnit.librarySource = librarySource; | 2499 definingUnit.librarySource = librarySource; |
2449 return libraryElement; | 2500 return libraryElement; |
2450 }); | 2501 }); |
2451 } | 2502 } |
2452 | 2503 |
2453 /** | 2504 /** |
2454 * Get the [Source] object for the given [uri]. | 2505 * Get the [Source] object for the given [uri]. |
2455 */ | 2506 */ |
2456 Source _getSource(String uri) { | 2507 Source _getSource(String uri) { |
2457 return _sources.putIfAbsent( | 2508 return _sources.putIfAbsent( |
2458 uri, () => _analysisContext.sourceFactory.forUri(uri)); | 2509 uri, () => _analysisContext.sourceFactory.forUri(uri)); |
2459 } | 2510 } |
2460 } | 2511 } |
OLD | NEW |