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

Side by Side Diff: pkg/front_end/lib/src/fasta/builder/shadow_ast.dart

Issue 2768533002: Fasta type inference prototype #2
Patch Set: Merge origin/master Created 3 years, 9 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 unified diff | Download patch
OLDNEW
(Empty)
1 import 'package:front_end/src/fasta/type_inference/local_type_inferrer.dart';
2 import 'package:kernel/ast.dart' show DartType, InterfaceType;
3 import 'package:kernel/core_types.dart';
4
5 abstract class Block implements Statement {
6 Iterable<Statement> get shadowStatements;
7
8 @override
9 void shadowInfer(LocalTypeInferrer inferrer, FunctionContext context) {
10 for (var statement in shadowStatements) {
11 statement.shadowInfer(inferrer, context);
12 }
13 }
14 }
15
16 abstract class Expression {
17 DartType shadowInfer(
18 LocalTypeInferrer inferrer, DartType context, bool typeNeeded);
19 }
20
21 abstract class FunctionExpression implements Expression {
22 void set shadowInferredReturnType(DartType type);
23
24 Statement get shadowBody;
25
26 bool get shadowIsAsync;
27
28 bool get shadowIsExpressionFunction;
29
30 bool get shadowIsGenerator;
31
32 DartType shadowMakeFunctionType();
33
34 @override
35 DartType shadowInfer(
36 LocalTypeInferrer inferrer, DartType context, bool typeNeeded) {
37 // TODO(paulberry): infer argument types and type parameters.
38 // TODO(paulberry): full support for generators.
39 Statement body = shadowBody;
40 // TODO(paulberry): Dart 1.0 rules say we only need to set the function
41 // node's return type if it uses expression syntax. Does that make sense
42 // for Dart 2.0?
43 bool needToSetReturnType = shadowIsExpressionFunction;
44 bool returnTypeNeeded = typeNeeded || needToSetReturnType;
45 bool isAsync = shadowIsAsync;
46 var functionContext = new FunctionContext(
47 inferrer, returnTypeNeeded, isAsync, shadowIsGenerator);
48 body.shadowInfer(inferrer, functionContext);
49 DartType inferredReturnType;
50 if (needToSetReturnType || typeNeeded) {
51 inferredReturnType = functionContext.inferredReturnType;
52 if (isAsync) {
53 inferredReturnType = new InterfaceType(
54 inferrer.coreTypes.futureClass, <DartType>[inferredReturnType]);
55 }
56 }
57 if (needToSetReturnType) {
58 this.shadowInferredReturnType = inferredReturnType;
59 }
60 if (typeNeeded) {
61 return shadowMakeFunctionType();
62 } else {
63 return null;
64 }
65 }
66 }
67
68 abstract class IntLiteral implements Expression {
69 @override
70 DartType shadowInfer(
71 LocalTypeInferrer inferrer, DartType context, bool typeNeeded) {
72 return typeNeeded ? inferrer.coreTypes.intClass.rawType : null;
73 }
74 }
75
76 abstract class ListLiteral implements Expression {
77 DartType get declaredTypeArgumentForInference;
78
79 Iterable<Expression> get expressionsForInference;
80
81 void set inferredTypeArgument(DartType type);
82
83 @override
84 DartType shadowInfer(
85 LocalTypeInferrer inferrer, DartType context, bool typeNeeded) {
86 DartType declaredTypeArgument = declaredTypeArgumentForInference;
87 DartType typeArgumentContext = declaredTypeArgument;
88 if (typeArgumentContext == null) {
89 if (context is InterfaceType &&
90 context.classNode == inferrer.coreTypes.listClass &&
91 context.typeArguments.length == 1) {
92 typeArgumentContext = context.typeArguments[0];
93 } else if (context != null) {
94 // TODO(paulberry): report an error?
95 throw new UnimplementedError('$context');
scheglov 2017/03/24 15:38:10 If I understand correctly, "context" will be Itera
Paul Berry 2017/03/24 17:59:50 You are correct. This entire method is a hack tha
96 }
97 }
98 DartType inferredTypeArgument = typeArgumentContext;
99 bool typeArgumentNeeded = inferredTypeArgument == null;
100 for (Expression e in expressionsForInference) {
101 DartType t =
102 e.shadowInfer(inferrer, typeArgumentContext, typeArgumentNeeded);
103 if (typeArgumentNeeded) {
104 inferredTypeArgument = inferrer.union(inferredTypeArgument, t);
105 }
106 }
107 if (inferredTypeArgument == null) {
108 // Empty list.
109 throw new UnimplementedError();
110 }
111 if (declaredTypeArgument == null) {
112 this.inferredTypeArgument = inferredTypeArgument;
113 }
114 if (typeNeeded) {
115 return new InterfaceType(
116 inferrer.coreTypes.listClass, <DartType>[inferredTypeArgument]);
117 } else {
118 return null;
119 }
120 }
121 }
122
123 abstract class NullLiteral implements Expression {
124 @override
125 DartType shadowInfer(
126 LocalTypeInferrer inferrer, DartType context, bool typeNeeded) {
127 return typeNeeded ? inferrer.coreTypes.nullClass.rawType : null;
128 }
129 }
130
131 abstract class ReturnStatement implements Statement {
132 Expression get expressionForInference;
133
134 @override
135 void shadowInfer(LocalTypeInferrer inferrer, FunctionContext context) {
136 DartType expressionContext = null; // TODO(paulberry): probably wrong.
137 bool expressionTypeNeeded =
138 context.returnTypeNeeded && !context.isGenerator;
139 DartType expressionType = expressionForInference.shadowInfer(
140 inferrer, expressionContext, expressionTypeNeeded);
141 if (expressionTypeNeeded) {
142 if (context.isAsync) {
143 expressionType = _unwrapFuture(inferrer.coreTypes, expressionType);
144 }
145 context.recordReturnType(expressionType);
146 }
147 }
148
149 DartType _unwrapFuture(CoreTypes coreTypes, DartType type) {
150 // TODO(paulberry): replace with a full implementation of what's in the spec
151 // (e.g. handle types derived from Future). Also probably move to Kernel.
152 if (type is InterfaceType && type.classNode == coreTypes.futureClass) {
153 return type.typeArguments[0];
154 } else {
155 return type;
156 }
157 }
158 }
159
160 abstract class Statement {
161 void shadowInfer(LocalTypeInferrer inferrer, FunctionContext context);
162 }
163
164 abstract class VariableDeclaration implements Statement {
165 DartType get shadowDeclaredType;
166
167 DartType get shadowInferredType;
168
169 void set shadowInferredType(DartType type);
170
171 Expression get shadowInitializer;
172
173 @override
174 void shadowInfer(LocalTypeInferrer inferrer, FunctionContext context) {
175 Expression initializer = shadowInitializer;
176 if (initializer != null) {
177 DartType type = shadowDeclaredType;
178 DartType inferredType =
179 initializer.shadowInfer(inferrer, type, type == null);
180 if (type == null) {
181 this.shadowInferredType = inferredType;
182 }
183 }
184 }
185 }
186
187 abstract class VariableGet implements Expression {
188 VariableDeclaration get shadowDeclaration;
189
190 @override
191 DartType shadowInfer(
192 LocalTypeInferrer inferrer, DartType context, bool typeNeeded) {
193 return typeNeeded ? shadowDeclaration.shadowInferredType : null;
194 }
195 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/builder/ast_factory.dart ('k') | pkg/front_end/lib/src/fasta/kernel/ast_factory.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698