| 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/element/element.dart'; |
| 11 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
| 12 import 'package:analyzer/file_system/file_system.dart'; | 13 import 'package:analyzer/file_system/file_system.dart'; |
| 13 import 'package:analyzer/file_system/memory_file_system.dart'; | 14 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 14 import 'package:analyzer/src/dart/element/element.dart'; | 15 import 'package:analyzer/src/dart/element/element.dart'; |
| 15 import 'package:analyzer/src/dart/element/type.dart'; | 16 import 'package:analyzer/src/dart/element/type.dart'; |
| 16 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 17 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| 17 import 'package:analyzer/src/generated/source.dart'; | 18 import 'package:analyzer/src/generated/source.dart'; |
| 18 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; | 19 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; |
| 19 import 'package:analyzer/src/summary/resynthesize.dart'; | 20 import 'package:analyzer/src/summary/resynthesize.dart'; |
| 20 import 'package:front_end/file_system.dart'; | 21 import 'package:front_end/file_system.dart'; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 35 defineReflectiveSuite(() { | 36 defineReflectiveSuite(() { |
| 36 defineReflectiveTests(ResynthesizeKernelStrongTest); | 37 defineReflectiveTests(ResynthesizeKernelStrongTest); |
| 37 }); | 38 }); |
| 38 } | 39 } |
| 39 | 40 |
| 40 @reflectiveTest | 41 @reflectiveTest |
| 41 class ResynthesizeKernelStrongTest extends ResynthesizeTest { | 42 class ResynthesizeKernelStrongTest extends ResynthesizeTest { |
| 42 final resourceProvider = new MemoryResourceProvider(context: pathos.posix); | 43 final resourceProvider = new MemoryResourceProvider(context: pathos.posix); |
| 43 | 44 |
| 44 @override | 45 @override |
| 46 bool get isSharedFrontEnd => true; |
| 47 |
| 48 @override |
| 45 bool get isStrongMode => true; | 49 bool get isStrongMode => true; |
| 46 | 50 |
| 47 @override | 51 @override |
| 48 Source addLibrarySource(String path, String content) { | 52 Source addLibrarySource(String path, String content) { |
| 49 path = resourceProvider.convertPath(path); | 53 path = resourceProvider.convertPath(path); |
| 50 File file = resourceProvider.newFile(path, content); | 54 File file = resourceProvider.newFile(path, content); |
| 51 return file.createSource(); | 55 return file.createSource(); |
| 52 } | 56 } |
| 53 | 57 |
| 54 @override | 58 @override |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 test_class_documented_tripleSlash() async { | 221 test_class_documented_tripleSlash() async { |
| 218 await super.test_class_documented_tripleSlash(); | 222 await super.test_class_documented_tripleSlash(); |
| 219 } | 223 } |
| 220 | 224 |
| 221 @failingTest | 225 @failingTest |
| 222 test_class_documented_withLeadingNotDocumentation() async { | 226 test_class_documented_withLeadingNotDocumentation() async { |
| 223 await super.test_class_documented_withLeadingNotDocumentation(); | 227 await super.test_class_documented_withLeadingNotDocumentation(); |
| 224 } | 228 } |
| 225 | 229 |
| 226 @failingTest | 230 @failingTest |
| 227 test_class_field_const() async { | |
| 228 await super.test_class_field_const(); | |
| 229 } | |
| 230 | |
| 231 @failingTest | |
| 232 test_class_interfaces_unresolved() async { | 231 test_class_interfaces_unresolved() async { |
| 233 await super.test_class_interfaces_unresolved(); | 232 await super.test_class_interfaces_unresolved(); |
| 234 } | 233 } |
| 235 | 234 |
| 236 @failingTest | 235 @failingTest |
| 237 test_class_mixins() async { | 236 test_class_mixins() async { |
| 238 await super.test_class_mixins(); | 237 await super.test_class_mixins(); |
| 239 } | 238 } |
| 240 | 239 |
| 241 @failingTest | 240 @failingTest |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 test_const_invokeConstructor_unnamed_unresolved2() async { | 398 test_const_invokeConstructor_unnamed_unresolved2() async { |
| 400 await super.test_const_invokeConstructor_unnamed_unresolved2(); | 399 await super.test_const_invokeConstructor_unnamed_unresolved2(); |
| 401 } | 400 } |
| 402 | 401 |
| 403 @failingTest | 402 @failingTest |
| 404 test_const_invokeConstructor_unnamed_unresolved3() async { | 403 test_const_invokeConstructor_unnamed_unresolved3() async { |
| 405 await super.test_const_invokeConstructor_unnamed_unresolved3(); | 404 await super.test_const_invokeConstructor_unnamed_unresolved3(); |
| 406 } | 405 } |
| 407 | 406 |
| 408 @failingTest | 407 @failingTest |
| 409 test_const_length_ofClassConstField() async { | |
| 410 await super.test_const_length_ofClassConstField(); | |
| 411 } | |
| 412 | |
| 413 @failingTest | |
| 414 test_const_length_ofClassConstField_imported() async { | 408 test_const_length_ofClassConstField_imported() async { |
| 415 await super.test_const_length_ofClassConstField_imported(); | 409 await super.test_const_length_ofClassConstField_imported(); |
| 416 } | 410 } |
| 417 | 411 |
| 418 @failingTest | 412 @failingTest |
| 419 test_const_length_ofClassConstField_imported_withPrefix() async { | 413 test_const_length_ofClassConstField_imported_withPrefix() async { |
| 420 await super.test_const_length_ofClassConstField_imported_withPrefix(); | 414 await super.test_const_length_ofClassConstField_imported_withPrefix(); |
| 421 } | 415 } |
| 422 | 416 |
| 423 @failingTest | 417 @failingTest |
| 424 test_const_length_ofStringLiteral() async { | |
| 425 await super.test_const_length_ofStringLiteral(); | |
| 426 } | |
| 427 | |
| 428 @failingTest | |
| 429 test_const_length_ofTopLevelVariable() async { | |
| 430 await super.test_const_length_ofTopLevelVariable(); | |
| 431 } | |
| 432 | |
| 433 @failingTest | |
| 434 test_const_length_ofTopLevelVariable_imported() async { | 418 test_const_length_ofTopLevelVariable_imported() async { |
| 435 await super.test_const_length_ofTopLevelVariable_imported(); | 419 await super.test_const_length_ofTopLevelVariable_imported(); |
| 436 } | 420 } |
| 437 | 421 |
| 438 @failingTest | 422 @failingTest |
| 439 test_const_length_ofTopLevelVariable_imported_withPrefix() async { | 423 test_const_length_ofTopLevelVariable_imported_withPrefix() async { |
| 440 await super.test_const_length_ofTopLevelVariable_imported_withPrefix(); | 424 await super.test_const_length_ofTopLevelVariable_imported_withPrefix(); |
| 441 } | 425 } |
| 442 | 426 |
| 443 @failingTest | 427 @failingTest |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 test_field_documented() async { | 961 test_field_documented() async { |
| 978 await super.test_field_documented(); | 962 await super.test_field_documented(); |
| 979 } | 963 } |
| 980 | 964 |
| 981 @failingTest | 965 @failingTest |
| 982 test_field_formal_param_inferred_type_implicit() async { | 966 test_field_formal_param_inferred_type_implicit() async { |
| 983 await super.test_field_formal_param_inferred_type_implicit(); | 967 await super.test_field_formal_param_inferred_type_implicit(); |
| 984 } | 968 } |
| 985 | 969 |
| 986 @failingTest | 970 @failingTest |
| 987 test_field_propagatedType_const_noDep() async { | |
| 988 await super.test_field_propagatedType_const_noDep(); | |
| 989 } | |
| 990 | |
| 991 @failingTest | |
| 992 test_field_propagatedType_final_dep_inLib() async { | 971 test_field_propagatedType_final_dep_inLib() async { |
| 993 await super.test_field_propagatedType_final_dep_inLib(); | 972 await super.test_field_propagatedType_final_dep_inLib(); |
| 994 } | 973 } |
| 995 | 974 |
| 996 @failingTest | 975 @failingTest |
| 997 test_field_propagatedType_final_dep_inPart() async { | 976 test_field_propagatedType_final_dep_inPart() async { |
| 998 await super.test_field_propagatedType_final_dep_inPart(); | 977 await super.test_field_propagatedType_final_dep_inPart(); |
| 999 } | 978 } |
| 1000 | 979 |
| 1001 @failingTest | 980 @failingTest |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2165 @failingTest | 2144 @failingTest |
| 2166 test_variable_setterInPart_getterInPart() async { | 2145 test_variable_setterInPart_getterInPart() async { |
| 2167 await super.test_variable_setterInPart_getterInPart(); | 2146 await super.test_variable_setterInPart_getterInPart(); |
| 2168 } | 2147 } |
| 2169 } | 2148 } |
| 2170 | 2149 |
| 2171 /** | 2150 /** |
| 2172 * Builder of [Expression]s from [kernel.Expression]s. | 2151 * Builder of [Expression]s from [kernel.Expression]s. |
| 2173 */ | 2152 */ |
| 2174 class _ExprBuilder { | 2153 class _ExprBuilder { |
| 2154 final _KernelLibraryResynthesizerContextImpl _context; |
| 2155 |
| 2156 _ExprBuilder(this._context); |
| 2157 |
| 2175 Expression build(kernel.Expression expr) { | 2158 Expression build(kernel.Expression expr) { |
| 2176 if (expr is kernel.NullLiteral) { | 2159 if (expr is kernel.NullLiteral) { |
| 2177 return AstTestFactory.nullLiteral(); | 2160 return AstTestFactory.nullLiteral(); |
| 2178 } | 2161 } |
| 2179 if (expr is kernel.BoolLiteral) { | 2162 if (expr is kernel.BoolLiteral) { |
| 2180 return AstTestFactory.booleanLiteral(expr.value); | 2163 return AstTestFactory.booleanLiteral(expr.value); |
| 2181 } | 2164 } |
| 2182 if (expr is kernel.IntLiteral) { | 2165 if (expr is kernel.IntLiteral) { |
| 2183 return AstTestFactory.integer(expr.value); | 2166 return AstTestFactory.integer(expr.value); |
| 2184 } | 2167 } |
| 2185 if (expr is kernel.DoubleLiteral) { | 2168 if (expr is kernel.DoubleLiteral) { |
| 2186 return AstTestFactory.doubleLiteral(expr.value); | 2169 return AstTestFactory.doubleLiteral(expr.value); |
| 2187 } | 2170 } |
| 2188 if (expr is kernel.StringLiteral) { | 2171 if (expr is kernel.StringLiteral) { |
| 2189 return AstTestFactory.string2(expr.value); | 2172 return AstTestFactory.string2(expr.value); |
| 2190 } | 2173 } |
| 2191 if (expr is kernel.StringConcatenation) { | 2174 if (expr is kernel.StringConcatenation) { |
| 2192 List<InterpolationElement> elements = expr.expressions | 2175 List<InterpolationElement> elements = expr.expressions |
| 2193 .map(build) | 2176 .map(build) |
| 2194 .map(_newInterpolationElement) | 2177 .map(_newInterpolationElement) |
| 2195 .toList(growable: false); | 2178 .toList(growable: false); |
| 2196 return AstTestFactory.string(elements); | 2179 return AstTestFactory.string(elements); |
| 2197 } | 2180 } |
| 2198 if (expr is kernel.SymbolLiteral) { | 2181 if (expr is kernel.SymbolLiteral) { |
| 2199 List<String> components = expr.value.split('.').toList(); | 2182 List<String> components = expr.value.split('.').toList(); |
| 2200 return AstTestFactory.symbolLiteral(components); | 2183 return AstTestFactory.symbolLiteral(components); |
| 2201 } | 2184 } |
| 2185 if (expr is kernel.StaticGet) { |
| 2186 kernel.Reference reference = expr.targetReference; |
| 2187 Element element = _getElement(reference); |
| 2188 if (element is PropertyInducingElement) { |
| 2189 element = (element as PropertyInducingElement).getter; |
| 2190 } |
| 2191 SimpleIdentifier identifier = |
| 2192 AstTestFactory.identifier3(reference.canonicalName.name); |
| 2193 identifier.staticElement = element; |
| 2194 return identifier; |
| 2195 } |
| 2196 if (expr is kernel.PropertyGet) { |
| 2197 Expression target = build(expr.receiver); |
| 2198 SimpleIdentifier identifier = AstTestFactory.identifier3(expr.name.name); |
| 2199 ElementImpl element = _getElement(expr.interfaceTargetReference); |
| 2200 identifier.staticElement = element; |
| 2201 return AstTestFactory.propertyAccess(target, identifier); |
| 2202 } |
| 2202 // TODO(scheglov): complete getExpression | 2203 // TODO(scheglov): complete getExpression |
| 2203 throw new UnimplementedError('kernel: $expr'); | 2204 throw new UnimplementedError('kernel: (${expr.runtimeType}) $expr'); |
| 2205 } |
| 2206 |
| 2207 ElementImpl _getElement(kernel.Reference reference) { |
| 2208 return _context._getElement(reference?.canonicalName); |
| 2204 } | 2209 } |
| 2205 | 2210 |
| 2206 InterpolationElement _newInterpolationElement(Expression expr) { | 2211 InterpolationElement _newInterpolationElement(Expression expr) { |
| 2207 if (expr is SimpleStringLiteral) { | 2212 if (expr is SimpleStringLiteral) { |
| 2208 return astFactory.interpolationString(expr.literal, expr.value); | 2213 return astFactory.interpolationString(expr.literal, expr.value); |
| 2209 } else { | 2214 } else { |
| 2210 return AstTestFactory.interpolationExpression(expr); | 2215 return AstTestFactory.interpolationExpression(expr); |
| 2211 } | 2216 } |
| 2212 } | 2217 } |
| 2213 } | 2218 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2261 implements KernelLibraryResynthesizerContext { | 2266 implements KernelLibraryResynthesizerContext { |
| 2262 final _KernelResynthesizer _resynthesizer; | 2267 final _KernelResynthesizer _resynthesizer; |
| 2263 | 2268 |
| 2264 @override | 2269 @override |
| 2265 final kernel.Library library; | 2270 final kernel.Library library; |
| 2266 | 2271 |
| 2267 _KernelLibraryResynthesizerContextImpl(this._resynthesizer, this.library); | 2272 _KernelLibraryResynthesizerContextImpl(this._resynthesizer, this.library); |
| 2268 | 2273 |
| 2269 @override | 2274 @override |
| 2270 Expression getExpression(kernel.Expression expression) { | 2275 Expression getExpression(kernel.Expression expression) { |
| 2271 return new _ExprBuilder().build(expression); | 2276 return new _ExprBuilder(this).build(expression); |
| 2272 } | 2277 } |
| 2273 | 2278 |
| 2274 @override | 2279 @override |
| 2275 InterfaceType getInterfaceType( | 2280 InterfaceType getInterfaceType( |
| 2276 ElementImpl context, kernel.Supertype kernelType) { | 2281 ElementImpl context, kernel.Supertype kernelType) { |
| 2277 return _getInterfaceType( | 2282 return _getInterfaceType( |
| 2278 kernelType.className.canonicalName, kernelType.typeArguments); | 2283 kernelType.className.canonicalName, kernelType.typeArguments); |
| 2279 } | 2284 } |
| 2280 | 2285 |
| 2281 DartType getType(ElementImpl context, kernel.DartType kernelType) { | 2286 DartType getType(ElementImpl context, kernel.DartType kernelType) { |
| 2282 if (kernelType is kernel.DynamicType) return DynamicTypeImpl.instance; | 2287 if (kernelType is kernel.DynamicType) return DynamicTypeImpl.instance; |
| 2283 if (kernelType is kernel.InterfaceType) { | 2288 if (kernelType is kernel.InterfaceType) { |
| 2284 return _getInterfaceType( | 2289 return _getInterfaceType( |
| 2285 kernelType.className.canonicalName, kernelType.typeArguments); | 2290 kernelType.className.canonicalName, kernelType.typeArguments); |
| 2286 } | 2291 } |
| 2287 if (kernelType is kernel.VoidType) return VoidTypeImpl.instance; | 2292 if (kernelType is kernel.VoidType) return VoidTypeImpl.instance; |
| 2288 // TODO(scheglov) Support other kernel types. | 2293 // TODO(scheglov) Support other kernel types. |
| 2289 throw new UnimplementedError('For ${kernelType.runtimeType}'); | 2294 throw new UnimplementedError('For ${kernelType.runtimeType}'); |
| 2290 } | 2295 } |
| 2291 | 2296 |
| 2297 /** |
| 2298 * Return the [ElementImpl] that corresponds to the given [name], or `null` |
| 2299 * if the corresponding element cannot be found. |
| 2300 */ |
| 2301 ElementImpl _getElement(kernel.CanonicalName name) { |
| 2302 if (name == null) return null; |
| 2303 kernel.CanonicalName parentName = name.parent; |
| 2304 |
| 2305 // If the parent is the root, then this name is a library. |
| 2306 if (parentName.isRoot) { |
| 2307 return _resynthesizer.getLibrary(name.name); |
| 2308 } |
| 2309 |
| 2310 // Skip qualifiers. |
| 2311 bool isGetter = false; |
| 2312 bool isSetter = false; |
| 2313 bool isField = false; |
| 2314 if (parentName.name == '@getters') { |
| 2315 isGetter = true; |
| 2316 parentName = parentName.parent; |
| 2317 } else if (parentName.name == '@setters') { |
| 2318 isSetter = true; |
| 2319 parentName = parentName.parent; |
| 2320 } else if (parentName.name == '@fields') { |
| 2321 isField = true; |
| 2322 parentName = parentName.parent; |
| 2323 } |
| 2324 |
| 2325 ElementImpl parentElement = _getElement(parentName); |
| 2326 if (parentElement == null) return null; |
| 2327 |
| 2328 // Search in units of the library. |
| 2329 if (parentElement is LibraryElementImpl) { |
| 2330 for (CompilationUnitElement unit in parentElement.units) { |
| 2331 CompilationUnitElementImpl unitImpl = unit; |
| 2332 ElementImpl child = unitImpl.getChild(name.name); |
| 2333 if (child != null) { |
| 2334 return child; |
| 2335 } |
| 2336 } |
| 2337 return null; |
| 2338 } |
| 2339 |
| 2340 // Search in the class. |
| 2341 if (parentElement is ClassElementImpl) { |
| 2342 if (isGetter) { |
| 2343 return parentElement.getGetter(name.name) as ElementImpl; |
| 2344 } else if (isSetter) { |
| 2345 return parentElement.getSetter(name.name) as ElementImpl; |
| 2346 } else if (isField) { |
| 2347 return parentElement.getField(name.name) as ElementImpl; |
| 2348 } |
| 2349 return null; |
| 2350 } |
| 2351 |
| 2352 throw new UnimplementedError('Should not be reached.'); |
| 2353 } |
| 2354 |
| 2292 InterfaceType _getInterfaceType( | 2355 InterfaceType _getInterfaceType( |
| 2293 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) { | 2356 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) { |
| 2294 var libraryName = className.parent; | 2357 var libraryName = className.parent; |
| 2295 var libraryElement = _resynthesizer.getLibrary(libraryName.name); | 2358 var libraryElement = _resynthesizer.getLibrary(libraryName.name); |
| 2296 ClassElementImpl classElement = libraryElement.getType(className.name); | 2359 ClassElementImpl classElement = libraryElement.getType(className.name); |
| 2297 | 2360 |
| 2298 if (kernelArguments.isEmpty) { | 2361 if (kernelArguments.isEmpty) { |
| 2299 return classElement.type; | 2362 return classElement.type; |
| 2300 } | 2363 } |
| 2301 | 2364 |
| 2302 return new InterfaceTypeImpl.elementWithNameAndArgs( | 2365 return new InterfaceTypeImpl.elementWithNameAndArgs( |
| 2303 classElement, classElement.name, () { | 2366 classElement, classElement.name, () { |
| 2304 List<DartType> arguments = kernelArguments | 2367 List<DartType> arguments = kernelArguments |
| 2305 .map((kernel.DartType k) => getType(classElement, k)) | 2368 .map((kernel.DartType k) => getType(classElement, k)) |
| 2306 .toList(growable: false); | 2369 .toList(growable: false); |
| 2307 return arguments; | 2370 return arguments; |
| 2308 }); | 2371 }); |
| 2309 } | 2372 } |
| 2310 } | 2373 } |
| 2311 | 2374 |
| 2312 class _KernelResynthesizer { | 2375 class _KernelResynthesizer { |
| 2313 final AnalysisContext _analysisContext; | 2376 final AnalysisContext _analysisContext; |
| 2314 final Map<String, kernel.Library> _kernelMap; | 2377 final Map<String, kernel.Library> _kernelMap; |
| 2315 final Map<String, LibraryElementImpl> _libraryMap = {}; | 2378 final Map<String, LibraryElementImpl> _libraryMap = {}; |
| 2316 | 2379 |
| 2380 /** |
| 2381 * Cache of [Source] objects that have already been converted from URIs. |
| 2382 */ |
| 2383 final Map<String, Source> _sources = <String, Source>{}; |
| 2384 |
| 2317 _KernelResynthesizer(this._analysisContext, this._kernelMap); | 2385 _KernelResynthesizer(this._analysisContext, this._kernelMap); |
| 2318 | 2386 |
| 2319 LibraryElementImpl getLibrary(String uriStr) { | 2387 LibraryElementImpl getLibrary(String uriStr) { |
| 2320 return _libraryMap.putIfAbsent(uriStr, () { | 2388 return _libraryMap.putIfAbsent(uriStr, () { |
| 2321 var kernel = _kernelMap[uriStr]; | 2389 var kernel = _kernelMap[uriStr]; |
| 2322 if (kernel == null) return null; | 2390 if (kernel == null) return null; |
| 2391 |
| 2323 var libraryContext = | 2392 var libraryContext = |
| 2324 new _KernelLibraryResynthesizerContextImpl(this, kernel); | 2393 new _KernelLibraryResynthesizerContextImpl(this, kernel); |
| 2325 return new LibraryElementImpl.forKernel(_analysisContext, libraryContext); | 2394 Source librarySource = _getSource(uriStr); |
| 2395 LibraryElementImpl libraryElement = |
| 2396 new LibraryElementImpl.forKernel(_analysisContext, libraryContext); |
| 2397 CompilationUnitElementImpl definingUnit = |
| 2398 libraryElement.definingCompilationUnit; |
| 2399 definingUnit.source = librarySource; |
| 2400 definingUnit.librarySource = librarySource; |
| 2401 return libraryElement; |
| 2326 }); | 2402 }); |
| 2327 } | 2403 } |
| 2404 |
| 2405 /** |
| 2406 * Get the [Source] object for the given [uri]. |
| 2407 */ |
| 2408 Source _getSource(String uri) { |
| 2409 return _sources.putIfAbsent( |
| 2410 uri, () => _analysisContext.sourceFactory.forUri(uri)); |
| 2411 } |
| 2328 } | 2412 } |
| OLD | NEW |