| OLD | NEW |
| 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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 /// An accessor that generates a 'throw NoSuchMethodError' on both read | 288 /// An accessor that generates a 'throw NoSuchMethodError' on both read |
| 289 /// and write access. | 289 /// and write access. |
| 290 Accessor unresolvedAccess(String name) { | 290 Accessor unresolvedAccess(String name) { |
| 291 return new _StaticAccessor(this, name, null, null); | 291 return new _StaticAccessor(this, name, null, null); |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 class TypeScope extends ReferenceScope { | 295 class TypeScope extends ReferenceScope { |
| 296 final Map<TypeParameterElement, ast.TypeParameter> localTypeParameters = | 296 final Map<TypeParameterElement, ast.TypeParameter> localTypeParameters = |
| 297 <TypeParameterElement, ast.TypeParameter>{}; | 297 <TypeParameterElement, ast.TypeParameter>{}; |
| 298 TypeAnnotationBuilder _typeBuilder; |
| 298 | 299 |
| 299 TypeScope(ReferenceLevelLoader loader) : super(loader); | 300 TypeScope(ReferenceLevelLoader loader) : super(loader) { |
| 301 _typeBuilder = new TypeAnnotationBuilder(this); |
| 302 } |
| 300 | 303 |
| 301 String get location => '?'; | 304 String get location => '?'; |
| 302 | 305 |
| 303 bool get allowClassTypeParameters => false; | 306 bool get allowClassTypeParameters => false; |
| 304 | 307 |
| 305 ast.DartType get defaultTypeParameterBound => getRootClassReference().rawType; | 308 ast.DartType get defaultTypeParameterBound => getRootClassReference().rawType; |
| 306 | 309 |
| 307 ast.TypeParameter getTypeParameterReference(TypeParameterElement element) { | 310 ast.TypeParameter getTypeParameterReference(TypeParameterElement element) { |
| 308 return localTypeParameters[element] ?? | 311 return localTypeParameters[element] ?? |
| 309 loader.tryGetClassTypeParameter(element) ?? | 312 loader.tryGetClassTypeParameter(element) ?? |
| 310 (localTypeParameters[element] = new ast.TypeParameter(element.name)); | 313 (localTypeParameters[element] = new ast.TypeParameter(element.name)); |
| 311 } | 314 } |
| 312 | 315 |
| 313 ast.TypeParameter makeTypeParameter(TypeParameterElement element, | 316 ast.TypeParameter makeTypeParameter(TypeParameterElement element, |
| 314 {ast.DartType bound}) { | 317 {ast.DartType bound}) { |
| 315 var typeParameter = getTypeParameterReference(element); | 318 var typeParameter = getTypeParameterReference(element); |
| 316 assert(bound != null); | 319 assert(bound != null); |
| 317 typeParameter.bound = bound; | 320 typeParameter.bound = bound; |
| 318 return typeParameter; | 321 return typeParameter; |
| 319 } | 322 } |
| 320 | 323 |
| 321 ast.DartType buildType(DartType type) { | 324 ast.DartType buildType(DartType type) { |
| 322 return new TypeAnnotationBuilder(this).buildFromDartType(type); | 325 return _typeBuilder.buildFromDartType(type); |
| 323 } | 326 } |
| 324 | 327 |
| 325 ast.Supertype buildSupertype(DartType type) { | 328 ast.Supertype buildSupertype(DartType type) { |
| 326 if (type is InterfaceType) { | 329 if (type is InterfaceType) { |
| 327 var classElement = type.element; | 330 var classElement = type.element; |
| 328 if (classElement == null) return getRootClassReference().asRawSupertype; | 331 if (classElement == null) return getRootClassReference().asRawSupertype; |
| 329 var classNode = getClassReference(classElement); | 332 var classNode = getClassReference(classElement); |
| 330 if (classNode.typeParameters.isEmpty || | 333 if (classNode.typeParameters.isEmpty || |
| 331 classNode.typeParameters.length != type.typeArguments.length) { | 334 classNode.typeParameters.length != type.typeArguments.length) { |
| 332 return classNode.asRawSupertype; | 335 return classNode.asRawSupertype; |
| 333 } else { | 336 } else { |
| 334 return new ast.Supertype(classNode, | 337 return new ast.Supertype(classNode, |
| 335 type.typeArguments.map(buildType).toList(growable: false)); | 338 type.typeArguments.map(buildType).toList(growable: false)); |
| 336 } | 339 } |
| 337 } | 340 } |
| 338 return getRootClassReference().asRawSupertype; | 341 return getRootClassReference().asRawSupertype; |
| 339 } | 342 } |
| 340 | 343 |
| 341 ast.DartType buildTypeAnnotation(AstNode node) { | 344 ast.DartType buildTypeAnnotation(AstNode node) { |
| 342 return new TypeAnnotationBuilder(this).build(node); | 345 return _typeBuilder.build(node); |
| 343 } | 346 } |
| 344 | 347 |
| 345 ast.DartType buildOptionalTypeAnnotation(AstNode node) { | 348 ast.DartType buildOptionalTypeAnnotation(AstNode node) { |
| 346 return node == null ? null : new TypeAnnotationBuilder(this).build(node); | 349 return node == null ? null : _typeBuilder.build(node); |
| 347 } | 350 } |
| 348 | 351 |
| 349 ast.DartType getInferredType(Expression node) { | 352 ast.DartType getInferredType(Expression node) { |
| 350 if (!strongMode) return const ast.DynamicType(); | 353 if (!strongMode) return const ast.DynamicType(); |
| 351 // TODO: Is this official way to get the strong-mode inferred type? | 354 // TODO: Is this official way to get the strong-mode inferred type? |
| 352 return buildType(node.staticType); | 355 return buildType(node.staticType); |
| 353 } | 356 } |
| 354 | 357 |
| 355 ast.DartType getInferredTypeArgument(Expression node, int index) { | 358 ast.DartType getInferredTypeArgument(Expression node, int index) { |
| 356 var type = getInferredType(node); | 359 var type = getInferredType(node); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 383 } | 386 } |
| 384 return new List<ast.DartType>.filled( | 387 return new List<ast.DartType>.filled( |
| 385 genericFunctionType.typeParameters.length, const ast.DynamicType()); | 388 genericFunctionType.typeParameters.length, const ast.DynamicType()); |
| 386 } else { | 389 } else { |
| 387 return <ast.DartType>[]; | 390 return <ast.DartType>[]; |
| 388 } | 391 } |
| 389 } | 392 } |
| 390 | 393 |
| 391 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) { | 394 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) { |
| 392 if (node == null) return null; | 395 if (node == null) return null; |
| 393 return new TypeAnnotationBuilder(this).buildList(node.arguments); | 396 return _typeBuilder.buildList(node.arguments); |
| 394 } | 397 } |
| 395 | 398 |
| 396 List<ast.DartType> buildTypeArgumentList(TypeArgumentList node) { | 399 List<ast.DartType> buildTypeArgumentList(TypeArgumentList node) { |
| 397 return new TypeAnnotationBuilder(this).buildList(node.arguments); | 400 return _typeBuilder.buildList(node.arguments); |
| 398 } | 401 } |
| 399 | 402 |
| 400 List<ast.TypeParameter> buildOptionalTypeParameterList( | 403 List<ast.TypeParameter> buildOptionalTypeParameterList( |
| 401 TypeParameterList node) { | 404 TypeParameterList node) { |
| 402 if (node == null) return <ast.TypeParameter>[]; | 405 if (node == null) return <ast.TypeParameter>[]; |
| 403 return node.typeParameters.map(buildTypeParameter).toList(); | 406 return node.typeParameters.map(buildTypeParameter).toList(); |
| 404 } | 407 } |
| 405 | 408 |
| 406 ast.TypeParameter buildTypeParameter(TypeParameter node) { | 409 ast.TypeParameter buildTypeParameter(TypeParameter node) { |
| 407 return makeTypeParameter(node.element, | 410 return makeTypeParameter(node.element, |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 LabelStack(String label, this.next) : labels = <String>[label]; | 885 LabelStack(String label, this.next) : labels = <String>[label]; |
| 883 LabelStack.unlabeled(this.next) : labels = <String>[null]; | 886 LabelStack.unlabeled(this.next) : labels = <String>[null]; |
| 884 LabelStack.switchCase(String label, this.next) | 887 LabelStack.switchCase(String label, this.next) |
| 885 : isSwitchTarget = true, | 888 : isSwitchTarget = true, |
| 886 labels = <String>[label]; | 889 labels = <String>[label]; |
| 887 LabelStack.many(this.labels, this.next); | 890 LabelStack.many(this.labels, this.next); |
| 888 } | 891 } |
| 889 | 892 |
| 890 class StatementBuilder extends GeneralizingAstVisitor<ast.Statement> { | 893 class StatementBuilder extends GeneralizingAstVisitor<ast.Statement> { |
| 891 final ExpressionScope scope; | 894 final ExpressionScope scope; |
| 892 final LabelStack breakStack, continueStack; | 895 LabelStack breakStack, continueStack; |
| 893 | 896 |
| 894 StatementBuilder(this.scope, [this.breakStack, this.continueStack]); | 897 StatementBuilder(this.scope, [this.breakStack, this.continueStack]); |
| 895 | 898 |
| 896 ast.Statement build(Statement node) { | 899 ast.Statement build(Statement node) { |
| 897 return node.accept(this); | 900 return node.accept(this); |
| 898 } | 901 } |
| 899 | 902 |
| 900 ast.Statement buildOptional(Statement node) { | 903 ast.Statement buildOptional(Statement node) { |
| 901 return node?.accept(this); | 904 return node?.accept(this); |
| 902 } | 905 } |
| 903 | 906 |
| 904 ast.Statement buildInScope( | 907 ast.Statement buildInScope( |
| 905 Statement node, LabelStack breakNode, LabelStack continueNode) { | 908 Statement node, LabelStack breakNode, LabelStack continueNode) { |
| 906 return new StatementBuilder(scope, breakNode, continueNode).build(node); | 909 var oldBreak = this.breakStack; |
| 910 var oldContinue = this.continueStack; |
| 911 breakStack = breakNode; |
| 912 continueStack = continueNode; |
| 913 var result = build(node); |
| 914 this.breakStack = oldBreak; |
| 915 this.continueStack = oldContinue; |
| 916 return result; |
| 907 } | 917 } |
| 908 | 918 |
| 909 void buildBlockMember(Statement node, List<ast.Statement> output) { | 919 void buildBlockMember(Statement node, List<ast.Statement> output) { |
| 910 if (node is LabeledStatement && | 920 if (node is LabeledStatement && |
| 911 node.statement is VariableDeclarationStatement) { | 921 node.statement is VariableDeclarationStatement) { |
| 912 // If a variable is labeled, its scope is part of the enclosing block. | 922 // If a variable is labeled, its scope is part of the enclosing block. |
| 913 LabeledStatement labeled = node; | 923 LabeledStatement labeled = node; |
| 914 node = labeled.statement; | 924 node = labeled.statement; |
| 915 } | 925 } |
| 916 if (node is VariableDeclarationStatement) { | 926 if (node is VariableDeclarationStatement) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 bodies.add(member.statements); | 1091 bodies.add(member.statements); |
| 1082 currentCase = null; | 1092 currentCase = null; |
| 1083 } | 1093 } |
| 1084 } | 1094 } |
| 1085 if (currentCase != null) { | 1095 if (currentCase != null) { |
| 1086 // Close off a trailing block. | 1096 // Close off a trailing block. |
| 1087 bodies.add(const <Statement>[]); | 1097 bodies.add(const <Statement>[]); |
| 1088 currentCase = null; | 1098 currentCase = null; |
| 1089 } | 1099 } |
| 1090 // Now that the label environment is set up, build the bodies. | 1100 // Now that the label environment is set up, build the bodies. |
| 1091 var innerBuilder = new StatementBuilder(scope, breakNode, continueNode); | 1101 var oldBreak = this.breakStack; |
| 1102 var oldContinue = this.continueStack; |
| 1103 this.breakStack = breakNode; |
| 1104 this.continueStack = continueNode; |
| 1092 for (int i = 0; i < cases.length; ++i) { | 1105 for (int i = 0; i < cases.length; ++i) { |
| 1093 var blockNodes = <ast.Statement>[]; | 1106 var blockNodes = <ast.Statement>[]; |
| 1094 for (var statement in bodies[i]) { | 1107 for (var statement in bodies[i]) { |
| 1095 innerBuilder.buildBlockMember(statement, blockNodes); | 1108 buildBlockMember(statement, blockNodes); |
| 1096 } | 1109 } |
| 1097 if (blockNodes.isEmpty || !isBreakingStatement(blockNodes.last)) { | 1110 if (blockNodes.isEmpty || !isBreakingStatement(blockNodes.last)) { |
| 1098 if (i < cases.length - 1) { | 1111 if (i < cases.length - 1) { |
| 1099 blockNodes.add( | 1112 blockNodes.add( |
| 1100 new ast.ExpressionStatement(scope.buildThrowFallThroughError())); | 1113 new ast.ExpressionStatement(scope.buildThrowFallThroughError())); |
| 1101 } else { | 1114 } else { |
| 1102 var jump = new ast.BreakStatement(null); | 1115 var jump = new ast.BreakStatement(null); |
| 1103 blockNodes.add(jump); | 1116 blockNodes.add(jump); |
| 1104 breakNode.jumps.add(jump); | 1117 breakNode.jumps.add(jump); |
| 1105 } | 1118 } |
| 1106 } | 1119 } |
| 1107 cases[i].body = new ast.Block(blockNodes)..parent = cases[i]; | 1120 cases[i].body = new ast.Block(blockNodes)..parent = cases[i]; |
| 1108 } | 1121 } |
| 1109 // Unwind the stack of case labels and bind their jumps to the case target. | 1122 // Unwind the stack of case labels and bind their jumps to the case target. |
| 1110 while (continueNode != continueStack) { | 1123 while (continueNode != oldContinue) { |
| 1111 for (var jump in continueNode.jumps) { | 1124 for (var jump in continueNode.jumps) { |
| 1112 (jump as ast.ContinueSwitchStatement).target = | 1125 (jump as ast.ContinueSwitchStatement).target = |
| 1113 labelToNode[continueNode.labels.first]; | 1126 labelToNode[continueNode.labels.first]; |
| 1114 } | 1127 } |
| 1115 continueNode = continueNode.next; | 1128 continueNode = continueNode.next; |
| 1116 } | 1129 } |
| 1117 var expression = scope.buildExpression(node.expression); | 1130 var expression = scope.buildExpression(node.expression); |
| 1118 var result = new ast.SwitchStatement(expression, cases); | 1131 var result = new ast.SwitchStatement(expression, cases); |
| 1132 this.breakStack = oldBreak; |
| 1133 this.continueStack = oldContinue; |
| 1119 return makeBreakTarget(result, breakNode); | 1134 return makeBreakTarget(result, breakNode); |
| 1120 } | 1135 } |
| 1121 | 1136 |
| 1122 ast.Statement visitForStatement(ForStatement node) { | 1137 ast.Statement visitForStatement(ForStatement node) { |
| 1123 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[]; | 1138 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[]; |
| 1124 ast.Expression initialExpression; | 1139 ast.Expression initialExpression; |
| 1125 if (node.variables != null) { | 1140 if (node.variables != null) { |
| 1126 VariableDeclarationList list = node.variables; | 1141 VariableDeclarationList list = node.variables; |
| 1127 var type = scope.buildOptionalTypeAnnotation(list.type); | 1142 var type = scope.buildOptionalTypeAnnotation(list.type); |
| 1128 for (var variable in list.variables) { | 1143 for (var variable in list.variables) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 | 1287 |
| 1273 @override | 1288 @override |
| 1274 visitStatement(Statement node) { | 1289 visitStatement(Statement node) { |
| 1275 return scope.internalError('Unhandled statement ${node.runtimeType}'); | 1290 return scope.internalError('Unhandled statement ${node.runtimeType}'); |
| 1276 } | 1291 } |
| 1277 } | 1292 } |
| 1278 | 1293 |
| 1279 class ExpressionBuilder | 1294 class ExpressionBuilder |
| 1280 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { | 1295 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { |
| 1281 final ExpressionScope scope; | 1296 final ExpressionScope scope; |
| 1282 final ast.VariableDeclaration cascadeReceiver; | 1297 ast.VariableDeclaration cascadeReceiver; |
| 1283 ExpressionBuilder(this.scope, [this.cascadeReceiver]); | 1298 ExpressionBuilder(this.scope); |
| 1284 | 1299 |
| 1285 ast.Expression build(Expression node) { | 1300 ast.Expression build(Expression node) { |
| 1286 var result = node.accept(this); | 1301 var result = node.accept(this); |
| 1287 if (result is Accessor) { | 1302 if (result is Accessor) { |
| 1288 result = result.buildSimpleRead(); | 1303 result = result.buildSimpleRead(); |
| 1289 } | 1304 } |
| 1290 return result..fileOffset = _getOffset(node); | 1305 return result..fileOffset = _getOffset(node); |
| 1291 } | 1306 } |
| 1292 | 1307 |
| 1293 int _getOffset(AstNode node) { | 1308 int _getOffset(AstNode node) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 String value = node.components.map(_getTokenValue).join('.'); | 1441 String value = node.components.map(_getTokenValue).join('.'); |
| 1427 return new ast.SymbolLiteral(value); | 1442 return new ast.SymbolLiteral(value); |
| 1428 } | 1443 } |
| 1429 | 1444 |
| 1430 ast.Expression visitCascadeExpression(CascadeExpression node) { | 1445 ast.Expression visitCascadeExpression(CascadeExpression node) { |
| 1431 var receiver = build(node.target); | 1446 var receiver = build(node.target); |
| 1432 // If receiver is a variable it would be tempting to reuse it, but it | 1447 // If receiver is a variable it would be tempting to reuse it, but it |
| 1433 // might be reassigned in one of the cascade sections. | 1448 // might be reassigned in one of the cascade sections. |
| 1434 var receiverVariable = new ast.VariableDeclaration.forValue(receiver, | 1449 var receiverVariable = new ast.VariableDeclaration.forValue(receiver, |
| 1435 type: scope.getInferredType(node.target)); | 1450 type: scope.getInferredType(node.target)); |
| 1436 var inner = new ExpressionBuilder(scope, receiverVariable); | 1451 var oldReceiver = this.cascadeReceiver; |
| 1452 cascadeReceiver = receiverVariable; |
| 1437 ast.Expression result = new ast.VariableGet(receiverVariable); | 1453 ast.Expression result = new ast.VariableGet(receiverVariable); |
| 1438 for (var section in node.cascadeSections.reversed) { | 1454 for (var section in node.cascadeSections.reversed) { |
| 1439 var dummy = new ast.VariableDeclaration.forValue(inner.build(section)); | 1455 var dummy = new ast.VariableDeclaration.forValue(build(section)); |
| 1440 result = new ast.Let(dummy, result); | 1456 result = new ast.Let(dummy, result); |
| 1441 } | 1457 } |
| 1458 cascadeReceiver = oldReceiver; |
| 1442 return new ast.Let(receiverVariable, result); | 1459 return new ast.Let(receiverVariable, result); |
| 1443 } | 1460 } |
| 1444 | 1461 |
| 1445 ast.Expression makeCascadeReceiver() { | 1462 ast.Expression makeCascadeReceiver() { |
| 1446 assert(cascadeReceiver != null); | 1463 assert(cascadeReceiver != null); |
| 1447 return new ast.VariableGet(cascadeReceiver); | 1464 return new ast.VariableGet(cascadeReceiver); |
| 1448 } | 1465 } |
| 1449 | 1466 |
| 1450 ast.Expression visitConditionalExpression(ConditionalExpression node) { | 1467 ast.Expression visitConditionalExpression(ConditionalExpression node) { |
| 1451 return new ast.ConditionalExpression( | 1468 return new ast.ConditionalExpression( |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2095 typeParameter.parent is ast.Class) { | 2112 typeParameter.parent is ast.Class) { |
| 2096 return const ast.InvalidType(); | 2113 return const ast.InvalidType(); |
| 2097 } | 2114 } |
| 2098 return new ast.TypeParameterType(typeParameter); | 2115 return new ast.TypeParameterType(typeParameter); |
| 2099 } else { | 2116 } else { |
| 2100 return const ast.DynamicType(); | 2117 return const ast.DynamicType(); |
| 2101 } | 2118 } |
| 2102 } else if (type is InterfaceType) { | 2119 } else if (type is InterfaceType) { |
| 2103 var classNode = scope.getClassReference(type.element); | 2120 var classNode = scope.getClassReference(type.element); |
| 2104 if (type.typeArguments.length == 0) { | 2121 if (type.typeArguments.length == 0) { |
| 2105 return new ast.InterfaceType(classNode); | 2122 return classNode.rawType; |
| 2106 } | 2123 } |
| 2107 if (type.typeArguments.length != classNode.typeParameters.length) { | 2124 if (type.typeArguments.length != classNode.typeParameters.length) { |
| 2108 log.warning('Type parameter arity error in $type'); | 2125 log.warning('Type parameter arity error in $type'); |
| 2109 return const ast.InvalidType(); | 2126 return const ast.InvalidType(); |
| 2110 } | 2127 } |
| 2111 return new ast.InterfaceType( | 2128 return new ast.InterfaceType( |
| 2112 classNode, convertTypeList(type.typeArguments, boundVariables)); | 2129 classNode, convertTypeList(type.typeArguments, boundVariables)); |
| 2113 } else if (type is FunctionType) { | 2130 } else if (type is FunctionType) { |
| 2114 // TODO: Avoid infinite recursion in case of illegal circular typedef. | 2131 // TODO: Avoid infinite recursion in case of illegal circular typedef. |
| 2115 boundVariables?.addAll(type.typeParameters); | 2132 boundVariables?.addAll(type.typeParameters); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2175 result.add(new ast.NamedType(name, convertType(type, boundVariables))); | 2192 result.add(new ast.NamedType(name, convertType(type, boundVariables))); |
| 2176 }); | 2193 }); |
| 2177 sortAndRemoveDuplicates(result); | 2194 sortAndRemoveDuplicates(result); |
| 2178 return result; | 2195 return result; |
| 2179 } | 2196 } |
| 2180 | 2197 |
| 2181 ast.DartType visitSimpleIdentifier(SimpleIdentifier node) { | 2198 ast.DartType visitSimpleIdentifier(SimpleIdentifier node) { |
| 2182 Element element = node.staticElement; | 2199 Element element = node.staticElement; |
| 2183 switch (ElementKind.of(element)) { | 2200 switch (ElementKind.of(element)) { |
| 2184 case ElementKind.CLASS: | 2201 case ElementKind.CLASS: |
| 2185 return new ast.InterfaceType(scope.getClassReference(element)); | 2202 return scope.getClassReference(element).rawType; |
| 2186 | 2203 |
| 2187 case ElementKind.DYNAMIC: | 2204 case ElementKind.DYNAMIC: |
| 2188 return const ast.DynamicType(); | 2205 return const ast.DynamicType(); |
| 2189 | 2206 |
| 2190 case ElementKind.FUNCTION_TYPE_ALIAS: | 2207 case ElementKind.FUNCTION_TYPE_ALIAS: |
| 2191 FunctionTypeAliasElement functionType = element; | 2208 FunctionTypeAliasElement functionType = element; |
| 2192 return buildClosedTypeFromDartType(functionType.type); | 2209 return buildClosedTypeFromDartType(functionType.type); |
| 2193 | 2210 |
| 2194 case ElementKind.TYPE_PARAMETER: | 2211 case ElementKind.TYPE_PARAMETER: |
| 2195 var typeParameter = scope.getTypeParameterReference(element); | 2212 var typeParameter = scope.getTypeParameterReference(element); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2442 | 2459 |
| 2443 /// True for the `values` field of an `enum` class. | 2460 /// True for the `values` field of an `enum` class. |
| 2444 static bool _isValuesField(FieldElement field) => field.name == 'values'; | 2461 static bool _isValuesField(FieldElement field) => field.name == 'values'; |
| 2445 | 2462 |
| 2446 /// True for the `index` field of an `enum` class. | 2463 /// True for the `index` field of an `enum` class. |
| 2447 static bool _isIndexField(FieldElement field) => field.name == 'index'; | 2464 static bool _isIndexField(FieldElement field) => field.name == 'index'; |
| 2448 | 2465 |
| 2449 visitEnumDeclaration(EnumDeclaration node) { | 2466 visitEnumDeclaration(EnumDeclaration node) { |
| 2450 addAnnotations(node.metadata); | 2467 addAnnotations(node.metadata); |
| 2451 ast.Class classNode = currentClass; | 2468 ast.Class classNode = currentClass; |
| 2452 var intType = | 2469 var intType = scope.loader.getCoreClassReference('int').rawType; |
| 2453 new ast.InterfaceType(scope.loader.getCoreClassReference('int')); | |
| 2454 var indexFieldElement = element.fields.firstWhere(_isIndexField); | 2470 var indexFieldElement = element.fields.firstWhere(_isIndexField); |
| 2455 ast.Field indexField = scope.getMemberReference(indexFieldElement); | 2471 ast.Field indexField = scope.getMemberReference(indexFieldElement); |
| 2456 indexField.type = intType; | 2472 indexField.type = intType; |
| 2457 classNode.addMember(indexField); | 2473 classNode.addMember(indexField); |
| 2458 var parameter = new ast.VariableDeclaration('index', type: intType); | 2474 var parameter = new ast.VariableDeclaration('index', type: intType); |
| 2459 var function = new ast.FunctionNode(new ast.EmptyStatement(), | 2475 var function = new ast.FunctionNode(new ast.EmptyStatement(), |
| 2460 positionalParameters: [parameter]); | 2476 positionalParameters: [parameter]); |
| 2461 var superConstructor = scope.loader.getRootClassConstructorReference(); | 2477 var superConstructor = scope.loader.getRootClassConstructorReference(); |
| 2462 var constructor = new ast.Constructor(function, | 2478 var constructor = new ast.Constructor(function, |
| 2463 name: new ast.Name(''), | 2479 name: new ast.Name(''), |
| 2464 isConst: true, | 2480 isConst: true, |
| 2465 initializers: [ | 2481 initializers: [ |
| 2466 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), | 2482 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), |
| 2467 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) | 2483 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) |
| 2468 ]); | 2484 ]); |
| 2469 classNode.addMember(constructor); | 2485 classNode.addMember(constructor); |
| 2470 int index = 0; | 2486 int index = 0; |
| 2471 var enumConstantFields = <ast.Field>[]; | 2487 var enumConstantFields = <ast.Field>[]; |
| 2472 for (var constant in node.constants) { | 2488 for (var constant in node.constants) { |
| 2473 ast.Field field = scope.getMemberReference(constant.element); | 2489 ast.Field field = scope.getMemberReference(constant.element); |
| 2474 field.initializer = new ast.ConstructorInvocation( | 2490 field.initializer = new ast.ConstructorInvocation( |
| 2475 constructor, new ast.Arguments([new ast.IntLiteral(index)]), | 2491 constructor, new ast.Arguments([new ast.IntLiteral(index)]), |
| 2476 isConst: true)..parent = field; | 2492 isConst: true)..parent = field; |
| 2477 field.type = new ast.InterfaceType(classNode); | 2493 field.type = classNode.rawType; |
| 2478 classNode.addMember(field); | 2494 classNode.addMember(field); |
| 2479 ++index; | 2495 ++index; |
| 2480 enumConstantFields.add(field); | 2496 enumConstantFields.add(field); |
| 2481 } | 2497 } |
| 2482 // Add the 'values' field. | 2498 // Add the 'values' field. |
| 2483 var valuesFieldElement = element.fields.firstWhere(_isValuesField); | 2499 var valuesFieldElement = element.fields.firstWhere(_isValuesField); |
| 2484 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); | 2500 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); |
| 2485 var enumType = new ast.InterfaceType(classNode); | 2501 var enumType = classNode.rawType; |
| 2486 valuesField.type = new ast.InterfaceType( | 2502 valuesField.type = new ast.InterfaceType( |
| 2487 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); | 2503 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); |
| 2488 valuesField.initializer = new ast.ListLiteral( | 2504 valuesField.initializer = new ast.ListLiteral( |
| 2489 enumConstantFields.map(_makeStaticGet).toList(), | 2505 enumConstantFields.map(_makeStaticGet).toList(), |
| 2490 isConst: true, | 2506 isConst: true, |
| 2491 typeArgument: enumType)..parent = valuesField; | 2507 typeArgument: enumType)..parent = valuesField; |
| 2492 classNode.addMember(valuesField); | 2508 classNode.addMember(valuesField); |
| 2493 // TODO: Add the toString method. | 2509 // TODO: Add the toString method. |
| 2494 } | 2510 } |
| 2495 | 2511 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2637 ast.Procedure procedure = currentMember; | 2653 ast.Procedure procedure = currentMember; |
| 2638 ClassElement classElement = resolutionMap | 2654 ClassElement classElement = resolutionMap |
| 2639 .elementDeclaredByConstructorDeclaration(node) | 2655 .elementDeclaredByConstructorDeclaration(node) |
| 2640 .enclosingElement; | 2656 .enclosingElement; |
| 2641 ast.Class classNode = procedure.enclosingClass; | 2657 ast.Class classNode = procedure.enclosingClass; |
| 2642 var types = getFreshTypeParameters(classNode.typeParameters); | 2658 var types = getFreshTypeParameters(classNode.typeParameters); |
| 2643 for (int i = 0; i < classElement.typeParameters.length; ++i) { | 2659 for (int i = 0; i < classElement.typeParameters.length; ++i) { |
| 2644 scope.localTypeParameters[classElement.typeParameters[i]] = | 2660 scope.localTypeParameters[classElement.typeParameters[i]] = |
| 2645 types.freshTypeParameters[i]; | 2661 types.freshTypeParameters[i]; |
| 2646 } | 2662 } |
| 2663 var inferredReturnType = types.freshTypeParameters.isEmpty |
| 2664 ? classNode.rawType |
| 2665 : new ast.InterfaceType( |
| 2666 classNode, |
| 2667 types.freshTypeParameters |
| 2668 .map(makeTypeParameterType) |
| 2669 .toList(growable: false)); |
| 2647 var function = scope.buildFunctionNode(node.parameters, node.body, | 2670 var function = scope.buildFunctionNode(node.parameters, node.body, |
| 2648 typeParameters: types.freshTypeParameters, | 2671 typeParameters: types.freshTypeParameters, |
| 2649 inferredReturnType: new ast.InterfaceType(classNode, | 2672 inferredReturnType: inferredReturnType); |
| 2650 types.freshTypeParameters.map(makeTypeParameterType).toList())); | |
| 2651 procedure.function = function..parent = procedure; | 2673 procedure.function = function..parent = procedure; |
| 2652 handleNativeBody(node.body); | 2674 handleNativeBody(node.body); |
| 2653 if (node.redirectedConstructor != null) { | 2675 if (node.redirectedConstructor != null) { |
| 2654 // Redirecting factories with resolved targets don't show up here. | 2676 // Redirecting factories with resolved targets don't show up here. |
| 2655 assert(resolutionMap | 2677 assert(resolutionMap |
| 2656 .elementDeclaredByConstructorDeclaration(node) | 2678 .elementDeclaredByConstructorDeclaration(node) |
| 2657 .redirectedConstructor == | 2679 .redirectedConstructor == |
| 2658 null); | 2680 null); |
| 2659 var function = procedure.function; | 2681 var function = procedure.function; |
| 2660 var name = node.redirectedConstructor.type.name.name; | 2682 var name = node.redirectedConstructor.type.name.name; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 if (list[i - 1].compareTo(item) == 0) { | 2844 if (list[i - 1].compareTo(item) == 0) { |
| 2823 ++deleted; | 2845 ++deleted; |
| 2824 } else if (deleted > 0) { | 2846 } else if (deleted > 0) { |
| 2825 list[i - deleted] = item; | 2847 list[i - deleted] = item; |
| 2826 } | 2848 } |
| 2827 } | 2849 } |
| 2828 if (deleted > 0) { | 2850 if (deleted > 0) { |
| 2829 list.length -= deleted; | 2851 list.length -= deleted; |
| 2830 } | 2852 } |
| 2831 } | 2853 } |
| OLD | NEW |