Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 1543313002: Delay TypeProvider.objectType access until after dart:core resynthesizing. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/element_handle.dart'; 9 import 'package:analyzer/src/generated/element_handle.dart';
10 import 'package:analyzer/src/generated/engine.dart'; 10 import 'package:analyzer/src/generated/engine.dart';
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 final SourceFactory sourceFactory; 105 final SourceFactory sourceFactory;
106 106
107 /** 107 /**
108 * Cache of [Source] objects that have already been converted from URIs. 108 * Cache of [Source] objects that have already been converted from URIs.
109 */ 109 */
110 final Map<String, Source> _sources = <String, Source>{}; 110 final Map<String, Source> _sources = <String, Source>{};
111 111
112 /** 112 /**
113 * The [TypeProvider] used to obtain core types (such as Object, int, List, 113 * The [TypeProvider] used to obtain core types (such as Object, int, List,
114 * and dynamic) during resynthesis. 114 * and dynamic) during resynthesis.
115 *
116 * TODO(paulberry): will this create a chicken-and-egg problem when trying to
117 * resynthesize the core library from summaries?
118 */ 115 */
119 final TypeProvider typeProvider; 116 final TypeProvider typeProvider;
120 117
121 /** 118 /**
122 * Map of top level elements resynthesized from summaries. The three map 119 * Map of top level elements resynthesized from summaries. The three map
123 * keys are the first three elements of the element's location (the library 120 * keys are the first three elements of the element's location (the library
124 * URI, the compilation unit URI, and the name of the top level declaration). 121 * URI, the compilation unit URI, and the name of the top level declaration).
125 */ 122 */
126 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = 123 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements =
127 <String, Map<String, Map<String, Element>>>{}; 124 <String, Map<String, Map<String, Element>>>{};
128 125
129 /** 126 /**
130 * Map of libraries which have been resynthesized from summaries. The map 127 * Map of libraries which have been resynthesized from summaries. The map
131 * key is the library URI. 128 * key is the library URI.
132 */ 129 */
133 final Map<String, LibraryElement> _resynthesizedLibraries = 130 final Map<String, LibraryElement> _resynthesizedLibraries =
134 <String, LibraryElement>{}; 131 <String, LibraryElement>{};
135 132
136 SummaryResynthesizer(AnalysisContext context, this.getPrelinkedSummary, 133 SummaryResynthesizer(AnalysisContext context, this.typeProvider,
137 this.getUnlinkedSummary, this.sourceFactory) 134 this.getPrelinkedSummary, this.getUnlinkedSummary, this.sourceFactory)
138 : super(context), 135 : super(context);
139 typeProvider = context.typeProvider;
140 136
141 /** 137 /**
142 * Number of libraries that have been resynthesized so far. 138 * Number of libraries that have been resynthesized so far.
143 */ 139 */
144 int get resynthesisCount => _resynthesizedLibraries.length; 140 int get resynthesisCount => _resynthesizedLibraries.length;
145 141
146 @override 142 @override
147 Element getElement(ElementLocation location) { 143 Element getElement(ElementLocation location) {
148 if (location.components.length == 1) { 144 if (location.components.length == 1) {
149 return getLibraryElement(location.components[0]); 145 return getLibraryElement(location.components[0]);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 * Unlinked compilation units constituting the library to be resynthesized. 217 * Unlinked compilation units constituting the library to be resynthesized.
222 */ 218 */
223 final List<UnlinkedUnit> unlinkedUnits; 219 final List<UnlinkedUnit> unlinkedUnits;
224 220
225 /** 221 /**
226 * [Source] object for the library to be resynthesized. 222 * [Source] object for the library to be resynthesized.
227 */ 223 */
228 final Source librarySource; 224 final Source librarySource;
229 225
230 /** 226 /**
227 * Indicates whether [librarySource] is the `dart:core` library.
228 */
229 bool isCoreLibrary;
230
231 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[];
Paul Berry 2015/12/24 03:31:09 Please add a doc comment for this field. Perhaps
scheglov 2015/12/24 03:36:06 Done.
232
233 /**
231 * [ElementHolder] into which resynthesized elements should be placed. This 234 * [ElementHolder] into which resynthesized elements should be placed. This
232 * object is recreated afresh for each unit in the library, and is used to 235 * object is recreated afresh for each unit in the library, and is used to
233 * populate the [CompilationUnitElement]. 236 * populate the [CompilationUnitElement].
234 */ 237 */
235 ElementHolder unitHolder; 238 ElementHolder unitHolder;
236 239
237 /** 240 /**
238 * The [PrelinkedUnit] from which elements are currently being resynthesized. 241 * The [PrelinkedUnit] from which elements are currently being resynthesized.
239 */ 242 */
240 PrelinkedUnit prelinkedUnit; 243 PrelinkedUnit prelinkedUnit;
(...skipping 12 matching lines...) Expand all
253 <String, Map<String, Element>>{}; 256 <String, Map<String, Element>>{};
254 257
255 /** 258 /**
256 * Type parameters for the class or typedef currently being resynthesized. 259 * Type parameters for the class or typedef currently being resynthesized.
257 * 260 *
258 * TODO(paulberry): extend this to do the right thing for generic methods. 261 * TODO(paulberry): extend this to do the right thing for generic methods.
259 */ 262 */
260 List<TypeParameterElement> currentTypeParameters; 263 List<TypeParameterElement> currentTypeParameters;
261 264
262 _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary, 265 _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
263 this.unlinkedUnits, this.librarySource); 266 this.unlinkedUnits, this.librarySource) {
267 isCoreLibrary = librarySource.uri.toString() == 'dart:core';
268 }
264 269
265 /** 270 /**
266 * Resynthesize a [ClassElement] and place it in [unitHolder]. 271 * Resynthesize a [ClassElement] and place it in [unitHolder].
267 */ 272 */
268 void buildClass(UnlinkedClass serializedClass) { 273 void buildClass(UnlinkedClass serializedClass) {
269 try { 274 try {
270 currentTypeParameters = 275 currentTypeParameters =
271 serializedClass.typeParameters.map(buildTypeParameter).toList(); 276 serializedClass.typeParameters.map(buildTypeParameter).toList();
272 for (int i = 0; i < serializedClass.typeParameters.length; i++) { 277 for (int i = 0; i < serializedClass.typeParameters.length; i++) {
273 finishTypeParameter( 278 finishTypeParameter(
274 serializedClass.typeParameters[i], currentTypeParameters[i]); 279 serializedClass.typeParameters[i], currentTypeParameters[i]);
275 } 280 }
276 ClassElementImpl classElement = 281 ClassElementImpl classElement =
277 new ClassElementImpl(serializedClass.name, -1); 282 new ClassElementImpl(serializedClass.name, -1);
278 classElement.mixinApplication = serializedClass.isMixinApplication; 283 classElement.mixinApplication = serializedClass.isMixinApplication;
279 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement); 284 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
280 if (serializedClass.supertype != null) { 285 if (serializedClass.supertype != null) {
281 classElement.supertype = buildType(serializedClass.supertype); 286 classElement.supertype = buildType(serializedClass.supertype);
282 } else if (!serializedClass.hasNoSupertype) { 287 } else if (!serializedClass.hasNoSupertype) {
283 classElement.supertype = summaryResynthesizer.typeProvider.objectType; 288 if (isCoreLibrary) {
289 delayedObjectSubclasses.add(classElement);
290 } else {
291 classElement.supertype = summaryResynthesizer.typeProvider.objectType;
292 }
284 } 293 }
285 classElement.interfaces = 294 classElement.interfaces =
286 serializedClass.interfaces.map(buildType).toList(); 295 serializedClass.interfaces.map(buildType).toList();
287 classElement.mixins = serializedClass.mixins.map(buildType).toList(); 296 classElement.mixins = serializedClass.mixins.map(buildType).toList();
288 classElement.typeParameters = currentTypeParameters; 297 classElement.typeParameters = currentTypeParameters;
289 ElementHolder memberHolder = new ElementHolder(); 298 ElementHolder memberHolder = new ElementHolder();
290 bool constructorFound = false; 299 bool constructorFound = false;
291 for (UnlinkedExecutable serializedExecutable 300 for (UnlinkedExecutable serializedExecutable
292 in serializedClass.executables) { 301 in serializedClass.executables) {
293 switch (serializedExecutable.kind) { 302 switch (serializedExecutable.kind) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 constructorElement.factory = serializedExecutable.isFactory; 369 constructorElement.factory = serializedExecutable.isFactory;
361 constructorElement.const2 = serializedExecutable.isConst; 370 constructorElement.const2 = serializedExecutable.isConst;
362 holder.addConstructor(constructorElement); 371 holder.addConstructor(constructorElement);
363 } 372 }
364 373
365 /** 374 /**
366 * Resynthesize the [ClassElement] corresponding to an enum, along with the 375 * Resynthesize the [ClassElement] corresponding to an enum, along with the
367 * associated fields and implicit accessors. 376 * associated fields and implicit accessors.
368 */ 377 */
369 void buildEnum(UnlinkedEnum serializedEnum) { 378 void buildEnum(UnlinkedEnum serializedEnum) {
379 assert(!isCoreLibrary);
370 // TODO(paulberry): add offset support (for this element type and others) 380 // TODO(paulberry): add offset support (for this element type and others)
371 ClassElementImpl classElement = 381 ClassElementImpl classElement =
372 new ClassElementImpl(serializedEnum.name, -1); 382 new ClassElementImpl(serializedEnum.name, -1);
373 classElement.enum2 = true; 383 classElement.enum2 = true;
374 InterfaceType enumType = new InterfaceTypeImpl(classElement); 384 InterfaceType enumType = new InterfaceTypeImpl(classElement);
375 classElement.type = enumType; 385 classElement.type = enumType;
376 classElement.supertype = summaryResynthesizer.typeProvider.objectType; 386 classElement.supertype = summaryResynthesizer.typeProvider.objectType;
377 ElementHolder memberHolder = new ElementHolder(); 387 ElementHolder memberHolder = new ElementHolder();
378 FieldElementImpl indexField = new FieldElementImpl('index', -1); 388 FieldElementImpl indexField = new FieldElementImpl('index', -1);
379 indexField.final2 = true; 389 indexField.final2 = true;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 element.setter = setter; 575 element.setter = setter;
566 } 576 }
567 } 577 }
568 578
569 /** 579 /**
570 * Build the implicit field associated with a getter or setter, and place it 580 * Build the implicit field associated with a getter or setter, and place it
571 * in [holder]. 581 * in [holder].
572 */ 582 */
573 FieldElementImpl buildImplicitField(String name, DartType type, 583 FieldElementImpl buildImplicitField(String name, DartType type,
574 UnlinkedExecutableKind kind, ElementHolder holder) { 584 UnlinkedExecutableKind kind, ElementHolder holder) {
575 if (holder.getField(name) == null) { 585 FieldElementImpl field = holder.getField(name);
576 FieldElementImpl field = new FieldElementImpl(name, -1); 586 if (field == null) {
587 field = new FieldElementImpl(name, -1);
577 field.synthetic = true; 588 field.synthetic = true;
578 field.final2 = kind == UnlinkedExecutableKind.getter; 589 field.final2 = kind == UnlinkedExecutableKind.getter;
579 field.type = type; 590 field.type = type;
580 holder.addField(field); 591 holder.addField(field);
581 return field; 592 return field;
582 } else { 593 } else {
583 // TODO(paulberry): if adding a setter where there was previously
584 // only a getter, remove "final" modifier.
585 // TODO(paulberry): what if the getter and setter have a type mismatch? 594 // TODO(paulberry): what if the getter and setter have a type mismatch?
586 throw new UnimplementedError(); 595 field.final2 = false;
596 return field;
587 } 597 }
588 } 598 }
589 599
590 /** 600 /**
591 * Build the implicit top level variable associated with a getter or setter, 601 * Build the implicit top level variable associated with a getter or setter,
592 * and place it in [holder]. 602 * and place it in [holder].
593 */ 603 */
594 PropertyInducingElementImpl buildImplicitTopLevelVariable( 604 PropertyInducingElementImpl buildImplicitTopLevelVariable(
595 String name, UnlinkedExecutableKind kind, ElementHolder holder) { 605 String name, UnlinkedExecutableKind kind, ElementHolder holder) {
596 if (holder.getTopLevelVariable(name) == null) { 606 if (holder.getTopLevelVariable(name) == null) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 imports.add(buildImport(unlinkedDefiningUnit.imports[i], 677 imports.add(buildImport(unlinkedDefiningUnit.imports[i],
668 prelinkedLibrary.importDependencies[i])); 678 prelinkedLibrary.importDependencies[i]));
669 } 679 }
670 libraryElement.imports = imports; 680 libraryElement.imports = imports;
671 libraryElement.exports = 681 libraryElement.exports =
672 unlinkedDefiningUnit.exports.map(buildExport).toList(); 682 unlinkedDefiningUnit.exports.map(buildExport).toList();
673 populateUnit(definingCompilationUnit, 0); 683 populateUnit(definingCompilationUnit, 0);
674 for (int i = 0; i < parts.length; i++) { 684 for (int i = 0; i < parts.length; i++) {
675 populateUnit(parts[i], i + 1); 685 populateUnit(parts[i], i + 1);
676 } 686 }
687 if (isCoreLibrary) {
688 ClassElement objectElement = libraryElement.getType('Object');
689 assert(objectElement != null);
690 for (ClassElementImpl classElement in delayedObjectSubclasses) {
691 classElement.supertype = objectElement.type;
692 }
693 }
677 return libraryElement; 694 return libraryElement;
678 } 695 }
679 696
680 /** 697 /**
681 * Resynthesize a [ParameterElement]. 698 * Resynthesize a [ParameterElement].
682 */ 699 */
683 ParameterElement buildParameter(UnlinkedParam serializedParameter) { 700 ParameterElement buildParameter(UnlinkedParam serializedParameter) {
684 ParameterElementImpl parameterElement = 701 ParameterElementImpl parameterElement =
685 new ParameterElementImpl(serializedParameter.name, -1); 702 new ParameterElementImpl(serializedParameter.name, -1);
686 if (serializedParameter.isFunctionTyped) { 703 if (serializedParameter.isFunctionTyped) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 /** 751 /**
735 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] 752 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType]
736 * may refer to elements in other libraries than the library being 753 * may refer to elements in other libraries than the library being
737 * deserialized, so handles are used to avoid having to deserialize other 754 * deserialized, so handles are used to avoid having to deserialize other
738 * libraries in the process. 755 * libraries in the process.
739 */ 756 */
740 DartType buildType(UnlinkedTypeRef type) { 757 DartType buildType(UnlinkedTypeRef type) {
741 if (type.paramReference != 0) { 758 if (type.paramReference != 0) {
742 // TODO(paulberry): make this work for generic methods. 759 // TODO(paulberry): make this work for generic methods.
743 return currentTypeParameters[ 760 return currentTypeParameters[
744 currentTypeParameters.length - type.paramReference].type; 761 currentTypeParameters.length - type.paramReference]
762 .type;
745 } else { 763 } else {
746 // TODO(paulberry): handle references to things other than classes (note: 764 // TODO(paulberry): handle references to things other than classes (note:
747 // this should only occur in the case of erroneous code). 765 // this should only occur in the case of erroneous code).
748 // TODO(paulberry): test reference to something inside a part. 766 // TODO(paulberry): test reference to something inside a part.
749 // TODO(paulberry): test reference to something inside a part of the 767 // TODO(paulberry): test reference to something inside a part of the
750 // current lib. 768 // current lib.
751 UnlinkedReference reference = unlinkedUnit.references[type.reference]; 769 UnlinkedReference reference = unlinkedUnit.references[type.reference];
752 PrelinkedReference referenceResolution = 770 PrelinkedReference referenceResolution =
753 prelinkedUnit.references[type.reference]; 771 prelinkedUnit.references[type.reference];
754 String referencedLibraryUri; 772 String referencedLibraryUri;
755 String partUri; 773 String partUri;
756 if (referenceResolution.dependency != 0) { 774 if (referenceResolution.dependency != 0) {
757 PrelinkedDependency dependency = 775 PrelinkedDependency dependency =
758 prelinkedLibrary.dependencies[referenceResolution.dependency]; 776 prelinkedLibrary.dependencies[referenceResolution.dependency];
759 Source referencedLibrarySource = summaryResynthesizer.sourceFactory 777 Source referencedLibrarySource = summaryResynthesizer.sourceFactory
760 .resolveUri(librarySource, dependency.uri); 778 .resolveUri(librarySource, dependency.uri);
761 referencedLibraryUri = referencedLibrarySource.uri.toString(); 779 referencedLibraryUri = referencedLibrarySource.uri.toString();
762 // TODO(paulberry): consider changing Location format so that this is 780 // TODO(paulberry): consider changing Location format so that this is
763 // not necessary (2nd string in location should just be the unit 781 // not necessary (2nd string in location should just be the unit
764 // number). 782 // number).
765 if (referenceResolution.unit != 0) { 783 if (referenceResolution.unit != 0) {
766 UnlinkedUnit referencedLibraryDefiningUnit = 784 UnlinkedUnit referencedLibraryDefiningUnit =
767 summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri); 785 summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri);
768 String uri = referencedLibraryDefiningUnit.parts[0].uri; 786 String uri = referencedLibraryDefiningUnit
787 .parts[referenceResolution.unit - 1].uri;
769 Source partSource = summaryResynthesizer.sourceFactory 788 Source partSource = summaryResynthesizer.sourceFactory
770 .resolveUri(referencedLibrarySource, uri); 789 .resolveUri(referencedLibrarySource, uri);
771 partUri = partSource.uri.toString(); 790 partUri = partSource.uri.toString();
772 } else { 791 } else {
773 partUri = referencedLibraryUri; 792 partUri = referencedLibraryUri;
774 } 793 }
775 } else if (referenceResolution.kind == 794 } else if (referenceResolution.kind ==
776 PrelinkedReferenceKind.unresolved) { 795 PrelinkedReferenceKind.unresolved) {
777 return summaryResynthesizer.typeProvider.undefinedType; 796 return summaryResynthesizer.typeProvider.undefinedType;
778 } else if (reference.name.isEmpty) { 797 } else if (reference.name.isEmpty) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 } 959 }
941 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) { 960 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
942 elementMap[typeAlias.name] = typeAlias; 961 elementMap[typeAlias.name] = typeAlias;
943 } 962 }
944 resummarizedElements[absoluteUri] = elementMap; 963 resummarizedElements[absoluteUri] = elementMap;
945 unitHolder = null; 964 unitHolder = null;
946 prelinkedUnit = null; 965 prelinkedUnit = null;
947 unlinkedUnit = null; 966 unlinkedUnit = null;
948 } 967 }
949 } 968 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/summary_sdk.dart » ('j') | pkg/analyzer/lib/src/summary/summary_sdk.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698