Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Unified Diff: pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart

Issue 2981693002: Start copying resolution/inference data from front end to analyzer ASTs. (Closed)
Patch Set: Address code review comments. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/file_state.dart ('k') | pkg/analyzer/lib/src/fasta/analyzer_loader.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart
diff --git a/pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart b/pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart
index 5b687caf60324920e40905e9f557466ae95d7a09..99e2a7ce9e3143e7689a4a19ec8ba230942570ce 100644
--- a/pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart
+++ b/pkg/analyzer/lib/src/fasta/analyzer_diet_listener.dart
@@ -4,6 +4,26 @@
library fasta.analyzer_diet_listener;
+import 'package:analyzer/dart/ast/ast.dart' as ast show AstNode;
+
+import 'package:analyzer/dart/element/type.dart' as ast show DartType;
+
+import 'package:analyzer/src/dart/element/type.dart';
+
+import 'package:analyzer/src/fasta/resolution_applier.dart'
+ show ValidatingResolutionApplier;
+
+import 'package:analyzer/src/fasta/resolution_storer.dart'
+ show InstrumentedResolutionStorer;
+
+import 'package:front_end/src/fasta/kernel/body_builder.dart' show BodyBuilder;
+
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'
+ show TypeInferenceEngine;
+
+import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
+ show TypeInferenceListener;
+
import 'package:kernel/ast.dart' show AsyncMarker;
import 'package:front_end/src/fasta/source/stack_listener.dart'
@@ -11,12 +31,22 @@ import 'package:front_end/src/fasta/source/stack_listener.dart'
import 'package:front_end/src/fasta/builder/builder.dart';
+import 'package:front_end/src/fasta/parser/parser.dart' show MemberKind, Parser;
+
+import 'package:front_end/src/scanner/token.dart' show Token;
+
import 'package:front_end/src/fasta/source/source_library_builder.dart'
show SourceLibraryBuilder;
import 'package:front_end/src/fasta/source/diet_listener.dart'
show DietListener;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+import 'package:kernel/kernel.dart' as kernel show DartType;
+
import 'element_store.dart' show ElementStore;
import 'ast_builder.dart' show AstBuilder;
@@ -24,16 +54,144 @@ import 'ast_builder.dart' show AstBuilder;
class AnalyzerDietListener extends DietListener {
final ElementStore elementStore;
- AnalyzerDietListener(SourceLibraryBuilder library, this.elementStore)
- : super(library, null, null, null);
+ /// The body builder for the method currently being compiled, or `null` if no
+ /// method is currently being compiled.
+ ///
+ /// Needed because it performs resolution and type inference.
+ BodyBuilder _bodyBuilder;
+
+ /// The list of types inferred by the body builder for the method currently
+ /// being compiled, or `null` if no method is currently being compiled.
+ List<kernel.DartType> _kernelTypes;
+
+ /// File offsets corresponding to the types in [_kernelTypes].
+ ///
+ /// These are used strictly for validation purposes.
+ List<int> _typeOffsets;
+
+ /// Indicates whether a kernel representation of the code should be generated.
+ ///
+ /// When `false`, an analyzer AST is generated, and type inference is copied
+ /// over to it, but the result is not converted to a kernel representation.
+ ///
+ /// TODO(paulberry): remove this once "kompile" functionality is no longer
+ /// needed.
+ final bool generateKernel;
+
+ /// Indicates whether a resolved AST should be generated.
+ ///
+ /// When `false`, an analyzer AST is generated, but none of the types or
+ /// elements pointed to by the AST are guaranteed to be correct.
+ ///
+ /// This is needed in order to support the old "kompile" use case, since the
+ /// tests of that functionality were based on the behavior prior to
+ /// integrating resolution and type inference with analyzer.
+ ///
+ /// TODO(paulberry): remove this once "kompile" functionality is no longer
+ /// needed.
+ final bool doResolution;
+
+ AnalyzerDietListener(
+ SourceLibraryBuilder library,
+ this.elementStore,
+ ClassHierarchy hierarchy,
+ CoreTypes coreTypes,
+ TypeInferenceEngine typeInferenceEngine,
+ this.generateKernel,
+ this.doResolution)
+ : super(library, hierarchy, coreTypes, typeInferenceEngine);
+
+ @override
+ void buildFunctionBody(
+ Token token, ProcedureBuilder builder, MemberKind kind, Token metadata) {
+ Scope typeParameterScope = builder.computeTypeParameterScope(memberScope);
+ Scope formalParameterScope =
+ builder.computeFormalParameterScope(typeParameterScope);
+ assert(typeParameterScope != null);
+ assert(formalParameterScope != null);
+ // Create a body builder to do type inference, and a listener to record the
+ // types that are inferred.
+ _kernelTypes = <kernel.DartType>[];
+ _typeOffsets = <int>[];
+ var resolutionStorer =
+ new InstrumentedResolutionStorer(_kernelTypes, _typeOffsets);
+ _bodyBuilder = super.createListener(builder, memberScope,
+ builder.isInstanceMember, formalParameterScope, resolutionStorer);
+ // Parse the function body normally; this will build the analyzer AST, run
+ // the body builder to do type inference, and then copy the inferred types
+ // over to the analyzer AST.
+ parseFunctionBody(
+ createListener(builder, typeParameterScope, builder.isInstanceMember,
+ formalParameterScope),
+ token,
+ metadata,
+ kind);
+ // The inferred types and the body builder are no longer needed.
+ _bodyBuilder = null;
+ _kernelTypes = null;
+ _typeOffsets = null;
+ }
StackListener createListener(
ModifierBuilder builder, Scope memberScope, bool isInstanceMember,
- [Scope formalParameterScope]) {
- return new AstBuilder(
- null, library, builder, elementStore, memberScope, false, uri);
+ [Scope formalParameterScope, TypeInferenceListener listener]) {
+ return new AstBuilder(null, library, builder, elementStore, memberScope,
+ false, generateKernel, uri);
}
@override
AsyncMarker getAsyncMarker(StackListener listener) => null;
+
+ @override
+ void listenerFinishFunction(
+ StackListener listener,
+ Token token,
+ Token metadata,
+ MemberKind kind,
+ List metadataConstants,
+ dynamic formals,
+ AsyncMarker asyncModifier,
+ dynamic body) {
+ // TODO(paulberry): this duplicates a lot of code from
+ // DietListener.parseFunctionBody.
+ if (doResolution) {
+ // At this point the analyzer AST has been built, but it doesn't contain
+ // resolution data or inferred types. Run the body builder and gather this
ahe 2017/07/13 14:51:40 Long line.
Paul Berry 2017/07/13 15:54:46 Done.
+ // information.
+ Parser parser = new Parser(_bodyBuilder);
+ List bodyBuilderMetadataConstants;
+ if (metadata != null) {
+ parser.parseMetadataStar(metadata);
+ bodyBuilderMetadataConstants = _bodyBuilder.pop();
+ }
+ token = parser.parseFormalParametersOpt(token, kind);
+ var bodyBuilderFormals = _bodyBuilder.pop();
+ _bodyBuilder.checkEmpty(token.charOffset);
+ token = parser.parseInitializersOpt(token);
+ bool isExpression = false;
+ bool allowAbstract = asyncModifier == AsyncMarker.Sync;
+ parser.parseFunctionBody(token, isExpression, allowAbstract);
+ var bodyBuilderBody = _bodyBuilder.pop();
+ _bodyBuilder.checkEmpty(token.charOffset);
+ _bodyBuilder.finishFunction(bodyBuilderMetadataConstants,
+ bodyBuilderFormals, asyncModifier, bodyBuilderBody);
+
+ // Now apply the resolution data and inferred types to the analyzer AST.
+ var translatedTypes = _translateTypes(_kernelTypes);
+ var resolutionApplier =
+ new ValidatingResolutionApplier(translatedTypes, _typeOffsets);
+ ast.AstNode bodyAsAstNode = body;
+ bodyAsAstNode.accept(resolutionApplier);
+ resolutionApplier.checkDone();
+ }
+ listener.finishFunction(metadataConstants, formals, asyncModifier, body);
+ }
+
+ /// Translates the given kernel types into analyzer types.
+ static List<ast.DartType> _translateTypes(List<kernel.DartType> kernelTypes) {
+ // For now we just translate everything to `dynamic`.
+ // TODO(paulberry): implement propert translation of types.
+ return new List<ast.DartType>.filled(
+ kernelTypes.length, DynamicTypeImpl.instance);
+ }
}
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/file_state.dart ('k') | pkg/analyzer/lib/src/fasta/analyzer_loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698