| 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/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 * Type parameters for the generic class, typedef, or executable currently | 260 * Type parameters for the generic class, typedef, or executable currently |
| 261 * being resynthesized, if any. If multiple entities with type parameters | 261 * being resynthesized, if any. If multiple entities with type parameters |
| 262 * are nested (e.g. a generic executable inside a generic class), this is the | 262 * are nested (e.g. a generic executable inside a generic class), this is the |
| 263 * concatenation of all type parameters from all declarations currently in | 263 * concatenation of all type parameters from all declarations currently in |
| 264 * force, with the outermost declaration appearing first. If there are no | 264 * force, with the outermost declaration appearing first. If there are no |
| 265 * type parameters, or we are not currently resynthesizing a class, typedef, | 265 * type parameters, or we are not currently resynthesizing a class, typedef, |
| 266 * or executable, then this is an empty list. | 266 * or executable, then this is an empty list. |
| 267 */ | 267 */ |
| 268 List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[]; | 268 List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[]; |
| 269 | 269 |
| 270 /** |
| 271 * If a class is currently being resynthesized, map from field name to the |
| 272 * type of the corresponding field. This is used to populate the types of |
| 273 * initializing formal parameters whose type is implicit. |
| 274 */ |
| 275 Map<String, DartType> fieldTypes; |
| 276 |
| 270 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, | 277 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, |
| 271 this.unlinkedUnits, this.librarySource) { | 278 this.unlinkedUnits, this.librarySource) { |
| 272 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; | 279 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; |
| 273 } | 280 } |
| 274 | 281 |
| 275 /** | 282 /** |
| 276 * Return a list of type arguments corresponding to [currentTypeParameters]. | 283 * Return a list of type arguments corresponding to [currentTypeParameters]. |
| 277 */ | 284 */ |
| 278 List<TypeParameterType> get currentTypeArguments => currentTypeParameters | 285 List<TypeParameterType> get currentTypeArguments => currentTypeParameters |
| 279 ?.map((TypeParameterElement param) => param.type) | 286 ?.map((TypeParameterElement param) => param.type) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 301 delayedObjectSubclasses.add(classElement); | 308 delayedObjectSubclasses.add(classElement); |
| 302 } else { | 309 } else { |
| 303 classElement.supertype = summaryResynthesizer.typeProvider.objectType; | 310 classElement.supertype = summaryResynthesizer.typeProvider.objectType; |
| 304 } | 311 } |
| 305 } | 312 } |
| 306 classElement.interfaces = | 313 classElement.interfaces = |
| 307 serializedClass.interfaces.map(buildType).toList(); | 314 serializedClass.interfaces.map(buildType).toList(); |
| 308 classElement.mixins = serializedClass.mixins.map(buildType).toList(); | 315 classElement.mixins = serializedClass.mixins.map(buildType).toList(); |
| 309 classElement.typeParameters = currentTypeParameters; | 316 classElement.typeParameters = currentTypeParameters; |
| 310 ElementHolder memberHolder = new ElementHolder(); | 317 ElementHolder memberHolder = new ElementHolder(); |
| 318 fieldTypes = <String, DartType>{}; |
| 319 for (UnlinkedVariable serializedVariable in serializedClass.fields) { |
| 320 buildVariable(serializedVariable, memberHolder); |
| 321 } |
| 311 bool constructorFound = false; | 322 bool constructorFound = false; |
| 312 for (UnlinkedExecutable serializedExecutable | 323 for (UnlinkedExecutable serializedExecutable |
| 313 in serializedClass.executables) { | 324 in serializedClass.executables) { |
| 314 switch (serializedExecutable.kind) { | 325 switch (serializedExecutable.kind) { |
| 315 case UnlinkedExecutableKind.constructor: | 326 case UnlinkedExecutableKind.constructor: |
| 316 constructorFound = true; | 327 constructorFound = true; |
| 317 buildConstructor( | 328 buildConstructor( |
| 318 serializedExecutable, memberHolder, correspondingType); | 329 serializedExecutable, memberHolder, correspondingType); |
| 319 break; | 330 break; |
| 320 case UnlinkedExecutableKind.functionOrMethod: | 331 case UnlinkedExecutableKind.functionOrMethod: |
| 321 case UnlinkedExecutableKind.getter: | 332 case UnlinkedExecutableKind.getter: |
| 322 case UnlinkedExecutableKind.setter: | 333 case UnlinkedExecutableKind.setter: |
| 323 buildExecutable(serializedExecutable, memberHolder); | 334 buildExecutable(serializedExecutable, memberHolder); |
| 324 break; | 335 break; |
| 325 } | 336 } |
| 326 } | 337 } |
| 327 for (UnlinkedVariable serializedVariable in serializedClass.fields) { | |
| 328 buildVariable(serializedVariable, memberHolder); | |
| 329 } | |
| 330 if (!serializedClass.isMixinApplication) { | 338 if (!serializedClass.isMixinApplication) { |
| 331 if (!constructorFound) { | 339 if (!constructorFound) { |
| 332 // Synthesize implicit constructors. | 340 // Synthesize implicit constructors. |
| 333 ConstructorElementImpl constructor = | 341 ConstructorElementImpl constructor = |
| 334 new ConstructorElementImpl('', -1); | 342 new ConstructorElementImpl('', -1); |
| 335 constructor.synthetic = true; | 343 constructor.synthetic = true; |
| 336 constructor.returnType = correspondingType; | 344 constructor.returnType = correspondingType; |
| 337 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs( | 345 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 338 constructor, null, currentTypeArguments, false); | 346 constructor, null, currentTypeArguments, false); |
| 339 memberHolder.addConstructor(constructor); | 347 memberHolder.addConstructor(constructor); |
| 340 } | 348 } |
| 341 classElement.constructors = memberHolder.constructors; | 349 classElement.constructors = memberHolder.constructors; |
| 342 } | 350 } |
| 343 classElement.accessors = memberHolder.accessors; | 351 classElement.accessors = memberHolder.accessors; |
| 344 classElement.fields = memberHolder.fields; | 352 classElement.fields = memberHolder.fields; |
| 345 classElement.methods = memberHolder.methods; | 353 classElement.methods = memberHolder.methods; |
| 346 correspondingType.typeArguments = currentTypeArguments; | 354 correspondingType.typeArguments = currentTypeArguments; |
| 347 classElement.type = correspondingType; | 355 classElement.type = correspondingType; |
| 348 buildDocumentation(classElement, serializedClass.documentationComment); | 356 buildDocumentation(classElement, serializedClass.documentationComment); |
| 349 unitHolder.addType(classElement); | 357 unitHolder.addType(classElement); |
| 350 } finally { | 358 } finally { |
| 351 currentTypeParameters = <TypeParameterElement>[]; | 359 currentTypeParameters = <TypeParameterElement>[]; |
| 360 fieldTypes = null; |
| 352 } | 361 } |
| 353 } | 362 } |
| 354 | 363 |
| 355 /** | 364 /** |
| 356 * Resynthesize a [NamespaceCombinator]. | 365 * Resynthesize a [NamespaceCombinator]. |
| 357 */ | 366 */ |
| 358 NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) { | 367 NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) { |
| 359 if (serializedCombinator.shows.isNotEmpty) { | 368 if (serializedCombinator.shows.isNotEmpty) { |
| 360 ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl(); | 369 ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl(); |
| 361 // Note: we call toList() so that we don't retain a reference to the | 370 // Note: we call toList() so that we don't retain a reference to the |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 parameterTypeElement.enclosingElement = parameterElement; | 856 parameterTypeElement.enclosingElement = parameterElement; |
| 848 parameterTypeElement.shareParameters(parameterElement.parameters); | 857 parameterTypeElement.shareParameters(parameterElement.parameters); |
| 849 if (serializedParameter.type != null) { | 858 if (serializedParameter.type != null) { |
| 850 parameterTypeElement.returnType = buildType(serializedParameter.type); | 859 parameterTypeElement.returnType = buildType(serializedParameter.type); |
| 851 } else { | 860 } else { |
| 852 parameterTypeElement.returnType = VoidTypeImpl.instance; | 861 parameterTypeElement.returnType = VoidTypeImpl.instance; |
| 853 } | 862 } |
| 854 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( | 863 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 855 parameterTypeElement, null, currentTypeArguments, false); | 864 parameterTypeElement, null, currentTypeArguments, false); |
| 856 } else { | 865 } else { |
| 857 parameterElement.type = buildType(serializedParameter.type); | 866 if (serializedParameter.isInitializingFormal && |
| 867 serializedParameter.hasImplicitType) { |
| 868 // The type is inherited from the matching field. |
| 869 parameterElement.type = fieldTypes[serializedParameter.name] ?? |
| 870 summaryResynthesizer.typeProvider.dynamicType; |
| 871 } else { |
| 872 parameterElement.type = buildType(serializedParameter.type); |
| 873 } |
| 858 parameterElement.hasImplicitType = serializedParameter.hasImplicitType; | 874 parameterElement.hasImplicitType = serializedParameter.hasImplicitType; |
| 859 } | 875 } |
| 860 switch (serializedParameter.kind) { | 876 switch (serializedParameter.kind) { |
| 861 case UnlinkedParamKind.named: | 877 case UnlinkedParamKind.named: |
| 862 parameterElement.parameterKind = ParameterKind.NAMED; | 878 parameterElement.parameterKind = ParameterKind.NAMED; |
| 863 break; | 879 break; |
| 864 case UnlinkedParamKind.positional: | 880 case UnlinkedParamKind.positional: |
| 865 parameterElement.parameterKind = ParameterKind.POSITIONAL; | 881 parameterElement.parameterKind = ParameterKind.POSITIONAL; |
| 866 break; | 882 break; |
| 867 case UnlinkedParamKind.required: | 883 case UnlinkedParamKind.required: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 892 /** | 908 /** |
| 893 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] | 909 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] |
| 894 * may refer to elements in other libraries than the library being | 910 * may refer to elements in other libraries than the library being |
| 895 * deserialized, so handles are used to avoid having to deserialize other | 911 * deserialized, so handles are used to avoid having to deserialize other |
| 896 * libraries in the process. | 912 * libraries in the process. |
| 897 */ | 913 */ |
| 898 DartType buildType(UnlinkedTypeRef type) { | 914 DartType buildType(UnlinkedTypeRef type) { |
| 899 if (type.paramReference != 0) { | 915 if (type.paramReference != 0) { |
| 900 // TODO(paulberry): make this work for generic methods. | 916 // TODO(paulberry): make this work for generic methods. |
| 901 return currentTypeParameters[ | 917 return currentTypeParameters[ |
| 902 currentTypeParameters.length - type.paramReference] | 918 currentTypeParameters.length - type.paramReference].type; |
| 903 .type; | |
| 904 } else { | 919 } else { |
| 905 // TODO(paulberry): handle references to things other than classes (note: | 920 // TODO(paulberry): handle references to things other than classes (note: |
| 906 // this should only occur in the case of erroneous code). | 921 // this should only occur in the case of erroneous code). |
| 907 // TODO(paulberry): test reference to something inside a part. | 922 // TODO(paulberry): test reference to something inside a part. |
| 908 // TODO(paulberry): test reference to something inside a part of the | 923 // TODO(paulberry): test reference to something inside a part of the |
| 909 // current lib. | 924 // current lib. |
| 910 UnlinkedReference reference = unlinkedUnit.references[type.reference]; | 925 UnlinkedReference reference = unlinkedUnit.references[type.reference]; |
| 911 LinkedReference referenceResolution = | 926 LinkedReference referenceResolution = |
| 912 linkedUnit.references[type.reference]; | 927 linkedUnit.references[type.reference]; |
| 913 ElementLocationImpl location; | 928 ElementLocationImpl location; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 buildVariableCommonParts(element, serializedVariable); | 1044 buildVariableCommonParts(element, serializedVariable); |
| 1030 unitHolder.addTopLevelVariable(element); | 1045 unitHolder.addTopLevelVariable(element); |
| 1031 buildImplicitAccessors(element, unitHolder); | 1046 buildImplicitAccessors(element, unitHolder); |
| 1032 } else { | 1047 } else { |
| 1033 FieldElementImpl element = new FieldElementImpl( | 1048 FieldElementImpl element = new FieldElementImpl( |
| 1034 serializedVariable.name, serializedVariable.nameOffset); | 1049 serializedVariable.name, serializedVariable.nameOffset); |
| 1035 buildVariableCommonParts(element, serializedVariable); | 1050 buildVariableCommonParts(element, serializedVariable); |
| 1036 element.static = serializedVariable.isStatic; | 1051 element.static = serializedVariable.isStatic; |
| 1037 holder.addField(element); | 1052 holder.addField(element); |
| 1038 buildImplicitAccessors(element, holder); | 1053 buildImplicitAccessors(element, holder); |
| 1054 fieldTypes[element.name] = element.type; |
| 1039 } | 1055 } |
| 1040 } | 1056 } |
| 1041 | 1057 |
| 1042 /** | 1058 /** |
| 1043 * Handle the parts that are common to top level variables and fields. | 1059 * Handle the parts that are common to top level variables and fields. |
| 1044 */ | 1060 */ |
| 1045 void buildVariableCommonParts(PropertyInducingElementImpl element, | 1061 void buildVariableCommonParts(PropertyInducingElementImpl element, |
| 1046 UnlinkedVariable serializedVariable) { | 1062 UnlinkedVariable serializedVariable) { |
| 1047 element.type = buildType(serializedVariable.type); | 1063 element.type = buildType(serializedVariable.type); |
| 1048 element.const3 = serializedVariable.isConst; | 1064 element.const3 = serializedVariable.isConst; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 } | 1146 } |
| 1131 for (PropertyAccessorElementImpl accessor in unit.accessors) { | 1147 for (PropertyAccessorElementImpl accessor in unit.accessors) { |
| 1132 elementMap[accessor.identifier] = accessor; | 1148 elementMap[accessor.identifier] = accessor; |
| 1133 } | 1149 } |
| 1134 resummarizedElements[absoluteUri] = elementMap; | 1150 resummarizedElements[absoluteUri] = elementMap; |
| 1135 unitHolder = null; | 1151 unitHolder = null; |
| 1136 linkedUnit = null; | 1152 linkedUnit = null; |
| 1137 unlinkedUnit = null; | 1153 unlinkedUnit = null; |
| 1138 } | 1154 } |
| 1139 } | 1155 } |
| OLD | NEW |