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..dedddee32efc59e6dd5b08541c65a022e9eed761 |
--- /dev/null |
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart |
@@ -0,0 +1,75 @@ |
+// 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); |
+ } |
+ |
+ 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 const bool _debug = false; |
+ |
+ 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); |
+ } |
+} |