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

Side by Side Diff: pkg/kernel/lib/analyzer/ast_from_analyzer.dart

Issue 2619193003: Insert implicit downcasts in kernel strong mode. (Closed)
Patch Set: Merge Created 3 years, 11 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
« no previous file with comments | « no previous file | pkg/kernel/lib/ast.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.analyzer.ast_from_analyzer; 4 library kernel.analyzer.ast_from_analyzer;
5 5
6 import '../ast.dart' as ast; 6 import '../ast.dart' as ast;
7 import '../frontend/accessors.dart'; 7 import '../frontend/accessors.dart';
8 import '../frontend/super_initializers.dart'; 8 import '../frontend/super_initializers.dart';
9 import '../log.dart'; 9 import '../log.dart';
10 import '../type_algebra.dart'; 10 import '../type_algebra.dart';
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 TypeScope(ReferenceLevelLoader loader) : super(loader) { 300 TypeScope(ReferenceLevelLoader loader) : super(loader) {
301 _typeBuilder = new TypeAnnotationBuilder(this); 301 _typeBuilder = new TypeAnnotationBuilder(this);
302 } 302 }
303 303
304 String get location => '?'; 304 String get location => '?';
305 305
306 bool get allowClassTypeParameters => false; 306 bool get allowClassTypeParameters => false;
307 307
308 ast.DartType get defaultTypeParameterBound => getRootClassReference().rawType; 308 ast.DartType get defaultTypeParameterBound => getRootClassReference().rawType;
309 309
310 ast.TypeParameter tryGetTypeParameterReference(TypeParameterElement element) {
311 return localTypeParameters[element] ??
312 loader.tryGetClassTypeParameter(element);
313 }
314
310 ast.TypeParameter getTypeParameterReference(TypeParameterElement element) { 315 ast.TypeParameter getTypeParameterReference(TypeParameterElement element) {
311 return localTypeParameters[element] ?? 316 return localTypeParameters[element] ??
312 loader.tryGetClassTypeParameter(element) ?? 317 loader.tryGetClassTypeParameter(element) ??
313 (localTypeParameters[element] = new ast.TypeParameter(element.name)); 318 (localTypeParameters[element] = new ast.TypeParameter(element.name));
314 } 319 }
315 320
316 ast.TypeParameter makeTypeParameter(TypeParameterElement element, 321 ast.TypeParameter makeTypeParameter(TypeParameterElement element,
317 {ast.DartType bound}) { 322 {ast.DartType bound}) {
318 var typeParameter = getTypeParameterReference(element); 323 var typeParameter = getTypeParameterReference(element);
319 assert(bound != null); 324 assert(bound != null);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 // variables. If successful, use the substituted types in the order 383 // variables. If successful, use the substituted types in the order
379 // they occur in the type parameter list. 384 // they occur in the type parameter list.
380 var substitution = unifyTypes(genericFunctionType.withoutTypeParameters, 385 var substitution = unifyTypes(genericFunctionType.withoutTypeParameters,
381 inferredFunctionType, genericFunctionType.typeParameters.toSet()); 386 inferredFunctionType, genericFunctionType.typeParameters.toSet());
382 if (substitution != null) { 387 if (substitution != null) {
383 return genericFunctionType.typeParameters 388 return genericFunctionType.typeParameters
384 .map((p) => substitution[p] ?? const ast.DynamicType()) 389 .map((p) => substitution[p] ?? const ast.DynamicType())
385 .toList(); 390 .toList();
386 } 391 }
387 return new List<ast.DartType>.filled( 392 return new List<ast.DartType>.filled(
388 genericFunctionType.typeParameters.length, const ast.DynamicType()); 393 genericFunctionType.typeParameters.length, const ast.DynamicType(),
394 growable: true);
389 } else { 395 } else {
390 return <ast.DartType>[]; 396 return <ast.DartType>[];
391 } 397 }
392 } 398 }
393 399
394 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) { 400 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) {
395 if (node == null) return null; 401 if (node == null) return null;
396 return _typeBuilder.buildList(node.arguments); 402 return _typeBuilder.buildList(node.arguments);
397 } 403 }
398 404
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 loop = makeBreakTarget(loop, breakNode); 1183 loop = makeBreakTarget(loop, breakNode);
1178 if (initialExpression != null) { 1184 if (initialExpression != null) {
1179 return new ast.Block(<ast.Statement>[ 1185 return new ast.Block(<ast.Statement>[
1180 new ast.ExpressionStatement(initialExpression), 1186 new ast.ExpressionStatement(initialExpression),
1181 loop 1187 loop
1182 ]); 1188 ]);
1183 } 1189 }
1184 return loop; 1190 return loop;
1185 } 1191 }
1186 1192
1193 DartType iterableElementType(DartType iterable) {
1194 if (iterable is InterfaceType) {
1195 var iterator = iterable.lookUpInheritedGetter('iterator')?.returnType;
1196 if (iterator is InterfaceType) {
1197 return iterator.lookUpInheritedGetter('current')?.returnType;
1198 }
1199 }
1200 return null;
1201 }
1202
1203 DartType streamElementType(DartType stream) {
1204 if (stream is InterfaceType) {
1205 var class_ = stream.element;
1206 if (class_.library.isDartAsync &&
1207 class_.name == 'Stream' &&
1208 stream.typeArguments.length == 1) {
1209 return stream.typeArguments[0];
1210 }
1211 }
1212 return null;
1213 }
1214
1187 ast.Statement visitForEachStatement(ForEachStatement node) { 1215 ast.Statement visitForEachStatement(ForEachStatement node) {
1188 ast.VariableDeclaration variable; 1216 ast.VariableDeclaration variable;
1189 Accessor leftHand; 1217 Accessor leftHand;
1190 if (node.loopVariable != null) { 1218 if (node.loopVariable != null) {
1191 DeclaredIdentifier loopVariable = node.loopVariable; 1219 DeclaredIdentifier loopVariable = node.loopVariable;
1192 variable = scope.makeVariableDeclaration(loopVariable.element, 1220 variable = scope.makeVariableDeclaration(loopVariable.element,
1193 type: scope.buildOptionalTypeAnnotation(loopVariable.type)); 1221 type: scope.buildOptionalTypeAnnotation(loopVariable.type));
1194 } else if (node.identifier != null) { 1222 } else if (node.identifier != null) {
1195 leftHand = scope.buildLeftHandValue(node.identifier); 1223 leftHand = scope.buildLeftHandValue(node.identifier);
1196 // TODO: In strong mode, set variable type based on iterable type.
1197 variable = new ast.VariableDeclaration(null, isFinal: true); 1224 variable = new ast.VariableDeclaration(null, isFinal: true);
1225 if (scope.strongMode) {
1226 var containerType = node.iterable.staticType;
1227 DartType elementType = node.awaitKeyword != null
1228 ? streamElementType(containerType)
1229 : iterableElementType(containerType);
1230 if (elementType != null) {
1231 variable.type = scope.buildType(elementType);
1232 }
1233 }
1198 } 1234 }
1199 var breakNode = new LabelStack.unlabeled(breakStack); 1235 var breakNode = new LabelStack.unlabeled(breakStack);
1200 var continueNode = new LabelStack.unlabeled(continueStack); 1236 var continueNode = new LabelStack.unlabeled(continueStack);
1201 addLoopLabels(node, continueNode); 1237 addLoopLabels(node, continueNode);
1202 var body = buildInScope(node.body, breakNode, continueNode); 1238 var body = buildInScope(node.body, breakNode, continueNode);
1203 if (leftHand != null) { 1239 if (leftHand != null) {
1204 // Desugar 1240 // Desugar
1205 // 1241 //
1206 // for (x in e) BODY 1242 // for (x in e) BODY
1207 // 1243 //
1208 // to 1244 // to
1209 // 1245 //
1210 // for (var tmp in e) { 1246 // for (var tmp in e) {
1211 // x = tmp; 1247 // x = tmp;
1212 // BODY 1248 // BODY
1213 // } 1249 // }
1214 body = new ast.Block(<ast.Statement>[ 1250 body = new ast.Block(<ast.Statement>[
1215 new ast.ExpressionStatement(leftHand 1251 new ast.ExpressionStatement(leftHand
1216 .buildAssignment(new ast.VariableGet(variable), voidContext: true)), 1252 .buildAssignment(new ast.VariableGet(variable), voidContext: true)),
1217 body 1253 body
1218 ]); 1254 ]);
1219 } 1255 }
1220 var loop = new ast.ForInStatement( 1256 var loop = new ast.ForInStatement(
1221 variable, 1257 variable,
1222 scope.buildExpression(node.iterable), 1258 scope.buildExpression(node.iterable),
1223 makeBreakTarget(body, continueNode), 1259 makeBreakTarget(body, continueNode),
1224 isAsync: node.awaitKeyword != null); 1260 isAsync: node.awaitKeyword != null)..fileOffset = node.offset;
1225 return makeBreakTarget(loop, breakNode); 1261 return makeBreakTarget(loop, breakNode);
1226 } 1262 }
1227 1263
1228 ast.Statement visitIfStatement(IfStatement node) { 1264 ast.Statement visitIfStatement(IfStatement node) {
1229 return new ast.IfStatement(scope.buildExpression(node.condition), 1265 return new ast.IfStatement(scope.buildExpression(node.condition),
1230 build(node.thenStatement), buildOptional(node.elseStatement)); 1266 build(node.thenStatement), buildOptional(node.elseStatement));
1231 } 1267 }
1232 1268
1233 ast.Statement visitReturnStatement(ReturnStatement node) { 1269 ast.Statement visitReturnStatement(ReturnStatement node) {
1234 return new ast.ReturnStatement( 1270 return new ast.ReturnStatement(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 ast.Statement visitYieldStatement(YieldStatement node) { 1321 ast.Statement visitYieldStatement(YieldStatement node) {
1286 return new ast.YieldStatement(scope.buildExpression(node.expression), 1322 return new ast.YieldStatement(scope.buildExpression(node.expression),
1287 isYieldStar: node.star != null); 1323 isYieldStar: node.star != null);
1288 } 1324 }
1289 1325
1290 ast.Statement visitFunctionDeclarationStatement( 1326 ast.Statement visitFunctionDeclarationStatement(
1291 FunctionDeclarationStatement node) { 1327 FunctionDeclarationStatement node) {
1292 var declaration = node.functionDeclaration; 1328 var declaration = node.functionDeclaration;
1293 var expression = declaration.functionExpression; 1329 var expression = declaration.functionExpression;
1294 LocalElement element = declaration.element as dynamic; // Cross cast. 1330 LocalElement element = declaration.element as dynamic; // Cross cast.
1295 // TODO: Set a function type on the variable.
1296 return new ast.FunctionDeclaration( 1331 return new ast.FunctionDeclaration(
1297 scope.makeVariableDeclaration(element), 1332 scope.makeVariableDeclaration(element,
1333 type: scope.buildType(declaration.element.type)),
1298 scope.buildFunctionNode(expression.parameters, expression.body, 1334 scope.buildFunctionNode(expression.parameters, expression.body,
1299 typeParameters: scope.buildOptionalTypeParameterList( 1335 typeParameters: scope.buildOptionalTypeParameterList(
1300 expression.typeParameters, 1336 expression.typeParameters,
1301 strongModeOnly: true), 1337 strongModeOnly: true),
1302 returnType: declaration.returnType))..fileOffset = node.offset; 1338 returnType: declaration.returnType))..fileOffset = node.offset;
1303 } 1339 }
1304 1340
1305 @override 1341 @override
1306 visitStatement(Statement node) { 1342 visitStatement(Statement node) {
1307 return scope.internalError('Unhandled statement ${node.runtimeType}'); 1343 return scope.internalError('Unhandled statement ${node.runtimeType}');
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 /// If [boundVariables] is null, no type variables are replaced, otherwise all 2179 /// If [boundVariables] is null, no type variables are replaced, otherwise all
2144 /// type variables except those in [boundVariables] are replaced. In other 2180 /// type variables except those in [boundVariables] are replaced. In other
2145 /// words, it represents the bound variables, or "all variables" if omitted. 2181 /// words, it represents the bound variables, or "all variables" if omitted.
2146 ast.DartType convertType( 2182 ast.DartType convertType(
2147 DartType type, List<TypeParameterElement> boundVariables) { 2183 DartType type, List<TypeParameterElement> boundVariables) {
2148 if (type is TypeParameterType) { 2184 if (type is TypeParameterType) {
2149 if (isUnreifiedTypeParameter(type.element)) { 2185 if (isUnreifiedTypeParameter(type.element)) {
2150 return const ast.DynamicType(); 2186 return const ast.DynamicType();
2151 } 2187 }
2152 if (boundVariables == null || boundVariables.contains(type)) { 2188 if (boundVariables == null || boundVariables.contains(type)) {
2153 var typeParameter = scope.getTypeParameterReference(type.element); 2189 var typeParameter = scope.tryGetTypeParameterReference(type.element);
2190 if (typeParameter == null) {
2191 // The analyzer sometimes gives us a type parameter that was not
2192 // bound anywhere. Make sure we do not emit a dangling reference.
2193 if (type.element.bound != null) {
2194 return convertType(type.element.bound, []);
2195 }
2196 return const ast.DynamicType();
2197 }
2154 if (!scope.allowClassTypeParameters && 2198 if (!scope.allowClassTypeParameters &&
2155 typeParameter.parent is ast.Class) { 2199 typeParameter.parent is ast.Class) {
2156 return const ast.InvalidType(); 2200 return const ast.InvalidType();
2157 } 2201 }
2158 return new ast.TypeParameterType(typeParameter); 2202 return new ast.TypeParameterType(typeParameter);
2159 } else { 2203 } else {
2160 return const ast.DynamicType(); 2204 return const ast.DynamicType();
2161 } 2205 }
2162 } else if (type is InterfaceType) { 2206 } else if (type is InterfaceType) {
2163 var classNode = scope.getClassReference(type.element); 2207 var classNode = scope.getClassReference(type.element);
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 if (list[i - 1].compareTo(item) == 0) { 2936 if (list[i - 1].compareTo(item) == 0) {
2893 ++deleted; 2937 ++deleted;
2894 } else if (deleted > 0) { 2938 } else if (deleted > 0) {
2895 list[i - deleted] = item; 2939 list[i - deleted] = item;
2896 } 2940 }
2897 } 2941 }
2898 if (deleted > 0) { 2942 if (deleted > 0) {
2899 list.length -= deleted; 2943 list.length -= deleted;
2900 } 2944 }
2901 } 2945 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/lib/ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698