Chromium Code Reviews| Index: pkg/analyzer/lib/src/summary/resynthesize.dart |
| diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart |
| index 03688eb0d8ef5194fbe1fd39855c6452ce595ba5..1f1ca1da7bc584bacde8618144d0f545284fb9e1 100644 |
| --- a/pkg/analyzer/lib/src/summary/resynthesize.dart |
| +++ b/pkg/analyzer/lib/src/summary/resynthesize.dart |
| @@ -678,6 +678,107 @@ class _DeferredConstructorElement extends ConstructorElementHandle { |
| } |
| /** |
| + * Local function element representing the intializer for a variable that has |
| + * been resynthesized from a summary. The actual element won't be constructed |
| + * until it is requested. But properties [context] and [enclosingElement] can |
| + * be used without creating the actual element. |
| + */ |
| +class _DeferredInitializerElement extends FunctionElementHandle { |
| + /** |
| + * The variable element containing this element. |
| + */ |
| + final VariableElement _enclosingElement; |
|
scheglov
2016/02/18 21:53:51
We could do
@override
final VariableElement enclo
Paul Berry
2016/02/18 22:14:23
Done.
|
| + |
| + _DeferredInitializerElement(this._enclosingElement) : super(null, null); |
| + |
| + @override |
| + FunctionElement get actualElement => _enclosingElement.initializer; |
| + |
| + @override |
| + AnalysisContext get context => _enclosingElement.context; |
| + |
| + @override |
| + VariableElement get enclosingElement => _enclosingElement; |
| + |
| + @override |
| + ElementLocation get location => actualElement.location; |
| +} |
| + |
| +/** |
| + * Local function element that has been resynthesized from a summary. The |
| + * actual element won't be constructed until it is requested. But properties |
| + * [context] and [enclosingElement] can be used without creating the actual |
| + * element. |
| + */ |
| +class _DeferredLocalFunctionElement extends FunctionElementHandle { |
| + /** |
| + * The executable element containing this element. |
| + */ |
| + final ExecutableElement _enclosingElement; |
| + |
| + /** |
| + * The index of this function within [ExecutableElement.functions]. |
| + */ |
| + final int _localIndex; |
| + |
| + _DeferredLocalFunctionElement(this._enclosingElement, this._localIndex) |
| + : super(null, null); |
| + |
| + @override |
| + FunctionElement get actualElement { |
| + ExecutableElement enclosingElement = _enclosingElement; |
| + if (enclosingElement is PropertyAccessorElement && enclosingElement.isSynthetic) { |
| + return enclosingElement.variable.initializer; |
| + } else { |
| + return _enclosingElement.functions[_localIndex]; |
| + } |
| + } |
| + |
| + @override |
| + AnalysisContext get context => _enclosingElement.context; |
| + |
| + @override |
| + ExecutableElement get enclosingElement => _enclosingElement; |
| + |
| + @override |
| + ElementLocation get location => actualElement.location; |
| +} |
| + |
| +/** |
| + * Local variable element that has been resynthesized from a summary. The |
| + * actual element won't be constructed until it is requested. But properties |
| + * [context] and [enclosingElement] can be used without creating the actual |
| + * element. |
| + */ |
| +class _DeferredLocalVariableElement extends LocalVariableElementHandle { |
| + /** |
| + * The executable element containing this element. |
| + */ |
| + final ExecutableElement _enclosingElement; |
| + |
| + /** |
| + * The index of this variable within [ExecutableElement.localVariables]. |
| + */ |
| + final int _localIndex; |
| + |
| + _DeferredLocalVariableElement(this._enclosingElement, this._localIndex) |
| + : super(null, null); |
| + |
| + @override |
| + LocalVariableElement get actualElement => |
| + _enclosingElement.localVariables[_localIndex]; |
| + |
| + @override |
| + AnalysisContext get context => _enclosingElement.context; |
| + |
| + @override |
| + ExecutableElement get enclosingElement => _enclosingElement; |
| + |
| + @override |
| + ElementLocation get location => actualElement.location; |
| +} |
| + |
| +/** |
| * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the |
| * elements in a single library from that library's summary. |
| */ |
| @@ -1221,6 +1322,7 @@ class _LibraryResynthesizer { |
| case ReferenceKind.length: |
| case ReferenceKind.prefix: |
| case ReferenceKind.unresolved: |
| + case ReferenceKind.variable: |
| // Should never happen. Exported names never refer to import prefixes, |
| // and they always refer to defined top-level entities. |
| throw new StateError('Unexpected export name kind: ${exportName.kind}'); |
| @@ -1948,7 +2050,28 @@ class _LibraryResynthesizer { |
| element = new FunctionTypeAliasElementHandle( |
| summaryResynthesizer, location); |
| break; |
| + case ReferenceKind.variable: |
| + Element enclosingElement = enclosingInfo.element; |
| + if (enclosingElement is ExecutableElement) { |
| + element = new _DeferredLocalVariableElement( |
| + enclosingElement, linkedReference.localIndex); |
| + } else { |
| + throw new StateError('Unexpected element enclosing variable:' |
| + ' ${enclosingElement.runtimeType}'); |
| + } |
| + break; |
| case ReferenceKind.function: |
| + Element enclosingElement = enclosingInfo.element; |
| + if (enclosingElement is VariableElement) { |
| + element = new _DeferredInitializerElement(enclosingElement); |
| + } else if (enclosingElement is ExecutableElement) { |
| + element = new _DeferredLocalFunctionElement( |
| + enclosingElement, linkedReference.localIndex); |
| + } else { |
| + throw new StateError('Unexpected element enclosing function:' |
| + ' ${enclosingElement.runtimeType}'); |
| + } |
| + break; |
| case ReferenceKind.prefix: |
| case ReferenceKind.unresolved: |
| break; |