| 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 summary_resynthesizer; | 5 library summary_resynthesizer; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 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/src/dart/element/element.dart'; | 14 import 'package:analyzer/src/dart/element/element.dart'; |
| 15 import 'package:analyzer/src/dart/element/handle.dart'; | 15 import 'package:analyzer/src/dart/element/handle.dart'; |
| 16 import 'package:analyzer/src/dart/element/member.dart'; | 16 import 'package:analyzer/src/dart/element/member.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'; | 18 import 'package:analyzer/src/generated/engine.dart'; |
| 19 import 'package:analyzer/src/generated/resolver.dart'; | 19 import 'package:analyzer/src/generated/resolver.dart'; |
| 20 import 'package:analyzer/src/generated/source_io.dart'; | 20 import 'package:analyzer/src/generated/source_io.dart'; |
| 21 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; | 21 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; |
| 22 import 'package:analyzer/src/generated/testing/token_factory.dart'; | 22 import 'package:analyzer/src/generated/testing/token_factory.dart'; |
| 23 import 'package:analyzer/src/summary/format.dart'; | 23 import 'package:analyzer/src/summary/format.dart'; |
| 24 import 'package:analyzer/src/summary/idl.dart'; | 24 import 'package:analyzer/src/summary/idl.dart'; |
| 25 import 'package:analyzer/src/summary/summary_sdk.dart'; |
| 25 | 26 |
| 26 /** | 27 /** |
| 27 * Implementation of [ElementResynthesizer] used when resynthesizing an element | 28 * Implementation of [ElementResynthesizer] used when resynthesizing an element |
| 28 * model from summaries. | 29 * model from summaries. |
| 29 */ | 30 */ |
| 30 abstract class SummaryResynthesizer extends ElementResynthesizer { | 31 abstract class SummaryResynthesizer extends ElementResynthesizer { |
| 31 /** | 32 /** |
| 32 * The parent [SummaryResynthesizer] which is asked to resynthesize elements | |
| 33 * and get summaries before this resynthesizer attempts to do this. | |
| 34 * Can be `null`. | |
| 35 */ | |
| 36 final SummaryResynthesizer parent; | |
| 37 | |
| 38 /** | |
| 39 * Source factory used to convert URIs to [Source] objects. | 33 * Source factory used to convert URIs to [Source] objects. |
| 40 */ | 34 */ |
| 41 final SourceFactory sourceFactory; | 35 final SourceFactory sourceFactory; |
| 42 | 36 |
| 43 /** | 37 /** |
| 44 * Cache of [Source] objects that have already been converted from URIs. | 38 * Cache of [Source] objects that have already been converted from URIs. |
| 45 */ | 39 */ |
| 46 final Map<String, Source> _sources = <String, Source>{}; | 40 final Map<String, Source> _sources = <String, Source>{}; |
| 47 | 41 |
| 48 /** | 42 /** |
| 49 * The [TypeProvider] used to obtain core types (such as Object, int, List, | 43 * The [TypeProvider] used to obtain SDK types during resynthesis. |
| 50 * and dynamic) during resynthesis. | |
| 51 */ | 44 */ |
| 52 final TypeProvider typeProvider; | 45 TypeProvider _typeProvider; |
| 53 | 46 |
| 54 /** | 47 /** |
| 55 * Indicates whether the summary should be resynthesized assuming strong mode | 48 * Indicates whether the summary should be resynthesized assuming strong mode |
| 56 * semantics. | 49 * semantics. |
| 57 */ | 50 */ |
| 58 final bool strongMode; | 51 final bool strongMode; |
| 59 | 52 |
| 60 /** | 53 /** |
| 61 * Map of compilation units resynthesized from summaries. The two map keys | 54 * Map of compilation units resynthesized from summaries. The two map keys |
| 62 * are the first two elements of the element's location (the library URI and | 55 * are the first two elements of the element's location (the library URI and |
| (...skipping 10 matching lines...) Expand all Loading... |
| 73 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = | 66 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = |
| 74 <String, Map<String, Map<String, Element>>>{}; | 67 <String, Map<String, Map<String, Element>>>{}; |
| 75 | 68 |
| 76 /** | 69 /** |
| 77 * Map of libraries which have been resynthesized from summaries. The map | 70 * Map of libraries which have been resynthesized from summaries. The map |
| 78 * key is the library URI. | 71 * key is the library URI. |
| 79 */ | 72 */ |
| 80 final Map<String, LibraryElement> _resynthesizedLibraries = | 73 final Map<String, LibraryElement> _resynthesizedLibraries = |
| 81 <String, LibraryElement>{}; | 74 <String, LibraryElement>{}; |
| 82 | 75 |
| 83 SummaryResynthesizer(this.parent, AnalysisContext context, this.typeProvider, | 76 SummaryResynthesizer( |
| 84 this.sourceFactory, this.strongMode) | 77 AnalysisContext context, this.sourceFactory, this.strongMode) |
| 85 : super(context); | 78 : super(context) { |
| 79 _buildTypeProvider(); |
| 80 } |
| 86 | 81 |
| 87 /** | 82 /** |
| 88 * Number of libraries that have been resynthesized so far. | 83 * Number of libraries that have been resynthesized so far. |
| 89 */ | 84 */ |
| 90 int get resynthesisCount => _resynthesizedLibraries.length; | 85 int get resynthesisCount => _resynthesizedLibraries.length; |
| 91 | 86 |
| 92 /** | 87 /** |
| 93 * Perform delayed finalization of the `dart:core` and `dart:async` libraries. | 88 * The [TypeProvider] used to obtain SDK types during resynthesis. |
| 94 */ | 89 */ |
| 95 void finalizeCoreAsyncLibraries() { | 90 TypeProvider get typeProvider => _typeProvider; |
| 96 (_resynthesizedLibraries['dart:core'] as LibraryElementImpl) | |
| 97 .createLoadLibraryFunction(typeProvider); | |
| 98 (_resynthesizedLibraries['dart:async'] as LibraryElementImpl) | |
| 99 .createLoadLibraryFunction(typeProvider); | |
| 100 } | |
| 101 | 91 |
| 102 @override | 92 @override |
| 103 Element getElement(ElementLocation location) { | 93 Element getElement(ElementLocation location) { |
| 104 List<String> components = location.components; | 94 List<String> components = location.components; |
| 105 String libraryUri = components[0]; | 95 String libraryUri = components[0]; |
| 106 // Ask the parent resynthesizer. | |
| 107 if (parent != null && parent._hasLibrarySummary(libraryUri)) { | |
| 108 return parent.getElement(location); | |
| 109 } | |
| 110 // Resynthesize locally. | 96 // Resynthesize locally. |
| 111 if (components.length == 1) { | 97 if (components.length == 1) { |
| 112 return getLibraryElement(libraryUri); | 98 return getLibraryElement(libraryUri); |
| 113 } else if (components.length == 2) { | 99 } else if (components.length == 2) { |
| 114 Map<String, CompilationUnitElement> libraryMap = | 100 Map<String, CompilationUnitElement> libraryMap = |
| 115 _resynthesizedUnits[libraryUri]; | 101 _resynthesizedUnits[libraryUri]; |
| 116 if (libraryMap == null) { | 102 if (libraryMap == null) { |
| 117 getLibraryElement(libraryUri); | 103 getLibraryElement(libraryUri); |
| 118 libraryMap = _resynthesizedUnits[libraryUri]; | 104 libraryMap = _resynthesizedUnits[libraryUri]; |
| 119 assert(libraryMap != null); | 105 assert(libraryMap != null); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 } else { | 182 } else { |
| 197 throw new UnimplementedError(location.toString()); | 183 throw new UnimplementedError(location.toString()); |
| 198 } | 184 } |
| 199 } | 185 } |
| 200 | 186 |
| 201 /** | 187 /** |
| 202 * Get the [LibraryElement] for the given [uri], resynthesizing it if it | 188 * Get the [LibraryElement] for the given [uri], resynthesizing it if it |
| 203 * hasn't been resynthesized already. | 189 * hasn't been resynthesized already. |
| 204 */ | 190 */ |
| 205 LibraryElement getLibraryElement(String uri) { | 191 LibraryElement getLibraryElement(String uri) { |
| 206 if (parent != null && parent._hasLibrarySummary(uri)) { | |
| 207 return parent.getLibraryElement(uri); | |
| 208 } | |
| 209 return _resynthesizedLibraries.putIfAbsent(uri, () { | 192 return _resynthesizedLibraries.putIfAbsent(uri, () { |
| 210 LinkedLibrary serializedLibrary = _getLinkedSummaryOrNull(uri); | 193 LinkedLibrary serializedLibrary = getLinkedSummary(uri); |
| 211 Source librarySource = _getSource(uri); | 194 Source librarySource = _getSource(uri); |
| 212 if (serializedLibrary == null) { | 195 if (serializedLibrary == null) { |
| 213 LibraryElementImpl libraryElement = | 196 LibraryElementImpl libraryElement = |
| 214 new LibraryElementImpl(context, '', -1, 0); | 197 new LibraryElementImpl(context, '', -1, 0); |
| 215 libraryElement.isSynthetic = true; | 198 libraryElement.isSynthetic = true; |
| 216 CompilationUnitElementImpl unitElement = | 199 CompilationUnitElementImpl unitElement = |
| 217 new CompilationUnitElementImpl(librarySource.shortName); | 200 new CompilationUnitElementImpl(librarySource.shortName); |
| 218 libraryElement.definingCompilationUnit = unitElement; | 201 libraryElement.definingCompilationUnit = unitElement; |
| 219 unitElement.source = librarySource; | 202 unitElement.source = librarySource; |
| 220 unitElement.librarySource = librarySource; | 203 unitElement.librarySource = librarySource; |
| 221 libraryElement.createLoadLibraryFunction(typeProvider); | 204 libraryElement.createLoadLibraryFunction(typeProvider); |
| 222 libraryElement.publicNamespace = new Namespace({}); | 205 libraryElement.publicNamespace = new Namespace({}); |
| 223 libraryElement.exportNamespace = new Namespace({}); | 206 libraryElement.exportNamespace = new Namespace({}); |
| 224 return libraryElement; | 207 return libraryElement; |
| 225 } | 208 } |
| 226 UnlinkedUnit unlinkedSummary = _getUnlinkedSummaryOrNull(uri); | 209 UnlinkedUnit unlinkedSummary = getUnlinkedSummary(uri); |
| 227 if (unlinkedSummary == null) { | 210 if (unlinkedSummary == null) { |
| 228 throw new StateError('Unable to find unlinked summary: $uri'); | 211 throw new StateError('Unable to find unlinked summary: $uri'); |
| 229 } | 212 } |
| 230 List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[unlinkedSummary]; | 213 List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[unlinkedSummary]; |
| 231 for (String part in serializedUnits[0].publicNamespace.parts) { | 214 for (String part in serializedUnits[0].publicNamespace.parts) { |
| 232 Source partSource = sourceFactory.resolveUri(librarySource, part); | 215 Source partSource = sourceFactory.resolveUri(librarySource, part); |
| 233 if (partSource == null) { | 216 if (partSource == null) { |
| 234 serializedUnits.add(null); | 217 serializedUnits.add(null); |
| 235 } else { | 218 } else { |
| 236 String partAbsUri = partSource.uri.toString(); | 219 String partAbsUri = partSource.uri.toString(); |
| 237 serializedUnits.add(_getUnlinkedSummaryOrNull(partAbsUri) ?? | 220 serializedUnits.add(getUnlinkedSummary(partAbsUri) ?? |
| 238 new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder())); | 221 new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder())); |
| 239 } | 222 } |
| 240 } | 223 } |
| 241 _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer( | 224 _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer( |
| 242 this, serializedLibrary, serializedUnits, librarySource); | 225 this, serializedLibrary, serializedUnits, librarySource); |
| 243 LibraryElement library = libraryResynthesizer.buildLibrary(); | 226 LibraryElement library = libraryResynthesizer.buildLibrary(); |
| 244 _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits; | 227 _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits; |
| 245 return library; | 228 return library; |
| 246 }); | 229 }); |
| 247 } | 230 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 260 */ | 243 */ |
| 261 UnlinkedUnit getUnlinkedSummary(String uri); | 244 UnlinkedUnit getUnlinkedSummary(String uri); |
| 262 | 245 |
| 263 /** | 246 /** |
| 264 * Return `true` if this resynthesizer can provide summaries of the libraries | 247 * Return `true` if this resynthesizer can provide summaries of the libraries |
| 265 * with the given [uri]. Caller has already checked that | 248 * with the given [uri]. Caller has already checked that |
| 266 * `parent.hasLibrarySummary(uri)` returns `false`. | 249 * `parent.hasLibrarySummary(uri)` returns `false`. |
| 267 */ | 250 */ |
| 268 bool hasLibrarySummary(String uri); | 251 bool hasLibrarySummary(String uri); |
| 269 | 252 |
| 270 /** | 253 void _buildTypeProvider() { |
| 271 * Return the [LinkedLibrary] for the given [uri] or return `null` if it | 254 var coreLibrary = getLibraryElement('dart:core') as LibraryElementImpl; |
| 272 * could not be found. | 255 var asyncLibrary = getLibraryElement('dart:async') as LibraryElementImpl; |
| 273 */ | 256 SummaryTypeProvider summaryTypeProvider = new SummaryTypeProvider(); |
| 274 LinkedLibrary _getLinkedSummaryOrNull(String uri) { | 257 summaryTypeProvider.initializeCore(coreLibrary); |
| 275 if (parent != null && parent._hasLibrarySummary(uri)) { | 258 summaryTypeProvider.initializeAsync(asyncLibrary); |
| 276 return parent._getLinkedSummaryOrNull(uri); | 259 coreLibrary.createLoadLibraryFunction(summaryTypeProvider); |
| 277 } | 260 asyncLibrary.createLoadLibraryFunction(summaryTypeProvider); |
| 278 return getLinkedSummary(uri); | 261 _typeProvider = summaryTypeProvider; |
| 279 } | 262 } |
| 280 | 263 |
| 281 /** | 264 /** |
| 282 * Get the [Source] object for the given [uri]. | 265 * Get the [Source] object for the given [uri]. |
| 283 */ | 266 */ |
| 284 Source _getSource(String uri) { | 267 Source _getSource(String uri) { |
| 285 return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri)); | 268 return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri)); |
| 286 } | 269 } |
| 287 | |
| 288 /** | |
| 289 * Return the [UnlinkedUnit] for the given [uri] or return `null` if it | |
| 290 * could not be found. | |
| 291 */ | |
| 292 UnlinkedUnit _getUnlinkedSummaryOrNull(String uri) { | |
| 293 if (parent != null && parent._hasLibrarySummary(uri)) { | |
| 294 return parent._getUnlinkedSummaryOrNull(uri); | |
| 295 } | |
| 296 return getUnlinkedSummary(uri); | |
| 297 } | |
| 298 | |
| 299 /** | |
| 300 * Return `true` if this resynthesizer can provide summaries of the libraries | |
| 301 * with the given [uri]. | |
| 302 */ | |
| 303 bool _hasLibrarySummary(String uri) { | |
| 304 if (parent != null && parent._hasLibrarySummary(uri)) { | |
| 305 return true; | |
| 306 } | |
| 307 return hasLibrarySummary(uri); | |
| 308 } | |
| 309 } | 270 } |
| 310 | 271 |
| 311 /** | 272 /** |
| 312 * Builder of [Expression]s from [UnlinkedExpr]s. | 273 * Builder of [Expression]s from [UnlinkedExpr]s. |
| 313 */ | 274 */ |
| 314 class _ConstExprBuilder { | 275 class _ConstExprBuilder { |
| 315 static const ARGUMENT_LIST = 'ARGUMENT_LIST'; | 276 static const ARGUMENT_LIST = 'ARGUMENT_LIST'; |
| 316 | 277 |
| 317 final _UnitResynthesizer resynthesizer; | 278 final _UnitResynthesizer resynthesizer; |
| 318 final ElementImpl context; | 279 final ElementImpl context; |
| (...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 static String _getElementIdentifier(String name, ReferenceKind kind) { | 1870 static String _getElementIdentifier(String name, ReferenceKind kind) { |
| 1910 if (kind == ReferenceKind.topLevelPropertyAccessor || | 1871 if (kind == ReferenceKind.topLevelPropertyAccessor || |
| 1911 kind == ReferenceKind.propertyAccessor) { | 1872 kind == ReferenceKind.propertyAccessor) { |
| 1912 if (!name.endsWith('=')) { | 1873 if (!name.endsWith('=')) { |
| 1913 return name + '?'; | 1874 return name + '?'; |
| 1914 } | 1875 } |
| 1915 } | 1876 } |
| 1916 return name; | 1877 return name; |
| 1917 } | 1878 } |
| 1918 } | 1879 } |
| OLD | NEW |