Chromium Code Reviews| 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/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 */ | 39 */ |
| 40 final Map<String, Source> _sources = <String, Source>{}; | 40 final Map<String, Source> _sources = <String, Source>{}; |
| 41 | 41 |
| 42 /** | 42 /** |
| 43 * The [TypeProvider] used to obtain core types (such as Object, int, List, | 43 * The [TypeProvider] used to obtain core types (such as Object, int, List, |
| 44 * and dynamic) during resynthesis. | 44 * and dynamic) during resynthesis. |
| 45 */ | 45 */ |
| 46 final TypeProvider typeProvider; | 46 final TypeProvider typeProvider; |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * Indicates whether the summary should be resynthesized assuming strong mode | |
| 50 * semantics. | |
| 51 */ | |
| 52 final bool strongMode; | |
| 53 | |
| 54 /** | |
| 49 * Map of top level elements resynthesized from summaries. The three map | 55 * Map of top level elements resynthesized from summaries. The three map |
| 50 * keys are the first three elements of the element's location (the library | 56 * keys are the first three elements of the element's location (the library |
| 51 * URI, the compilation unit URI, and the name of the top level declaration). | 57 * URI, the compilation unit URI, and the name of the top level declaration). |
| 52 */ | 58 */ |
| 53 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = | 59 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = |
| 54 <String, Map<String, Map<String, Element>>>{}; | 60 <String, Map<String, Map<String, Element>>>{}; |
| 55 | 61 |
| 56 /** | 62 /** |
| 57 * Map of libraries which have been resynthesized from summaries. The map | 63 * Map of libraries which have been resynthesized from summaries. The map |
| 58 * key is the library URI. | 64 * key is the library URI. |
| 59 */ | 65 */ |
| 60 final Map<String, LibraryElement> _resynthesizedLibraries = | 66 final Map<String, LibraryElement> _resynthesizedLibraries = |
| 61 <String, LibraryElement>{}; | 67 <String, LibraryElement>{}; |
| 62 | 68 |
| 63 SummaryResynthesizer(this.parent, AnalysisContext context, this.typeProvider, | 69 SummaryResynthesizer(this.parent, AnalysisContext context, this.typeProvider, |
| 64 this.sourceFactory) | 70 this.sourceFactory, this.strongMode) |
| 65 : super(context); | 71 : super(context); |
| 66 | 72 |
| 67 /** | 73 /** |
| 68 * Number of libraries that have been resynthesized so far. | 74 * Number of libraries that have been resynthesized so far. |
| 69 */ | 75 */ |
| 70 int get resynthesisCount => _resynthesizedLibraries.length; | 76 int get resynthesisCount => _resynthesizedLibraries.length; |
| 71 | 77 |
| 72 /** | 78 /** |
| 73 * Perform delayed finalization of the `dart:core` and `dart:async` libraries. | 79 * Perform delayed finalization of the `dart:core` and `dart:async` libraries. |
| 74 */ | 80 */ |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 case UnlinkedExecutableKind.setter: | 515 case UnlinkedExecutableKind.setter: |
| 510 PropertyAccessorElementImpl executableElement = | 516 PropertyAccessorElementImpl executableElement = |
| 511 new PropertyAccessorElementImpl( | 517 new PropertyAccessorElementImpl( |
| 512 name, serializedExecutable.nameOffset); | 518 name, serializedExecutable.nameOffset); |
| 513 if (isTopLevel) { | 519 if (isTopLevel) { |
| 514 executableElement.static = true; | 520 executableElement.static = true; |
| 515 } else { | 521 } else { |
| 516 executableElement.static = serializedExecutable.isStatic; | 522 executableElement.static = serializedExecutable.isStatic; |
| 517 executableElement.abstract = serializedExecutable.isAbstract; | 523 executableElement.abstract = serializedExecutable.isAbstract; |
| 518 } | 524 } |
| 519 buildExecutableCommonParts(executableElement, serializedExecutable); | 525 buildExecutableCommonParts(executableElement, serializedExecutable, |
| 526 isSetter: kind == UnlinkedExecutableKind.setter); | |
| 520 DartType type; | 527 DartType type; |
| 521 if (kind == UnlinkedExecutableKind.getter) { | 528 if (kind == UnlinkedExecutableKind.getter) { |
| 522 executableElement.getter = true; | 529 executableElement.getter = true; |
| 523 type = executableElement.returnType; | 530 type = executableElement.returnType; |
| 524 } else { | 531 } else { |
| 525 executableElement.setter = true; | 532 executableElement.setter = true; |
| 526 type = executableElement.parameters[0].type; | 533 type = executableElement.parameters[0].type; |
| 527 } | 534 } |
| 528 holder.addAccessor(executableElement); | 535 holder.addAccessor(executableElement); |
| 529 // TODO(paulberry): consider removing implicit variables from the | 536 // TODO(paulberry): consider removing implicit variables from the |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 552 // unreachable. | 559 // unreachable. |
| 553 assert(false); | 560 assert(false); |
| 554 } | 561 } |
| 555 } | 562 } |
| 556 | 563 |
| 557 /** | 564 /** |
| 558 * Handle the parts of an executable element that are common to constructors, | 565 * Handle the parts of an executable element that are common to constructors, |
| 559 * functions, methods, getters, and setters. | 566 * functions, methods, getters, and setters. |
| 560 */ | 567 */ |
| 561 void buildExecutableCommonParts(ExecutableElementImpl executableElement, | 568 void buildExecutableCommonParts(ExecutableElementImpl executableElement, |
| 562 UnlinkedExecutable serializedExecutable) { | 569 UnlinkedExecutable serializedExecutable, |
| 570 {bool isSetter: false}) { | |
|
scheglov
2016/01/23 18:00:54
Why not use `serializedExecutable.kind == Unlinked
Paul Berry
2016/01/25 12:59:41
Done.
| |
| 563 List<TypeParameterType> oldTypeArguments = currentTypeArguments; | 571 List<TypeParameterType> oldTypeArguments = currentTypeArguments; |
| 564 int oldTypeParametersLength = currentTypeParameters.length; | 572 int oldTypeParametersLength = currentTypeParameters.length; |
| 565 if (serializedExecutable.typeParameters.isNotEmpty) { | 573 if (serializedExecutable.typeParameters.isNotEmpty) { |
| 566 executableElement.typeParameters = | 574 executableElement.typeParameters = |
| 567 serializedExecutable.typeParameters.map(buildTypeParameter).toList(); | 575 serializedExecutable.typeParameters.map(buildTypeParameter).toList(); |
| 568 currentTypeParameters.addAll(executableElement.typeParameters); | 576 currentTypeParameters.addAll(executableElement.typeParameters); |
| 569 } | 577 } |
| 570 executableElement.parameters = | 578 executableElement.parameters = |
| 571 serializedExecutable.parameters.map(buildParameter).toList(); | 579 serializedExecutable.parameters.map(buildParameter).toList(); |
| 572 if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) { | 580 if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) { |
| 573 // Caller handles setting the return type. | 581 // Caller handles setting the return type. |
| 574 assert(serializedExecutable.returnType == null); | 582 assert(serializedExecutable.returnType == null); |
| 575 } else { | 583 } else { |
| 576 executableElement.returnType = buildType(serializedExecutable.returnType); | 584 executableElement.returnType = |
| 585 buildLinkedType(serializedExecutable.inferredReturnTypeSlot) ?? | |
| 586 buildType(serializedExecutable.returnType, | |
| 587 defaultVoid: isSetter && summaryResynthesizer.strongMode); | |
| 577 executableElement.hasImplicitReturnType = | 588 executableElement.hasImplicitReturnType = |
| 578 serializedExecutable.returnType == null; | 589 serializedExecutable.returnType == null; |
| 579 } | 590 } |
| 580 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs( | 591 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 581 executableElement, null, oldTypeArguments, false); | 592 executableElement, null, oldTypeArguments, false); |
| 582 executableElement.external = serializedExecutable.isExternal; | 593 executableElement.external = serializedExecutable.isExternal; |
| 583 currentTypeParameters.removeRange( | 594 currentTypeParameters.removeRange( |
| 584 oldTypeParametersLength, currentTypeParameters.length); | 595 oldTypeParametersLength, currentTypeParameters.length); |
| 585 buildDocumentation( | 596 buildDocumentation( |
| 586 executableElement, serializedExecutable.documentationComment); | 597 executableElement, serializedExecutable.documentationComment); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 parameterTypeElement.returnType = buildType(serializedParameter.type); | 919 parameterTypeElement.returnType = buildType(serializedParameter.type); |
| 909 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( | 920 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 910 parameterTypeElement, null, currentTypeArguments, false); | 921 parameterTypeElement, null, currentTypeArguments, false); |
| 911 } else { | 922 } else { |
| 912 if (serializedParameter.isInitializingFormal && | 923 if (serializedParameter.isInitializingFormal && |
| 913 serializedParameter.type == null) { | 924 serializedParameter.type == null) { |
| 914 // The type is inherited from the matching field. | 925 // The type is inherited from the matching field. |
| 915 parameterElement.type = fields[serializedParameter.name]?.type ?? | 926 parameterElement.type = fields[serializedParameter.name]?.type ?? |
| 916 summaryResynthesizer.typeProvider.dynamicType; | 927 summaryResynthesizer.typeProvider.dynamicType; |
| 917 } else { | 928 } else { |
| 918 parameterElement.type = buildType(serializedParameter.type); | 929 parameterElement.type = |
| 930 buildLinkedType(serializedParameter.inferredTypeSlot) ?? | |
| 931 buildType(serializedParameter.type); | |
| 919 } | 932 } |
| 920 parameterElement.hasImplicitType = serializedParameter.type == null; | 933 parameterElement.hasImplicitType = serializedParameter.type == null; |
| 921 } | 934 } |
| 922 switch (serializedParameter.kind) { | 935 switch (serializedParameter.kind) { |
| 923 case UnlinkedParamKind.named: | 936 case UnlinkedParamKind.named: |
| 924 parameterElement.parameterKind = ParameterKind.NAMED; | 937 parameterElement.parameterKind = ParameterKind.NAMED; |
| 925 break; | 938 break; |
| 926 case UnlinkedParamKind.positional: | 939 case UnlinkedParamKind.positional: |
| 927 parameterElement.parameterKind = ParameterKind.POSITIONAL; | 940 parameterElement.parameterKind = ParameterKind.POSITIONAL; |
| 928 break; | 941 break; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 950 partUnit.uri = uri; | 963 partUnit.uri = uri; |
| 951 return partUnit; | 964 return partUnit; |
| 952 } | 965 } |
| 953 | 966 |
| 954 /** | 967 /** |
| 955 * Build a [DartType] object based on a [EntityRef]. This [DartType] | 968 * Build a [DartType] object based on a [EntityRef]. This [DartType] |
| 956 * may refer to elements in other libraries than the library being | 969 * may refer to elements in other libraries than the library being |
| 957 * deserialized, so handles are used to avoid having to deserialize other | 970 * deserialized, so handles are used to avoid having to deserialize other |
| 958 * libraries in the process. | 971 * libraries in the process. |
| 959 */ | 972 */ |
| 960 DartType buildType(EntityRef type) { | 973 DartType buildType(EntityRef type, {bool defaultVoid: false}) { |
| 961 if (type == null) { | 974 if (type == null) { |
| 962 return summaryResynthesizer.typeProvider.dynamicType; | 975 if (defaultVoid) { |
| 976 return VoidTypeImpl.instance; | |
| 977 } else { | |
| 978 return summaryResynthesizer.typeProvider.dynamicType; | |
| 979 } | |
| 963 } | 980 } |
| 964 if (type.paramReference != 0) { | 981 if (type.paramReference != 0) { |
| 965 // TODO(paulberry): make this work for generic methods. | 982 // TODO(paulberry): make this work for generic methods. |
| 966 return currentTypeParameters[ | 983 return currentTypeParameters[ |
| 967 currentTypeParameters.length - type.paramReference].type; | 984 currentTypeParameters.length - type.paramReference].type; |
| 968 } else { | 985 } else { |
| 969 // TODO(paulberry): handle references to things other than classes (note: | 986 // TODO(paulberry): handle references to things other than classes (note: |
| 970 // this should only occur in the case of erroneous code). | 987 // this should only occur in the case of erroneous code). |
| 971 // TODO(paulberry): test reference to something inside a part. | 988 // TODO(paulberry): test reference to something inside a part. |
| 972 // TODO(paulberry): test reference to something inside a part of the | 989 // TODO(paulberry): test reference to something inside a part of the |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1105 buildImplicitAccessors(element, holder); | 1122 buildImplicitAccessors(element, holder); |
| 1106 fields[element.name] = element; | 1123 fields[element.name] = element; |
| 1107 } | 1124 } |
| 1108 } | 1125 } |
| 1109 | 1126 |
| 1110 /** | 1127 /** |
| 1111 * Handle the parts that are common to top level variables and fields. | 1128 * Handle the parts that are common to top level variables and fields. |
| 1112 */ | 1129 */ |
| 1113 void buildVariableCommonParts(PropertyInducingElementImpl element, | 1130 void buildVariableCommonParts(PropertyInducingElementImpl element, |
| 1114 UnlinkedVariable serializedVariable) { | 1131 UnlinkedVariable serializedVariable) { |
| 1115 element.type = buildType(serializedVariable.type); | 1132 element.type = buildLinkedType(serializedVariable.inferredTypeSlot) ?? |
| 1133 buildType(serializedVariable.type); | |
| 1116 element.const3 = serializedVariable.isConst; | 1134 element.const3 = serializedVariable.isConst; |
| 1117 element.final2 = serializedVariable.isFinal; | 1135 element.final2 = serializedVariable.isFinal; |
| 1118 element.hasImplicitType = serializedVariable.type == null; | 1136 element.hasImplicitType = serializedVariable.type == null; |
| 1119 element.propagatedType = | 1137 element.propagatedType = |
| 1120 buildLinkedType(serializedVariable.propagatedTypeSlot); | 1138 buildLinkedType(serializedVariable.propagatedTypeSlot); |
| 1121 buildDocumentation(element, serializedVariable.documentationComment); | 1139 buildDocumentation(element, serializedVariable.documentationComment); |
| 1122 } | 1140 } |
| 1123 | 1141 |
| 1124 /** | 1142 /** |
| 1125 * Finish creating a [TypeParameterElement] by deserializing its bound. | 1143 * Finish creating a [TypeParameterElement] by deserializing its bound. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1205 for (PropertyAccessorElementImpl accessor in unit.accessors) { | 1223 for (PropertyAccessorElementImpl accessor in unit.accessors) { |
| 1206 elementMap[accessor.identifier] = accessor; | 1224 elementMap[accessor.identifier] = accessor; |
| 1207 } | 1225 } |
| 1208 resummarizedElements[absoluteUri] = elementMap; | 1226 resummarizedElements[absoluteUri] = elementMap; |
| 1209 unitHolder = null; | 1227 unitHolder = null; |
| 1210 linkedUnit = null; | 1228 linkedUnit = null; |
| 1211 unlinkedUnit = null; | 1229 unlinkedUnit = null; |
| 1212 linkedTypeMap = null; | 1230 linkedTypeMap = null; |
| 1213 } | 1231 } |
| 1214 } | 1232 } |
| OLD | NEW |