Chromium Code Reviews| Index: pkg/analyzer/lib/src/fasta/resolution_applier.dart |
| diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..97c4415906a17287d52f10033b195ca4f350d26d |
| --- /dev/null |
| +++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart |
| @@ -0,0 +1,80 @@ |
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +import 'package:analyzer/dart/ast/ast.dart'; |
| +import 'package:analyzer/dart/ast/visitor.dart'; |
| +import 'package:analyzer/dart/element/type.dart'; |
| + |
| +/// Visitor that applies resolution data from the front end (obtained via |
| +/// [ResolutionStorer]) to an analyzer AST. |
| +class ResolutionApplier extends GeneralizingAstVisitor { |
| + final List<DartType> _types; |
| + int _typeIndex = 0; |
| + |
| + ResolutionApplier(this._types); |
| + |
| + /// Verifies that all types passed to the constructor have been applied. |
| + void checkDone() { |
| + if (_typeIndex != _types.length) { |
| + throw new StateError( |
| + 'Some types were not consumed, starting at ${_types[_typeIndex]}'); |
| + } |
| + } |
| + |
| + @override |
| + void visitExpression(Expression node) { |
| + visitNode(node); |
| + node.staticType = _getTypeFor(node); |
| + } |
| + |
| + @override |
| + void visitMethodInvocation(MethodInvocation node) { |
| + node.target?.accept(this); |
| + // TODO(paulberry): store resolution of node.methodName. |
| + // TODO(paulberry): store resolution of node.typeArguments. |
| + node.argumentList.accept(this); |
| + node.staticType = _getTypeFor(node); |
| + } |
| + |
| + @override |
| + void visitNode(AstNode node) { |
| + node.visitChildren(this); |
|
scheglov
2017/07/12 21:43:46
I think this is the default behaviour of this meth
Paul Berry
2017/07/12 22:20:12
Good point, thank you. Removed.
|
| + } |
| + |
| + DartType _getTypeFor(Expression node) { |
| + return _types[_typeIndex++]; |
| + } |
| +} |
| + |
| +/// Visitor that applies resolution data from the front end (obtained via |
| +/// [ResolutionStorer]) to an analyzer AST, and also checks file offsets to |
| +/// verify that the types are applied to the correct subexpressions. |
| +class ValidatingResolutionApplier extends ResolutionApplier { |
| + /// Indicates whether debug messages should be printed. |
| + static bool _debug = false; |
|
scheglov
2017/07/12 21:43:46
We could also make it const, not sure if this matt
Paul Berry
2017/07/12 22:20:12
Done.
|
| + |
| + final List<int> _typeOffsets; |
| + |
| + ValidatingResolutionApplier(List<DartType> types, this._typeOffsets) |
| + : super(types); |
| + |
| + @override |
| + void checkDone() { |
| + if (_typeIndex != _types.length) { |
| + throw new StateError('Some types were not consumed, starting at offset ' |
| + '${_typeOffsets[_typeIndex]}'); |
| + } |
| + } |
| + |
| + @override |
| + DartType _getTypeFor(Expression node) { |
| + if (_debug) print('Getting type for $node'); |
| + if (node.offset != _typeOffsets[_typeIndex]) { |
| + throw new StateError( |
| + 'Expected a type for offset ${node.offset}; got one for ' |
| + '${_typeOffsets[_typeIndex]}'); |
| + } |
| + return super._getTypeFor(node); |
| + } |
| +} |