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

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

Issue 1949833002: Fix a corner case of AST-based type inference with sequences of identifiers separated by '.'. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /** 5 /**
6 * This library is capable of producing linked summaries from unlinked 6 * This library is capable of producing linked summaries from unlinked
7 * ones (or prelinked ones). It functions by building a miniature 7 * ones (or prelinked ones). It functions by building a miniature
8 * element model to represent the contents of the summaries, and then 8 * element model to represent the contents of the summaries, and then
9 * scanning the element model to gather linked information and adding 9 * scanning the element model to gather linked information and adding
10 * it to the summary data structures. 10 * it to the summary data structures.
(...skipping 3234 matching lines...) Expand 10 before | Expand all | Expand 10 after
3245 /** 3245 /**
3246 * Compute the dependencies of this node. 3246 * Compute the dependencies of this node.
3247 */ 3247 */
3248 List<NodeType> computeDependencies(); 3248 List<NodeType> computeDependencies();
3249 } 3249 }
3250 3250
3251 /** 3251 /**
3252 * Element used for references that result from trying to access a non-static 3252 * Element used for references that result from trying to access a non-static
3253 * member of an element that is not a container (e.g. accessing the "length" 3253 * member of an element that is not a container (e.g. accessing the "length"
3254 * property of a constant). 3254 * property of a constant).
3255 *
3256 * Also handles accesses to a chain of non-static members separated by '.'.
3255 */ 3257 */
3256 class NonstaticMemberElementForLink implements ReferenceableElementForLink { 3258 class NonstaticMemberElementForLink implements ReferenceableElementForLink {
3257 /** 3259 /**
3258 * The non-static element of this link element. 3260 * The static variable element from which the non-static member access begins.
3259 */ 3261 */
3260 final Element element; 3262 final VariableElementForLink _variable;
3261 3263
3262 /** 3264 /**
3263 * If the thing from which a member was accessed is a constant, the 3265 * The list of non-static members that are accessed.
3264 * associated [ConstNode]. Otherwise `null`.
3265 */ 3266 */
3266 final ConstVariableNode _constNode; 3267 final List<String> _names;
3267 3268
3268 NonstaticMemberElementForLink(this.element, this._constNode); 3269 /**
3270 * The library in which the access occurs. This determines whether private
3271 * names are accessible.
3272 */
3273 final LibraryElementForLink _library;
3274
3275 NonstaticMemberElementForLink(this._library, this._variable, this._names);
3269 3276
3270 @override 3277 @override
3271 ConstructorElementForLink get asConstructor => null; 3278 ConstructorElementForLink get asConstructor => null;
3272 3279
3273 @override 3280 @override
3274 ConstVariableNode get asConstVariable => _constNode; 3281 ConstVariableNode get asConstVariable => _variable._constNode;
3275 3282
3276 @override 3283 @override
3277 DartType get asStaticType { 3284 DartType get asStaticType {
3278 Element element = this.element; 3285 if (_library._linker.strongMode) {
3279 if (element is PropertyAccessorElement) { 3286 DartType type = _variable.asStaticType;
3280 if (element.isGetter) { 3287 for (String name in _names) {
3281 return element.returnType; 3288 type = _typeLookupStep(type, name);
3282 } 3289 }
3283 return DynamicTypeImpl.instance; 3290 return type;
3284 } 3291 }
3285 if (element is MethodElement) { 3292 // TODO(paulberry, scheglov): implement for propagated types
3286 return element.type;
3287 }
3288 return DynamicTypeImpl.instance; 3293 return DynamicTypeImpl.instance;
3289 } 3294 }
3290 3295
3291 @override 3296 @override
3292 TypeInferenceNode get asTypeInferenceNode { 3297 TypeInferenceNode get asTypeInferenceNode => _variable._typeInferenceNode;
3293 // TODO(paulberry): implement.
3294 return null;
3295 }
3296 3298
3297 @override 3299 @override
3298 DartType buildType(DartType getTypeArgument(int i), 3300 DartType buildType(DartType getTypeArgument(int i),
3299 List<int> implicitFunctionTypeIndices) => 3301 List<int> implicitFunctionTypeIndices) =>
3300 DynamicTypeImpl.instance; 3302 DynamicTypeImpl.instance;
3301 3303
3302 @override 3304 @override
3303 ReferenceableElementForLink getContainedName(String name) { 3305 ReferenceableElementForLink getContainedName(String name) {
3304 if (element != null) { 3306 return new NonstaticMemberElementForLink(
3305 DartType type = asStaticType; 3307 _library, _variable, _names.toList()..add(name));
3306 if (type is InterfaceType) { 3308 }
3307 Element nameElement = type.lookUpGetter(name, element.library); 3309
3308 nameElement ??= type.lookUpMethod(name, element.library); 3310 /**
3309 return new NonstaticMemberElementForLink(nameElement, _constNode); 3311 * Perform a single step in the resolution of the non-static access, looking
3312 * up in [type] for the nonstatic entity having the given [name]. Return the
3313 * type of the entity that was found, or `dynamic` if no entity was found.
3314 */
3315 DartType _typeLookupStep(DartType type, String name) {
3316 if (type is InterfaceType) {
3317 PropertyAccessorElement getter = type.lookUpGetter(name, _library);
3318 if (getter != null) {
3319 return getter.returnType;
3320 }
3321 MethodElement method = type.lookUpMethod(name, _library);
3322 if (method != null) {
3323 return method.type;
3310 } 3324 }
3311 } 3325 }
3312 return this; 3326 // TODO(paulberry): handle .call on function types and .toString or .hashCod e on all types.
3327 return DynamicTypeImpl.instance;
3313 } 3328 }
3314 } 3329 }
3315 3330
3316 /** 3331 /**
3317 * Element representing a function or method parameter resynthesized 3332 * Element representing a function or method parameter resynthesized
3318 * from a summary during linking. 3333 * from a summary during linking.
3319 */ 3334 */
3320 class ParameterElementForLink implements ParameterElementImpl { 3335 class ParameterElementForLink implements ParameterElementImpl {
3321 /** 3336 /**
3322 * The unlinked representation of the parameter in the summary. 3337 * The unlinked representation of the parameter in the summary.
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
3656 // (even if we have already computed it), since that would lead to 3671 // (even if we have already computed it), since that would lead to
3657 // non-deterministic type inference results. 3672 // non-deterministic type inference results.
3658 return DynamicTypeImpl.instance; 3673 return DynamicTypeImpl.instance;
3659 } else { 3674 } else {
3660 return variable.type; 3675 return variable.type;
3661 } 3676 }
3662 } 3677 }
3663 3678
3664 @override 3679 @override
3665 ReferenceableElementForLink getContainedName(String name) { 3680 ReferenceableElementForLink getContainedName(String name) {
3666 Element element = variable._getContainedElement(name); 3681 return new NonstaticMemberElementForLink(library, variable, <String>[name]);
3667 return new NonstaticMemberElementForLink(element, variable._constNode);
3668 } 3682 }
3669 3683
3670 @override 3684 @override
3671 bool isAccessibleIn(LibraryElement library) => 3685 bool isAccessibleIn(LibraryElement library) =>
3672 !Identifier.isPrivateName(name) || identical(this.library, library); 3686 !Identifier.isPrivateName(name) || identical(this.library, library);
3673 3687
3674 @override 3688 @override
3675 void link(CompilationUnitElementInBuildUnit compilationUnit) {} 3689 void link(CompilationUnitElementInBuildUnit compilationUnit) {}
3676 3690
3677 @override 3691 @override
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3828 @override 3842 @override
3829 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 3843 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
3830 } 3844 }
3831 3845
3832 /** 3846 /**
3833 * Element representing a top level variable resynthesized from a 3847 * Element representing a top level variable resynthesized from a
3834 * summary during linking. 3848 * summary during linking.
3835 */ 3849 */
3836 class TopLevelVariableElementForLink extends VariableElementForLink 3850 class TopLevelVariableElementForLink extends VariableElementForLink
3837 implements TopLevelVariableElement { 3851 implements TopLevelVariableElement {
3838 TopLevelVariableElementForLink(CompilationUnitElement enclosingElement, 3852 TopLevelVariableElementForLink(CompilationUnitElementForLink enclosingElement,
3839 UnlinkedVariable unlinkedVariable) 3853 UnlinkedVariable unlinkedVariable)
3840 : super(unlinkedVariable, enclosingElement); 3854 : super(unlinkedVariable, enclosingElement);
3841 3855
3842 @override 3856 @override
3843 bool get isStatic => true; 3857 bool get isStatic => true;
3844 3858
3845 @override 3859 @override
3860 LibraryElementForLink get library => compilationUnit.library;
3861
3862 @override
3846 TypeParameterizedElementForLink get _typeParameterContext => null; 3863 TypeParameterizedElementForLink get _typeParameterContext => null;
3847 3864
3848 /** 3865 /**
3849 * Store the results of type inference for this variable in 3866 * Store the results of type inference for this variable in
3850 * [compilationUnit]. 3867 * [compilationUnit].
3851 */ 3868 */
3852 void link(CompilationUnitElementInBuildUnit compilationUnit) { 3869 void link(CompilationUnitElementInBuildUnit compilationUnit) {
3853 if (hasImplicitType) { 3870 if (hasImplicitType) {
3854 TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode; 3871 TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
3855 if (typeInferenceNode != null) { 3872 if (typeInferenceNode != null) {
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
4417 * there are no type parameters in scope. 4434 * there are no type parameters in scope.
4418 */ 4435 */
4419 TypeParameterizedElementForLink get _typeParameterContext; 4436 TypeParameterizedElementForLink get _typeParameterContext;
4420 4437
4421 @override 4438 @override
4422 DartType buildType(DartType getTypeArgument(int i), 4439 DartType buildType(DartType getTypeArgument(int i),
4423 List<int> implicitFunctionTypeIndices) => 4440 List<int> implicitFunctionTypeIndices) =>
4424 DynamicTypeImpl.instance; 4441 DynamicTypeImpl.instance;
4425 4442
4426 ReferenceableElementForLink getContainedName(String name) { 4443 ReferenceableElementForLink getContainedName(String name) {
4427 Element element = _getContainedElement(name); 4444 return new NonstaticMemberElementForLink(library, this, <String>[name]);
4428 return new NonstaticMemberElementForLink(element, _constNode);
4429 } 4445 }
4430 4446
4431 @override 4447 @override
4432 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 4448 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
4433
4434 /**
4435 * Return the contained element with the given [name], or `null` if the lookup
4436 * fails. Currently only static types are supported in the linker, so lookup
4437 * is performed only in the strong mode.
4438 */
4439 Element _getContainedElement(String name) {
4440 Linker linker = compilationUnit.library._linker;
4441 if (linker.strongMode) {
4442 DartType type = asStaticType;
4443 if (type is InterfaceType) {
4444 Element result = type.lookUpGetter(name, compilationUnit.library);
4445 result ??= type.lookUpMethod(name, compilationUnit.library);
4446 return result;
4447 }
4448 }
4449 // TODO(scheglov): implement for propagated types
4450 return null;
4451 }
4452 } 4449 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698