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

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

Issue 1569923002: Fix some corner cases of resynthesizing generic function types. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 /** 194 /**
195 * Map of top level elements that have been resynthesized so far. The first 195 * Map of top level elements that have been resynthesized so far. The first
196 * key is the URI of the compilation unit; the second is the name of the top 196 * key is the URI of the compilation unit; the second is the name of the top
197 * level element. 197 * level element.
198 */ 198 */
199 final Map<String, Map<String, Element>> resummarizedElements = 199 final Map<String, Map<String, Element>> resummarizedElements =
200 <String, Map<String, Element>>{}; 200 <String, Map<String, Element>>{};
201 201
202 /** 202 /**
203 * Type parameters for the class or typedef currently being resynthesized. 203 * Type parameters for the generic class, typedef, or executable currently
204 * 204 * being resynthesized, if any. If multiple entities with type parameters
205 * TODO(paulberry): extend this to do the right thing for generic methods. 205 * are nested (e.g. a generic executable inside a generic class), this is the
206 * concatenation of all type parameters from all declarations currently in
207 * force, with the outermost declaration appearing first. If there are no
208 * type parameters, or we are not currently resynthesizing a class, typedef,
209 * or executable, then this is an empty list.
206 */ 210 */
207 List<TypeParameterElement> currentTypeParameters; 211 List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
208 212
209 _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary, 213 _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
210 this.unlinkedUnits, this.librarySource) { 214 this.unlinkedUnits, this.librarySource) {
211 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; 215 isCoreLibrary = librarySource.uri.toString() == 'dart:core';
212 } 216 }
213 217
214 /** 218 /**
215 * Return a list of type arguments corresponding to [currentTypeParameters]. 219 * Return a list of type arguments corresponding to [currentTypeParameters].
216 */ 220 */
217 List<TypeParameterType> get currentTypeArguments => currentTypeParameters 221 List<TypeParameterType> get currentTypeArguments => currentTypeParameters
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 buildVariable(serializedVariable, memberHolder); 271 buildVariable(serializedVariable, memberHolder);
268 } 272 }
269 if (!serializedClass.isMixinApplication) { 273 if (!serializedClass.isMixinApplication) {
270 if (!constructorFound) { 274 if (!constructorFound) {
271 // Synthesize implicit constructors. 275 // Synthesize implicit constructors.
272 ConstructorElementImpl constructor = 276 ConstructorElementImpl constructor =
273 new ConstructorElementImpl('', -1); 277 new ConstructorElementImpl('', -1);
274 constructor.synthetic = true; 278 constructor.synthetic = true;
275 constructor.returnType = correspondingType; 279 constructor.returnType = correspondingType;
276 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs( 280 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
277 constructor, null, currentTypeArguments); 281 constructor, null, currentTypeArguments, false);
278 memberHolder.addConstructor(constructor); 282 memberHolder.addConstructor(constructor);
279 } 283 }
280 classElement.constructors = memberHolder.constructors; 284 classElement.constructors = memberHolder.constructors;
281 } 285 }
282 classElement.accessors = memberHolder.accessors; 286 classElement.accessors = memberHolder.accessors;
283 classElement.fields = memberHolder.fields; 287 classElement.fields = memberHolder.fields;
284 classElement.methods = memberHolder.methods; 288 classElement.methods = memberHolder.methods;
285 correspondingType.typeArguments = currentTypeArguments; 289 correspondingType.typeArguments = currentTypeArguments;
286 classElement.type = correspondingType; 290 classElement.type = correspondingType;
287 unitHolder.addType(classElement); 291 unitHolder.addType(classElement);
288 } finally { 292 } finally {
289 currentTypeParameters = null; 293 currentTypeParameters = <TypeParameterElement>[];
290 } 294 }
291 } 295 }
292 296
293 /** 297 /**
294 * Resynthesize a [NamespaceCombinator]. 298 * Resynthesize a [NamespaceCombinator].
295 */ 299 */
296 NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) { 300 NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
297 if (serializedCombinator.shows.isNotEmpty) { 301 if (serializedCombinator.shows.isNotEmpty) {
298 ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl(); 302 ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl();
299 // Note: we call toList() so that we don't retain a reference to the 303 // Note: we call toList() so that we don't retain a reference to the
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 assert(false); 448 assert(false);
445 } 449 }
446 } 450 }
447 451
448 /** 452 /**
449 * Handle the parts of an executable element that are common to constructors, 453 * Handle the parts of an executable element that are common to constructors,
450 * functions, methods, getters, and setters. 454 * functions, methods, getters, and setters.
451 */ 455 */
452 void buildExecutableCommonParts(ExecutableElementImpl executableElement, 456 void buildExecutableCommonParts(ExecutableElementImpl executableElement,
453 UnlinkedExecutable serializedExecutable) { 457 UnlinkedExecutable serializedExecutable) {
458 List<TypeParameterType> oldTypeArguments = currentTypeArguments;
459 int oldTypeParametersLength = currentTypeParameters.length;
460 if (serializedExecutable.typeParameters.isNotEmpty) {
461 executableElement.typeParameters =
462 serializedExecutable.typeParameters.map(buildTypeParameter).toList();
463 currentTypeParameters.addAll(executableElement.typeParameters);
464 }
454 executableElement.parameters = 465 executableElement.parameters =
455 serializedExecutable.parameters.map(buildParameter).toList(); 466 serializedExecutable.parameters.map(buildParameter).toList();
456 if (serializedExecutable.returnType != null) { 467 if (serializedExecutable.returnType != null) {
457 executableElement.returnType = buildType(serializedExecutable.returnType); 468 executableElement.returnType = buildType(serializedExecutable.returnType);
458 } else if (serializedExecutable.kind == 469 } else if (serializedExecutable.kind ==
459 UnlinkedExecutableKind.constructor) { 470 UnlinkedExecutableKind.constructor) {
460 // Return type was set by the caller. 471 // Return type was set by the caller.
461 } else { 472 } else {
462 executableElement.returnType = VoidTypeImpl.instance; 473 executableElement.returnType = VoidTypeImpl.instance;
463 } 474 }
464 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs( 475 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
465 executableElement, null, currentTypeArguments); 476 executableElement, null, oldTypeArguments, false);
466 executableElement.hasImplicitReturnType = 477 executableElement.hasImplicitReturnType =
467 serializedExecutable.hasImplicitReturnType; 478 serializedExecutable.hasImplicitReturnType;
468 executableElement.external = serializedExecutable.isExternal; 479 executableElement.external = serializedExecutable.isExternal;
480 currentTypeParameters.removeRange(
481 oldTypeParametersLength, currentTypeParameters.length);
469 } 482 }
470 483
471 /** 484 /**
472 * Resynthesize an [ExportElement], 485 * Resynthesize an [ExportElement],
473 */ 486 */
474 ExportElement buildExport(UnlinkedExport serializedExport) { 487 ExportElement buildExport(UnlinkedExport serializedExport) {
475 ExportElementImpl exportElement = new ExportElementImpl(0); 488 ExportElementImpl exportElement = new ExportElementImpl(0);
476 String exportedLibraryUri = summaryResynthesizer.sourceFactory 489 String exportedLibraryUri = summaryResynthesizer.sourceFactory
477 .resolveUri(librarySource, serializedExport.uri) 490 .resolveUri(librarySource, serializedExport.uri)
478 .uri 491 .uri
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 parameterElement.parameters = 681 parameterElement.parameters =
669 serializedParameter.parameters.map(buildParameter).toList(); 682 serializedParameter.parameters.map(buildParameter).toList();
670 parameterTypeElement.enclosingElement = parameterElement; 683 parameterTypeElement.enclosingElement = parameterElement;
671 parameterTypeElement.shareParameters(parameterElement.parameters); 684 parameterTypeElement.shareParameters(parameterElement.parameters);
672 if (serializedParameter.type != null) { 685 if (serializedParameter.type != null) {
673 parameterTypeElement.returnType = buildType(serializedParameter.type); 686 parameterTypeElement.returnType = buildType(serializedParameter.type);
674 } else { 687 } else {
675 parameterTypeElement.returnType = VoidTypeImpl.instance; 688 parameterTypeElement.returnType = VoidTypeImpl.instance;
676 } 689 }
677 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( 690 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
678 parameterTypeElement, null, currentTypeArguments); 691 parameterTypeElement, null, currentTypeArguments, false);
679 } else { 692 } else {
680 parameterElement.type = buildType(serializedParameter.type); 693 parameterElement.type = buildType(serializedParameter.type);
681 parameterElement.hasImplicitType = serializedParameter.hasImplicitType; 694 parameterElement.hasImplicitType = serializedParameter.hasImplicitType;
682 } 695 }
683 switch (serializedParameter.kind) { 696 switch (serializedParameter.kind) {
684 case UnlinkedParamKind.named: 697 case UnlinkedParamKind.named:
685 parameterElement.parameterKind = ParameterKind.NAMED; 698 parameterElement.parameterKind = ParameterKind.NAMED;
686 break; 699 break;
687 case UnlinkedParamKind.positional: 700 case UnlinkedParamKind.positional:
688 parameterElement.parameterKind = ParameterKind.POSITIONAL; 701 parameterElement.parameterKind = ParameterKind.POSITIONAL;
(...skipping 24 matching lines...) Expand all
713 /** 726 /**
714 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] 727 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType]
715 * may refer to elements in other libraries than the library being 728 * may refer to elements in other libraries than the library being
716 * deserialized, so handles are used to avoid having to deserialize other 729 * deserialized, so handles are used to avoid having to deserialize other
717 * libraries in the process. 730 * libraries in the process.
718 */ 731 */
719 DartType buildType(UnlinkedTypeRef type) { 732 DartType buildType(UnlinkedTypeRef type) {
720 if (type.paramReference != 0) { 733 if (type.paramReference != 0) {
721 // TODO(paulberry): make this work for generic methods. 734 // TODO(paulberry): make this work for generic methods.
722 return currentTypeParameters[ 735 return currentTypeParameters[
723 currentTypeParameters.length - type.paramReference] 736 currentTypeParameters.length - type.paramReference].type;
724 .type;
725 } else { 737 } else {
726 // TODO(paulberry): handle references to things other than classes (note: 738 // TODO(paulberry): handle references to things other than classes (note:
727 // this should only occur in the case of erroneous code). 739 // this should only occur in the case of erroneous code).
728 // TODO(paulberry): test reference to something inside a part. 740 // TODO(paulberry): test reference to something inside a part.
729 // TODO(paulberry): test reference to something inside a part of the 741 // TODO(paulberry): test reference to something inside a part of the
730 // current lib. 742 // current lib.
731 UnlinkedReference reference = unlinkedUnit.references[type.reference]; 743 UnlinkedReference reference = unlinkedUnit.references[type.reference];
732 PrelinkedReference referenceResolution = 744 PrelinkedReference referenceResolution =
733 prelinkedUnit.references[type.reference]; 745 prelinkedUnit.references[type.reference];
734 String referencedLibraryUri; 746 String referencedLibraryUri;
735 String partUri; 747 String partUri;
736 if (referenceResolution.dependency != 0) { 748 if (referenceResolution.dependency != 0) {
737 PrelinkedDependency dependency = 749 PrelinkedDependency dependency =
738 prelinkedLibrary.dependencies[referenceResolution.dependency]; 750 prelinkedLibrary.dependencies[referenceResolution.dependency];
739 Source referencedLibrarySource = summaryResynthesizer.sourceFactory 751 Source referencedLibrarySource = summaryResynthesizer.sourceFactory
740 .resolveUri(librarySource, dependency.uri); 752 .resolveUri(librarySource, dependency.uri);
741 referencedLibraryUri = referencedLibrarySource.uri.toString(); 753 referencedLibraryUri = referencedLibrarySource.uri.toString();
742 // TODO(paulberry): consider changing Location format so that this is 754 // TODO(paulberry): consider changing Location format so that this is
743 // not necessary (2nd string in location should just be the unit 755 // not necessary (2nd string in location should just be the unit
744 // number). 756 // number).
745 if (referenceResolution.unit != 0) { 757 if (referenceResolution.unit != 0) {
746 UnlinkedUnit referencedLibraryDefiningUnit = 758 UnlinkedUnit referencedLibraryDefiningUnit =
747 summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri); 759 summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri);
748 String uri = referencedLibraryDefiningUnit 760 String uri = referencedLibraryDefiningUnit.publicNamespace.parts[
749 .publicNamespace.parts[referenceResolution.unit - 1].uri; 761 referenceResolution.unit - 1].uri;
750 Source partSource = summaryResynthesizer.sourceFactory 762 Source partSource = summaryResynthesizer.sourceFactory
751 .resolveUri(referencedLibrarySource, uri); 763 .resolveUri(referencedLibrarySource, uri);
752 partUri = partSource.uri.toString(); 764 partUri = partSource.uri.toString();
753 } else { 765 } else {
754 partUri = referencedLibraryUri; 766 partUri = referencedLibraryUri;
755 } 767 }
756 } else if (referenceResolution.kind == 768 } else if (referenceResolution.kind ==
757 PrelinkedReferenceKind.unresolved) { 769 PrelinkedReferenceKind.unresolved) {
758 return summaryResynthesizer.typeProvider.undefinedType; 770 return summaryResynthesizer.typeProvider.undefinedType;
759 } else if (reference.name.isEmpty) { 771 } else if (reference.name.isEmpty) {
760 return summaryResynthesizer.typeProvider.dynamicType; 772 return summaryResynthesizer.typeProvider.dynamicType;
761 } else { 773 } else {
762 referencedLibraryUri = librarySource.uri.toString(); 774 referencedLibraryUri = librarySource.uri.toString();
763 if (referenceResolution.unit != 0) { 775 if (referenceResolution.unit != 0) {
764 String uri = unlinkedUnits[0] 776 String uri = unlinkedUnits[0].publicNamespace.parts[
765 .publicNamespace 777 referenceResolution.unit - 1].uri;
766 .parts[referenceResolution.unit - 1]
767 .uri;
768 Source partSource = 778 Source partSource =
769 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri); 779 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
770 partUri = partSource.uri.toString(); 780 partUri = partSource.uri.toString();
771 } else { 781 } else {
772 partUri = referencedLibraryUri; 782 partUri = referencedLibraryUri;
773 } 783 }
774 } 784 }
775 ElementLocationImpl location = new ElementLocationImpl.con3( 785 ElementLocationImpl location = new ElementLocationImpl.con3(
776 <String>[referencedLibraryUri, partUri, reference.name]); 786 <String>[referencedLibraryUri, partUri, reference.name]);
777 List<DartType> typeArguments = const <DartType>[]; 787 List<DartType> typeArguments = const <DartType>[];
(...skipping 11 matching lines...) Expand all
789 case PrelinkedReferenceKind.classOrEnum: 799 case PrelinkedReferenceKind.classOrEnum:
790 return new InterfaceTypeImpl.elementWithNameAndArgs( 800 return new InterfaceTypeImpl.elementWithNameAndArgs(
791 new ClassElementHandle(summaryResynthesizer, location), 801 new ClassElementHandle(summaryResynthesizer, location),
792 reference.name, 802 reference.name,
793 typeArguments); 803 typeArguments);
794 case PrelinkedReferenceKind.typedef: 804 case PrelinkedReferenceKind.typedef:
795 return new FunctionTypeImpl.elementWithNameAndArgs( 805 return new FunctionTypeImpl.elementWithNameAndArgs(
796 new FunctionTypeAliasElementHandle( 806 new FunctionTypeAliasElementHandle(
797 summaryResynthesizer, location), 807 summaryResynthesizer, location),
798 reference.name, 808 reference.name,
799 typeArguments); 809 typeArguments,
810 typeArguments.isNotEmpty);
800 default: 811 default:
801 // TODO(paulberry): figure out how to handle this case (which should 812 // TODO(paulberry): figure out how to handle this case (which should
802 // only occur in the event of erroneous code). 813 // only occur in the event of erroneous code).
803 throw new UnimplementedError(); 814 throw new UnimplementedError();
804 } 815 }
805 } 816 }
806 } 817 }
807 818
808 /** 819 /**
809 * Resynthesize a [FunctionTypeAliasElement] and place it in the 820 * Resynthesize a [FunctionTypeAliasElement] and place it in the
(...skipping 15 matching lines...) Expand all
825 functionTypeAliasElement.returnType = 836 functionTypeAliasElement.returnType =
826 buildType(serializedTypedef.returnType); 837 buildType(serializedTypedef.returnType);
827 } else { 838 } else {
828 functionTypeAliasElement.returnType = VoidTypeImpl.instance; 839 functionTypeAliasElement.returnType = VoidTypeImpl.instance;
829 } 840 }
830 functionTypeAliasElement.type = 841 functionTypeAliasElement.type =
831 new FunctionTypeImpl.forTypedef(functionTypeAliasElement); 842 new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
832 functionTypeAliasElement.typeParameters = currentTypeParameters; 843 functionTypeAliasElement.typeParameters = currentTypeParameters;
833 unitHolder.addTypeAlias(functionTypeAliasElement); 844 unitHolder.addTypeAlias(functionTypeAliasElement);
834 } finally { 845 } finally {
835 currentTypeParameters = null; 846 currentTypeParameters = <TypeParameterElement>[];
836 } 847 }
837 } 848 }
838 849
839 /** 850 /**
840 * Resynthesize a [TypeParameterElement], handling all parts of its except 851 * Resynthesize a [TypeParameterElement], handling all parts of its except
841 * its bound. 852 * its bound.
842 * 853 *
843 * The bound is deferred until later since it may refer to other type 854 * The bound is deferred until later since it may refer to other type
844 * parameters that have not been resynthesized yet. To handle the bound, 855 * parameters that have not been resynthesized yet. To handle the bound,
845 * call [finishTypeParameter]. 856 * call [finishTypeParameter].
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 } 939 }
929 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) { 940 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
930 elementMap[typeAlias.name] = typeAlias; 941 elementMap[typeAlias.name] = typeAlias;
931 } 942 }
932 resummarizedElements[absoluteUri] = elementMap; 943 resummarizedElements[absoluteUri] = elementMap;
933 unitHolder = null; 944 unitHolder = null;
934 prelinkedUnit = null; 945 prelinkedUnit = null;
935 unlinkedUnit = null; 946 unlinkedUnit = null;
936 } 947 }
937 } 948 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/type.dart ('k') | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698