| Index: pkg/analyzer/lib/src/kernel/resynthesize.dart
|
| diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart
|
| index 7fc95a00e6e41bdfbbab97bc99012a426ab3719f..d3d0286bb3243a57e12e82b237ed2cb2116845db 100644
|
| --- a/pkg/analyzer/lib/src/kernel/resynthesize.dart
|
| +++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart
|
| @@ -48,18 +48,105 @@ class KernelResynthesizer {
|
|
|
| var libraryContext =
|
| new _KernelLibraryResynthesizerContextImpl(this, kernel);
|
| - Source librarySource = _getSource(uriStr);
|
| - LibraryElementImpl libraryElement =
|
| - new LibraryElementImpl.forKernel(_analysisContext, libraryContext);
|
| - CompilationUnitElementImpl definingUnit =
|
| - libraryElement.definingCompilationUnit;
|
| - definingUnit.source = librarySource;
|
| - definingUnit.librarySource = librarySource;
|
| + LibraryElementImpl libraryElement = libraryContext._buildLibrary(uriStr);
|
| +
|
| + // Build the defining unit.
|
| + var definingUnit = libraryContext._buildUnit(null).unit;
|
| + libraryElement.definingCompilationUnit = definingUnit;
|
| +
|
| + // Build units for parts.
|
| + var parts = new List<CompilationUnitElementImpl>(kernel.parts.length);
|
| + for (int i = 0; i < kernel.parts.length; i++) {
|
| + var fileUri = kernel.parts[i].fileUri;
|
| + var unitContext = libraryContext._buildUnit(fileUri);
|
| + parts[i] = unitContext.unit;
|
| + }
|
| + libraryElement.parts = parts;
|
| +
|
| return libraryElement;
|
| });
|
| }
|
|
|
| /**
|
| + * Return the [ElementImpl] that corresponds to the given [name], or `null`
|
| + * if the corresponding element cannot be found.
|
| + */
|
| + ElementImpl _getElement(kernel.CanonicalName name) {
|
| + if (name == null) return null;
|
| + kernel.CanonicalName parentName = name.parent;
|
| +
|
| + // If the parent is the root, then this name is a library.
|
| + if (parentName.isRoot) {
|
| + return getLibrary(name.name);
|
| + }
|
| +
|
| + // If the name is private, it is prefixed with a library URI.
|
| + if (name.name.startsWith('_')) {
|
| + parentName = parentName.parent;
|
| + }
|
| +
|
| + // Skip qualifiers.
|
| + bool isGetter = false;
|
| + bool isSetter = false;
|
| + bool isField = false;
|
| + bool isConstructor = false;
|
| + bool isMethod = false;
|
| + if (parentName.name == '@getters') {
|
| + isGetter = true;
|
| + parentName = parentName.parent;
|
| + } else if (parentName.name == '@setters') {
|
| + isSetter = true;
|
| + parentName = parentName.parent;
|
| + } else if (parentName.name == '@fields') {
|
| + isField = true;
|
| + parentName = parentName.parent;
|
| + } else if (parentName.name == '@constructors') {
|
| + isConstructor = true;
|
| + parentName = parentName.parent;
|
| + } else if (parentName.name == '@methods') {
|
| + isMethod = true;
|
| + parentName = parentName.parent;
|
| + }
|
| +
|
| + ElementImpl parentElement = _getElement(parentName);
|
| + if (parentElement == null) return null;
|
| +
|
| + // Search in units of the library.
|
| + if (parentElement is LibraryElementImpl) {
|
| + for (CompilationUnitElement unit in parentElement.units) {
|
| + CompilationUnitElementImpl unitImpl = unit;
|
| + ElementImpl child = unitImpl.getChild(name.name);
|
| + if (child != null) {
|
| + return child;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + // Search in the class.
|
| + if (parentElement is AbstractClassElementImpl) {
|
| + if (isGetter) {
|
| + return parentElement.getGetter(name.name) as ElementImpl;
|
| + } else if (isSetter) {
|
| + return parentElement.getSetter(name.name) as ElementImpl;
|
| + } else if (isField) {
|
| + return parentElement.getField(name.name) as ElementImpl;
|
| + } else if (isConstructor) {
|
| + if (name.name.isEmpty) {
|
| + return parentElement.unnamedConstructor as ConstructorElementImpl;
|
| + }
|
| + return parentElement.getNamedConstructor(name.name) as ElementImpl;
|
| + } else if (isMethod) {
|
| + return parentElement.getMethod(name.name) as ElementImpl;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + throw new UnimplementedError(
|
| + 'Internal error: ${parentElement.runtimeType} unexpected.');
|
| + }
|
| +
|
| + /**
|
| * Get the [Source] object for the given [uri].
|
| */
|
| Source _getSource(String uri) {
|
| @@ -72,7 +159,7 @@ class KernelResynthesizer {
|
| * Builder of [Expression]s from [kernel.Expression]s.
|
| */
|
| class _ExprBuilder {
|
| - final _KernelLibraryResynthesizerContextImpl _context;
|
| + final _KernelUnitResynthesizerContextImpl _context;
|
| final ElementImpl _contextElement;
|
|
|
| _ExprBuilder(this._context, this._contextElement);
|
| @@ -196,7 +283,8 @@ class _ExprBuilder {
|
| if (expr is kernel.ConstructorInvocation) {
|
| var element = _getElement(expr.targetReference);
|
|
|
| - var kernelType = expr.getStaticType(_context._resynthesizer._types);
|
| + var kernelType =
|
| + expr.getStaticType(_context.libraryContext.resynthesizer._types);
|
| var type = _context.getType(_contextElement, kernelType);
|
| TypeName typeName = _buildType(type);
|
|
|
| @@ -214,7 +302,7 @@ class _ExprBuilder {
|
| var type = _context.getType(_contextElement, expr.type);
|
| var identifier = AstTestFactory.identifier3(type.element.name);
|
| identifier.staticElement = type.element;
|
| - identifier.staticType = _context._resynthesizer.typeType;
|
| + identifier.staticType = _context.libraryContext.resynthesizer.typeType;
|
| return identifier;
|
| }
|
|
|
| @@ -330,7 +418,8 @@ class _ExprBuilder {
|
| }
|
|
|
| ElementImpl _getElement(kernel.Reference reference) {
|
| - return _context._getElement(reference?.canonicalName);
|
| + return _context.libraryContext.resynthesizer
|
| + ._getElement(reference?.canonicalName);
|
| }
|
|
|
| InterpolationElement _newInterpolationElement(Expression expr) {
|
| @@ -390,16 +479,97 @@ class _ExprBuilder {
|
| */
|
| class _KernelLibraryResynthesizerContextImpl
|
| implements KernelLibraryResynthesizerContext {
|
| - final KernelResynthesizer _resynthesizer;
|
| + final KernelResynthesizer resynthesizer;
|
|
|
| @override
|
| final kernel.Library library;
|
|
|
| - _KernelLibraryResynthesizerContextImpl(this._resynthesizer, this.library);
|
| + Source librarySource;
|
| + LibraryElementImpl libraryElement;
|
| +
|
| + _KernelLibraryResynthesizerContextImpl(this.resynthesizer, this.library);
|
| +
|
| + @override
|
| + LibraryElementImpl getLibrary(String uriStr) {
|
| + return resynthesizer.getLibrary(uriStr);
|
| + }
|
| +
|
| + LibraryElementImpl _buildLibrary(String uriStr) {
|
| + librarySource = resynthesizer._getSource(uriStr);
|
| + return libraryElement =
|
| + new LibraryElementImpl.forKernel(resynthesizer._analysisContext, this);
|
| + }
|
| +
|
| + _KernelUnitResynthesizerContextImpl _buildUnit(String fileUri) {
|
| + var unitContext = new _KernelUnitResynthesizerContextImpl(
|
| + this, fileUri ?? library.fileUri);
|
| + var unitElement = new CompilationUnitElementImpl.forKernel(
|
| + libraryElement, unitContext, '<no name>');
|
| + unitContext.unit = unitElement;
|
| + unitElement.librarySource = librarySource;
|
| + unitElement.source =
|
| + fileUri != null ? resynthesizer._getSource(fileUri) : librarySource;
|
| + unitContext.unit = unitElement;
|
| + return unitContext;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Implementation of [KernelUnit].
|
| + */
|
| +class _KernelUnitImpl implements KernelUnit {
|
| + final _KernelUnitResynthesizerContextImpl context;
|
| +
|
| + List<kernel.Class> _classes;
|
| + List<kernel.Field> _fields;
|
| + List<kernel.Procedure> _procedures;
|
| + List<kernel.Typedef> _typedefs;
|
| +
|
| + _KernelUnitImpl(this.context);
|
| +
|
| + @override
|
| + List<kernel.Class> get classes =>
|
| + _classes ??= context.libraryContext.library.classes
|
| + .where((n) => n.fileUri == context.fileUri)
|
| + .toList(growable: false);
|
| +
|
| + @override
|
| + List<kernel.Field> get fields =>
|
| + _fields ??= context.libraryContext.library.fields
|
| + .where((n) => n.fileUri == context.fileUri)
|
| + .toList(growable: false);
|
| +
|
| + @override
|
| + List<kernel.Procedure> get procedures =>
|
| + _procedures ??= context.libraryContext.library.procedures
|
| + .where((n) => n.fileUri == context.fileUri)
|
| + .toList(growable: false);
|
| +
|
| + @override
|
| + List<kernel.Typedef> get typedefs =>
|
| + _typedefs ??= context.libraryContext.library.typedefs
|
| + .where((n) => n.fileUri == context.fileUri)
|
| + .toList(growable: false);
|
| +}
|
| +
|
| +/**
|
| + * Implementation of [KernelUnitResynthesizerContext].
|
| + */
|
| +class _KernelUnitResynthesizerContextImpl
|
| + implements KernelUnitResynthesizerContext {
|
| + final _KernelLibraryResynthesizerContextImpl libraryContext;
|
| + final String fileUri;
|
| +
|
| + CompilationUnitElementImpl unit;
|
| +
|
| + _KernelUnitResynthesizerContextImpl(this.libraryContext, this.fileUri);
|
| +
|
| + @override
|
| + KernelUnit get kernelUnit => new _KernelUnitImpl(this);
|
|
|
| @override
|
| List<ElementAnnotation> buildAnnotations(
|
| - CompilationUnitElementImpl unit, List<kernel.Expression> expressions) {
|
| + List<kernel.Expression> expressions) {
|
| int length = expressions.length;
|
| if (length != 0) {
|
| var annotations = new List<ElementAnnotation>(length);
|
| @@ -413,12 +583,11 @@ class _KernelLibraryResynthesizerContextImpl
|
| }
|
|
|
| @override
|
| - UnitExplicitTopLevelAccessors buildTopLevelAccessors(
|
| - CompilationUnitElementImpl unit) {
|
| + UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
|
| var accessorsData = new UnitExplicitTopLevelAccessors();
|
| var implicitVariables = <String, TopLevelVariableElementImpl>{};
|
| // Build explicit property accessors and implicit fields.
|
| - for (var procedure in library.procedures) {
|
| + for (var procedure in kernelUnit.procedures) {
|
| bool isGetter = procedure.kind == kernel.ProcedureKind.Getter;
|
| bool isSetter = procedure.kind == kernel.ProcedureKind.Setter;
|
| if (isGetter || isSetter) {
|
| @@ -453,12 +622,12 @@ class _KernelLibraryResynthesizerContextImpl
|
| }
|
|
|
| @override
|
| - UnitExplicitTopLevelVariables buildTopLevelVariables(
|
| - CompilationUnitElementImpl unit) {
|
| - int numberOfVariables = library.fields.length;
|
| + UnitExplicitTopLevelVariables buildTopLevelVariables() {
|
| + List<kernel.Field> kernelFields = kernelUnit.fields;
|
| + int numberOfVariables = kernelFields.length;
|
| var variablesData = new UnitExplicitTopLevelVariables(numberOfVariables);
|
| for (int i = 0; i < numberOfVariables; i++) {
|
| - kernel.Field field = library.fields[i];
|
| + kernel.Field field = kernelFields[i];
|
|
|
| // Add the explicit variables.
|
| TopLevelVariableElementImpl variable;
|
| @@ -525,17 +694,13 @@ class _KernelLibraryResynthesizerContextImpl
|
| }
|
|
|
| @override
|
| - LibraryElement getLibrary(String uriStr) {
|
| - return _resynthesizer.getLibrary(uriStr);
|
| - }
|
| -
|
| - @override
|
| ConstructorElementImpl getRedirectedConstructor(
|
| kernel.Constructor kernelConstructor, kernel.Procedure kernelFactory) {
|
| if (kernelConstructor != null) {
|
| for (var initializer in kernelConstructor.initializers) {
|
| if (initializer is kernel.RedirectingInitializer) {
|
| - return _getElement(initializer.targetReference.canonicalName)
|
| + return libraryContext.resynthesizer
|
| + ._getElement(initializer.targetReference.canonicalName)
|
| as ConstructorElementImpl;
|
| }
|
| }
|
| @@ -545,7 +710,8 @@ class _KernelLibraryResynthesizerContextImpl
|
| if (body is RedirectingFactoryBody) {
|
| kernel.Member target = body.target;
|
| if (target != null) {
|
| - return _getElement(target.reference.canonicalName)
|
| + return libraryContext.resynthesizer
|
| + ._getElement(target.reference.canonicalName)
|
| as ConstructorElementImpl;
|
| }
|
| }
|
| @@ -612,88 +778,10 @@ class _KernelLibraryResynthesizerContextImpl
|
| return elementAnnotation;
|
| }
|
|
|
| - /**
|
| - * Return the [ElementImpl] that corresponds to the given [name], or `null`
|
| - * if the corresponding element cannot be found.
|
| - */
|
| - ElementImpl _getElement(kernel.CanonicalName name) {
|
| - if (name == null) return null;
|
| - kernel.CanonicalName parentName = name.parent;
|
| -
|
| - // If the parent is the root, then this name is a library.
|
| - if (parentName.isRoot) {
|
| - return _resynthesizer.getLibrary(name.name);
|
| - }
|
| -
|
| - // If the name is private, it is prefixed with a library URI.
|
| - if (name.name.startsWith('_')) {
|
| - parentName = parentName.parent;
|
| - }
|
| -
|
| - // Skip qualifiers.
|
| - bool isGetter = false;
|
| - bool isSetter = false;
|
| - bool isField = false;
|
| - bool isConstructor = false;
|
| - bool isMethod = false;
|
| - if (parentName.name == '@getters') {
|
| - isGetter = true;
|
| - parentName = parentName.parent;
|
| - } else if (parentName.name == '@setters') {
|
| - isSetter = true;
|
| - parentName = parentName.parent;
|
| - } else if (parentName.name == '@fields') {
|
| - isField = true;
|
| - parentName = parentName.parent;
|
| - } else if (parentName.name == '@constructors') {
|
| - isConstructor = true;
|
| - parentName = parentName.parent;
|
| - } else if (parentName.name == '@methods') {
|
| - isMethod = true;
|
| - parentName = parentName.parent;
|
| - }
|
| -
|
| - ElementImpl parentElement = _getElement(parentName);
|
| - if (parentElement == null) return null;
|
| -
|
| - // Search in units of the library.
|
| - if (parentElement is LibraryElementImpl) {
|
| - for (CompilationUnitElement unit in parentElement.units) {
|
| - CompilationUnitElementImpl unitImpl = unit;
|
| - ElementImpl child = unitImpl.getChild(name.name);
|
| - if (child != null) {
|
| - return child;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - // Search in the class.
|
| - if (parentElement is AbstractClassElementImpl) {
|
| - if (isGetter) {
|
| - return parentElement.getGetter(name.name) as ElementImpl;
|
| - } else if (isSetter) {
|
| - return parentElement.getSetter(name.name) as ElementImpl;
|
| - } else if (isField) {
|
| - return parentElement.getField(name.name) as ElementImpl;
|
| - } else if (isConstructor) {
|
| - if (name.name.isEmpty) {
|
| - return parentElement.unnamedConstructor as ConstructorElementImpl;
|
| - }
|
| - return parentElement.getNamedConstructor(name.name) as ElementImpl;
|
| - } else if (isMethod) {
|
| - return parentElement.getMethod(name.name) as ElementImpl;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - throw new UnimplementedError('Should not be reached.');
|
| - }
|
| -
|
| InterfaceType _getInterfaceType(ElementImpl context,
|
| kernel.CanonicalName className, List<kernel.DartType> kernelArguments) {
|
| var libraryName = className.parent;
|
| - var libraryElement = _resynthesizer.getLibrary(libraryName.name);
|
| + var libraryElement = libraryContext.getLibrary(libraryName.name);
|
| ClassElement classElement = libraryElement.getType(className.name);
|
| classElement ??= libraryElement.getEnum(className.name);
|
|
|
|
|