From ebdee7ee0f1fbcaf2d9451137e649a143d201d72 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 28 Mar 2018 16:54:44 +0000 Subject: [PATCH] More prep work to allow the linker to re-use resolution logic. See #32525. This CL makes the following changes: - Extracts the logic from AbstractClassElementImpl.getSetter to a static method so it can be re-used by the summary linker. - Modifies ParameterElementImpl._resynthesizeTypeAndParameters so that it avoids unnecessary calls to resolveLinkedType. This is crucial because resolveLinkedType is not available when linking. - Makes it possible to suppress reporting of const evaluation errors when doing resolution. This is necessary because in order to report these errors we must do constant evaluation, which is not possible during summary linking. - Modifies ResolverVisitor._hasSerializedConstantInitializer to avoid unnecessary calls to LibraryElementImpl.hasResolutionCapability. This is crucial because the linker contains an implementation of LibraryElementImpl that's incompatible with LibraryElementImpl.hasResolutionCapability. Change-Id: Iec91bd8d6a68193e091c2438bafcd7cb15488d89 Reviewed-on: https://dart-review.googlesource.com/48681 Reviewed-by: Konstantin Shcheglov Commit-Queue: Paul Berry --- .../lib/src/dart/element/element.dart | 35 +++++++++++-------- .../lib/src/generated/element_resolver.dart | 9 +++-- pkg/analyzer/lib/src/generated/resolver.dart | 22 ++++++------ 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 9a0e0b17843..7daaf3426f0 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -197,18 +197,7 @@ abstract class AbstractClassElementImpl extends ElementImpl @override PropertyAccessorElement getSetter(String setterName) { - // TODO (jwren) revisit- should we append '=' here or require clients to - // include it? - // Do we need the check for isSetter below? - if (!StringUtilities.endsWithChar(setterName, 0x3D)) { - setterName += '='; - } - for (PropertyAccessorElement accessor in accessors) { - if (accessor.isSetter && accessor.name == setterName) { - return accessor; - } - } - return null; + return getSetterFromAccessors(setterName, accessors); } @override @@ -394,6 +383,22 @@ abstract class AbstractClassElementImpl extends ElementImpl } return classElement as AbstractClassElementImpl; } + + static PropertyAccessorElement getSetterFromAccessors( + String setterName, List accessors) { + // TODO (jwren) revisit- should we append '=' here or require clients to + // include it? + // Do we need the check for isSetter below? + if (!StringUtilities.endsWithChar(setterName, 0x3D)) { + setterName += '='; + } + for (PropertyAccessorElement accessor in accessors) { + if (accessor.isSetter && accessor.name == setterName) { + return accessor; + } + } + return null; + } } /** @@ -8463,8 +8468,10 @@ class ParameterElementImpl extends VariableElementImpl _type = new FunctionTypeImpl(typeElement); typeElement.type = _type; } else { - _type = enclosingUnit.resynthesizerContext - .resolveLinkedType(this, _unlinkedParam.inferredTypeSlot); + if (_unlinkedParam.inferredTypeSlot != 0) { + _type = enclosingUnit.resynthesizerContext + .resolveLinkedType(this, _unlinkedParam.inferredTypeSlot); + } declaredType = enclosingUnit.resynthesizerContext .resolveTypeRef(this, _unlinkedParam.type, declaredType: true); } diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart index 7b3f43690e8..30d1a57f96c 100644 --- a/pkg/analyzer/lib/src/generated/element_resolver.dart +++ b/pkg/analyzer/lib/src/generated/element_resolver.dart @@ -120,11 +120,14 @@ class ElementResolver extends SimpleAstVisitor { */ TypePromotionManager _promoteManager; + /// Whether constant evaluation errors should be reported during resolution. + final bool reportConstEvaluationErrors; + /** * Initialize a newly created visitor to work for the given [_resolver] to * resolve the nodes in a compilation unit. */ - ElementResolver(this._resolver) { + ElementResolver(this._resolver, {this.reportConstEvaluationErrors: true}) { this._definingLibrary = _resolver.definingLibrary; AnalysisOptions options = _definingLibrary.context.analysisOptions; _enableHints = options.hint; @@ -578,7 +581,9 @@ class ElementResolver extends SimpleAstVisitor { node.staticElement = invokedConstructor; ArgumentList argumentList = node.argumentList; List parameters = _resolveArgumentsToFunction( - node.isConst, argumentList, invokedConstructor); + reportConstEvaluationErrors && node.isConst, + argumentList, + invokedConstructor); if (parameters != null) { argumentList.correspondingStaticParameters = parameters; } diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index 8592273abfd..3348af7b5b7 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -4983,12 +4983,15 @@ class ResolverVisitor extends ScopedVisitor { */ ResolverVisitor(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener, - {Scope nameScope}) + {Scope nameScope, + bool propagateTypes: true, + reportConstEvaluationErrors: true}) : super(definingLibrary, source, typeProvider, errorListener, nameScope: nameScope) { AnalysisOptions options = definingLibrary.context.analysisOptions; this.strongMode = options.strongMode; - this.elementResolver = new ElementResolver(this); + this.elementResolver = new ElementResolver(this, + reportConstEvaluationErrors: reportConstEvaluationErrors); this.typeSystem = definingLibrary.context.typeSystem; bool strongModeHints = false; if (options is AnalysisOptionsImpl) { @@ -6597,15 +6600,12 @@ class ResolverVisitor extends ScopedVisitor { * serialized. */ bool _hasSerializedConstantInitializer(ParameterElement parameter) { - if (LibraryElementImpl.hasResolutionCapability( - definingLibrary, LibraryResolutionCapability.constantExpressions)) { - Element executable = parameter.enclosingElement; - if (executable is MethodElement) { - return true; - } - if (executable is FunctionElement) { - return executable.enclosingElement is CompilationUnitElement; - } + Element executable = parameter.enclosingElement; + if (executable is MethodElement || + executable is FunctionElement && + executable.enclosingElement is CompilationUnitElement) { + return LibraryElementImpl.hasResolutionCapability( + definingLibrary, LibraryResolutionCapability.constantExpressions); } return false; }