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

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

Issue 2619193003: Insert implicit downcasts in kernel strong mode. (Closed)
Patch Set: Add missing status line 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
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 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 loop = makeBreakTarget(loop, breakNode); 1170 loop = makeBreakTarget(loop, breakNode);
1165 if (initialExpression != null) { 1171 if (initialExpression != null) {
1166 return new ast.Block(<ast.Statement>[ 1172 return new ast.Block(<ast.Statement>[
1167 new ast.ExpressionStatement(initialExpression), 1173 new ast.ExpressionStatement(initialExpression),
1168 loop 1174 loop
1169 ]); 1175 ]);
1170 } 1176 }
1171 return loop; 1177 return loop;
1172 } 1178 }
1173 1179
1180 DartType iterableElementType(DartType iterable) {
1181 if (iterable is InterfaceType) {
1182 var iterator = iterable.lookUpInheritedGetter('iterator')?.returnType;
1183 if (iterator is InterfaceType) {
1184 return iterator.lookUpInheritedGetter('current')?.returnType;
1185 }
1186 }
1187 return null;
1188 }
1189
1190 DartType streamElementType(DartType stream) {
1191 if (stream is InterfaceType) {
1192 var class_ = stream.element;
1193 if (class_.library.isDartAsync &&
1194 class_.name == 'Stream' &&
1195 stream.typeArguments.length == 1) {
1196 return stream.typeArguments[0];
1197 }
1198 }
1199 return null;
1200 }
1201
1174 ast.Statement visitForEachStatement(ForEachStatement node) { 1202 ast.Statement visitForEachStatement(ForEachStatement node) {
1175 ast.VariableDeclaration variable; 1203 ast.VariableDeclaration variable;
1176 Accessor leftHand; 1204 Accessor leftHand;
1177 if (node.loopVariable != null) { 1205 if (node.loopVariable != null) {
1178 DeclaredIdentifier loopVariable = node.loopVariable; 1206 DeclaredIdentifier loopVariable = node.loopVariable;
1179 variable = scope.makeVariableDeclaration(loopVariable.element, 1207 variable = scope.makeVariableDeclaration(loopVariable.element,
1180 type: scope.buildOptionalTypeAnnotation(loopVariable.type)); 1208 type: scope.buildOptionalTypeAnnotation(loopVariable.type));
1181 } else if (node.identifier != null) { 1209 } else if (node.identifier != null) {
1182 leftHand = scope.buildLeftHandValue(node.identifier); 1210 leftHand = scope.buildLeftHandValue(node.identifier);
1183 // TODO: In strong mode, set variable type based on iterable type.
1184 variable = new ast.VariableDeclaration(null, isFinal: true); 1211 variable = new ast.VariableDeclaration(null, isFinal: true);
1212 if (scope.strongMode) {
1213 var containerType = node.iterable.staticType;
1214 DartType elementType = node.awaitKeyword != null
1215 ? streamElementType(containerType)
1216 : iterableElementType(containerType);
1217 if (elementType != null) {
1218 variable.type = scope.buildType(elementType);
1219 }
1220 }
1185 } 1221 }
1186 var breakNode = new LabelStack.unlabeled(breakStack); 1222 var breakNode = new LabelStack.unlabeled(breakStack);
1187 var continueNode = new LabelStack.unlabeled(continueStack); 1223 var continueNode = new LabelStack.unlabeled(continueStack);
1188 addLoopLabels(node, continueNode); 1224 addLoopLabels(node, continueNode);
1189 var body = buildInScope(node.body, breakNode, continueNode); 1225 var body = buildInScope(node.body, breakNode, continueNode);
1190 if (leftHand != null) { 1226 if (leftHand != null) {
1191 // Desugar 1227 // Desugar
1192 // 1228 //
1193 // for (x in e) BODY 1229 // for (x in e) BODY
1194 // 1230 //
1195 // to 1231 // to
1196 // 1232 //
1197 // for (var tmp in e) { 1233 // for (var tmp in e) {
1198 // x = tmp; 1234 // x = tmp;
1199 // BODY 1235 // BODY
1200 // } 1236 // }
1201 body = new ast.Block(<ast.Statement>[ 1237 body = new ast.Block(<ast.Statement>[
1202 new ast.ExpressionStatement(leftHand 1238 new ast.ExpressionStatement(leftHand
1203 .buildAssignment(new ast.VariableGet(variable), voidContext: true)), 1239 .buildAssignment(new ast.VariableGet(variable), voidContext: true)),
1204 body 1240 body
1205 ]); 1241 ]);
1206 } 1242 }
1207 var loop = new ast.ForInStatement( 1243 var loop = new ast.ForInStatement(
1208 variable, 1244 variable,
1209 scope.buildExpression(node.iterable), 1245 scope.buildExpression(node.iterable),
1210 makeBreakTarget(body, continueNode), 1246 makeBreakTarget(body, continueNode),
1211 isAsync: node.awaitKeyword != null); 1247 isAsync: node.awaitKeyword != null)..fileOffset = node.offset;
1212 return makeBreakTarget(loop, breakNode); 1248 return makeBreakTarget(loop, breakNode);
1213 } 1249 }
1214 1250
1215 ast.Statement visitIfStatement(IfStatement node) { 1251 ast.Statement visitIfStatement(IfStatement node) {
1216 return new ast.IfStatement(scope.buildExpression(node.condition), 1252 return new ast.IfStatement(scope.buildExpression(node.condition),
1217 build(node.thenStatement), buildOptional(node.elseStatement)); 1253 build(node.thenStatement), buildOptional(node.elseStatement));
1218 } 1254 }
1219 1255
1220 ast.Statement visitReturnStatement(ReturnStatement node) { 1256 ast.Statement visitReturnStatement(ReturnStatement node) {
1221 return new ast.ReturnStatement( 1257 return new ast.ReturnStatement(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 ast.Statement visitYieldStatement(YieldStatement node) { 1308 ast.Statement visitYieldStatement(YieldStatement node) {
1273 return new ast.YieldStatement(scope.buildExpression(node.expression), 1309 return new ast.YieldStatement(scope.buildExpression(node.expression),
1274 isYieldStar: node.star != null); 1310 isYieldStar: node.star != null);
1275 } 1311 }
1276 1312
1277 ast.Statement visitFunctionDeclarationStatement( 1313 ast.Statement visitFunctionDeclarationStatement(
1278 FunctionDeclarationStatement node) { 1314 FunctionDeclarationStatement node) {
1279 var declaration = node.functionDeclaration; 1315 var declaration = node.functionDeclaration;
1280 var expression = declaration.functionExpression; 1316 var expression = declaration.functionExpression;
1281 LocalElement element = declaration.element as dynamic; // Cross cast. 1317 LocalElement element = declaration.element as dynamic; // Cross cast.
1282 // TODO: Set a function type on the variable.
1283 return new ast.FunctionDeclaration( 1318 return new ast.FunctionDeclaration(
1284 scope.makeVariableDeclaration(element), 1319 scope.makeVariableDeclaration(element,
1320 type: scope.buildType(declaration.element.type)),
1285 scope.buildFunctionNode(expression.parameters, expression.body, 1321 scope.buildFunctionNode(expression.parameters, expression.body,
1286 typeParameters: scope.buildOptionalTypeParameterList( 1322 typeParameters: scope.buildOptionalTypeParameterList(
1287 expression.typeParameters, 1323 expression.typeParameters,
1288 strongModeOnly: true), 1324 strongModeOnly: true),
1289 returnType: declaration.returnType)); 1325 returnType: declaration.returnType));
1290 } 1326 }
1291 1327
1292 @override 1328 @override
1293 visitStatement(Statement node) { 1329 visitStatement(Statement node) {
1294 return scope.internalError('Unhandled statement ${node.runtimeType}'); 1330 return scope.internalError('Unhandled statement ${node.runtimeType}');
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
2118 /// If [boundVariables] is null, no type variables are replaced, otherwise all 2154 /// If [boundVariables] is null, no type variables are replaced, otherwise all
2119 /// type variables except those in [boundVariables] are replaced. In other 2155 /// type variables except those in [boundVariables] are replaced. In other
2120 /// words, it represents the bound variables, or "all variables" if omitted. 2156 /// words, it represents the bound variables, or "all variables" if omitted.
2121 ast.DartType convertType( 2157 ast.DartType convertType(
2122 DartType type, List<TypeParameterElement> boundVariables) { 2158 DartType type, List<TypeParameterElement> boundVariables) {
2123 if (type is TypeParameterType) { 2159 if (type is TypeParameterType) {
2124 if (isUnreifiedTypeParameter(type.element)) { 2160 if (isUnreifiedTypeParameter(type.element)) {
2125 return const ast.DynamicType(); 2161 return const ast.DynamicType();
2126 } 2162 }
2127 if (boundVariables == null || boundVariables.contains(type)) { 2163 if (boundVariables == null || boundVariables.contains(type)) {
2128 var typeParameter = scope.getTypeParameterReference(type.element); 2164 var typeParameter = scope.tryGetTypeParameterReference(type.element);
2165 if (typeParameter == null) {
2166 // The analyzer sometimes gives us a type parameter that was not
2167 // bound anywhere. Make sure we do not emit a dangling reference.
2168 if (type.element.bound != null) {
2169 return convertType(type.element.bound, []);
2170 }
2171 return const ast.DynamicType();
2172 }
2129 if (!scope.allowClassTypeParameters && 2173 if (!scope.allowClassTypeParameters &&
2130 typeParameter.parent is ast.Class) { 2174 typeParameter.parent is ast.Class) {
2131 return const ast.InvalidType(); 2175 return const ast.InvalidType();
2132 } 2176 }
2133 return new ast.TypeParameterType(typeParameter); 2177 return new ast.TypeParameterType(typeParameter);
2134 } else { 2178 } else {
2135 return const ast.DynamicType(); 2179 return const ast.DynamicType();
2136 } 2180 }
2137 } else if (type is InterfaceType) { 2181 } else if (type is InterfaceType) {
2138 var classNode = scope.getClassReference(type.element); 2182 var classNode = scope.getClassReference(type.element);
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
2865 if (list[i - 1].compareTo(item) == 0) { 2909 if (list[i - 1].compareTo(item) == 0) {
2866 ++deleted; 2910 ++deleted;
2867 } else if (deleted > 0) { 2911 } else if (deleted > 0) {
2868 list[i - deleted] = item; 2912 list[i - deleted] = item;
2869 } 2913 }
2870 } 2914 }
2871 if (deleted > 0) { 2915 if (deleted > 0) {
2872 list.length -= deleted; 2916 list.length -= deleted;
2873 } 2917 }
2874 } 2918 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/lib/ast.dart » ('j') | pkg/kernel/testcases/closures/capture_closure.dart.expect » ('J')

Powered by Google App Engine
This is Rietveld 408576698