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