| 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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 393 |
| 394 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) { | 394 List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) { |
| 395 if (node == null) return null; | 395 if (node == null) return null; |
| 396 return _typeBuilder.buildList(node.arguments); | 396 return _typeBuilder.buildList(node.arguments); |
| 397 } | 397 } |
| 398 | 398 |
| 399 List<ast.DartType> buildTypeArgumentList(TypeArgumentList node) { | 399 List<ast.DartType> buildTypeArgumentList(TypeArgumentList node) { |
| 400 return _typeBuilder.buildList(node.arguments); | 400 return _typeBuilder.buildList(node.arguments); |
| 401 } | 401 } |
| 402 | 402 |
| 403 List<ast.TypeParameter> buildOptionalTypeParameterList( | 403 List<ast.TypeParameter> buildOptionalTypeParameterList(TypeParameterList node, |
| 404 TypeParameterList node) { | 404 {bool strongModeOnly: false}) { |
| 405 if (node == null) return <ast.TypeParameter>[]; | 405 if (node == null) return <ast.TypeParameter>[]; |
| 406 if (strongModeOnly && !strongMode) return <ast.TypeParameter>[]; |
| 406 return node.typeParameters.map(buildTypeParameter).toList(); | 407 return node.typeParameters.map(buildTypeParameter).toList(); |
| 407 } | 408 } |
| 408 | 409 |
| 409 ast.TypeParameter buildTypeParameter(TypeParameter node) { | 410 ast.TypeParameter buildTypeParameter(TypeParameter node) { |
| 410 return makeTypeParameter(node.element, | 411 return makeTypeParameter(node.element, |
| 411 bound: buildOptionalTypeAnnotation(node.bound) ?? | 412 bound: buildOptionalTypeAnnotation(node.bound) ?? |
| 412 defaultTypeParameterBound); | 413 defaultTypeParameterBound); |
| 413 } | 414 } |
| 414 | 415 |
| 415 ConstructorElement findDefaultConstructor(ClassElement class_) { | 416 ConstructorElement findDefaultConstructor(ClassElement class_) { |
| 416 for (var constructor in class_.constructors) { | 417 for (var constructor in class_.constructors) { |
| 417 // Note: isDefaultConstructor checks if the constructor is suitable for | 418 // Note: isDefaultConstructor checks if the constructor is suitable for |
| 418 // being invoked without arguments. It does not imply that it is | 419 // being invoked without arguments. It does not imply that it is |
| 419 // synthetic. | 420 // synthetic. |
| 420 if (constructor.isDefaultConstructor && !constructor.isFactory) { | 421 if (constructor.isDefaultConstructor && !constructor.isFactory) { |
| 421 return constructor; | 422 return constructor; |
| 422 } | 423 } |
| 423 } | 424 } |
| 424 return null; | 425 return null; |
| 425 } | 426 } |
| 426 | 427 |
| 427 ast.FunctionNode buildFunctionInterface(FunctionTypedElement element) { | 428 ast.FunctionNode buildFunctionInterface(FunctionTypedElement element) { |
| 428 var positional = <ast.VariableDeclaration>[]; | 429 var positional = <ast.VariableDeclaration>[]; |
| 429 var named = <ast.VariableDeclaration>[]; | 430 var named = <ast.VariableDeclaration>[]; |
| 430 int requiredParameterCount = 0; | 431 int requiredParameterCount = 0; |
| 431 // Initialize type parameters in two passes: put them into scope, | 432 // Initialize type parameters in two passes: put them into scope, |
| 432 // and compute the bounds afterwards while they are all in scope. | 433 // and compute the bounds afterwards while they are all in scope. |
| 433 var typeParameters = <ast.TypeParameter>[]; | 434 var typeParameters = <ast.TypeParameter>[]; |
| 434 for (var parameter in element.typeParameters) { | 435 if (strongMode || element is ConstructorElement) { |
| 435 var parameterNode = new ast.TypeParameter(parameter.name); | 436 for (var parameter in element.typeParameters) { |
| 436 typeParameters.add(parameterNode); | 437 var parameterNode = new ast.TypeParameter(parameter.name); |
| 437 localTypeParameters[parameter] = parameterNode; | 438 typeParameters.add(parameterNode); |
| 439 localTypeParameters[parameter] = parameterNode; |
| 440 } |
| 438 } | 441 } |
| 439 for (int i = 0; i < typeParameters.length; ++i) { | 442 for (int i = 0; i < typeParameters.length; ++i) { |
| 440 var parameter = element.typeParameters[i]; | 443 var parameter = element.typeParameters[i]; |
| 441 var parameterNode = typeParameters[i]; | 444 var parameterNode = typeParameters[i]; |
| 442 parameterNode.bound = parameter.bound == null | 445 parameterNode.bound = parameter.bound == null |
| 443 ? defaultTypeParameterBound | 446 ? defaultTypeParameterBound |
| 444 : buildType(parameter.bound); | 447 : buildType(parameter.bound); |
| 445 } | 448 } |
| 446 for (var parameter in element.parameters) { | 449 for (var parameter in element.parameters) { |
| 447 var parameterNode = new ast.VariableDeclaration(parameter.name, | 450 var parameterNode = new ast.VariableDeclaration(parameter.name, |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 | 1276 |
| 1274 ast.Statement visitFunctionDeclarationStatement( | 1277 ast.Statement visitFunctionDeclarationStatement( |
| 1275 FunctionDeclarationStatement node) { | 1278 FunctionDeclarationStatement node) { |
| 1276 var declaration = node.functionDeclaration; | 1279 var declaration = node.functionDeclaration; |
| 1277 var expression = declaration.functionExpression; | 1280 var expression = declaration.functionExpression; |
| 1278 LocalElement element = declaration.element as dynamic; // Cross cast. | 1281 LocalElement element = declaration.element as dynamic; // Cross cast. |
| 1279 // TODO: Set a function type on the variable. | 1282 // TODO: Set a function type on the variable. |
| 1280 return new ast.FunctionDeclaration( | 1283 return new ast.FunctionDeclaration( |
| 1281 scope.makeVariableDeclaration(element), | 1284 scope.makeVariableDeclaration(element), |
| 1282 scope.buildFunctionNode(expression.parameters, expression.body, | 1285 scope.buildFunctionNode(expression.parameters, expression.body, |
| 1283 typeParameters: | 1286 typeParameters: scope.buildOptionalTypeParameterList( |
| 1284 scope.buildOptionalTypeParameterList(expression.typeParameters), | 1287 expression.typeParameters, |
| 1288 strongModeOnly: true), |
| 1285 returnType: declaration.returnType)); | 1289 returnType: declaration.returnType)); |
| 1286 } | 1290 } |
| 1287 | 1291 |
| 1288 @override | 1292 @override |
| 1289 visitStatement(Statement node) { | 1293 visitStatement(Statement node) { |
| 1290 return scope.internalError('Unhandled statement ${node.runtimeType}'); | 1294 return scope.internalError('Unhandled statement ${node.runtimeType}'); |
| 1291 } | 1295 } |
| 1292 } | 1296 } |
| 1293 | 1297 |
| 1294 class ExpressionBuilder | 1298 class ExpressionBuilder |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 return new ast.ConditionalExpression( | 1472 return new ast.ConditionalExpression( |
| 1469 build(node.condition), | 1473 build(node.condition), |
| 1470 build(node.thenExpression), | 1474 build(node.thenExpression), |
| 1471 build(node.elseExpression), | 1475 build(node.elseExpression), |
| 1472 scope.getInferredType(node)); | 1476 scope.getInferredType(node)); |
| 1473 } | 1477 } |
| 1474 | 1478 |
| 1475 ast.Expression visitFunctionExpression(FunctionExpression node) { | 1479 ast.Expression visitFunctionExpression(FunctionExpression node) { |
| 1476 return new ast.FunctionExpression(scope.buildFunctionNode( | 1480 return new ast.FunctionExpression(scope.buildFunctionNode( |
| 1477 node.parameters, node.body, | 1481 node.parameters, node.body, |
| 1478 typeParameters: | 1482 typeParameters: scope.buildOptionalTypeParameterList( |
| 1479 scope.buildOptionalTypeParameterList(node.typeParameters), | 1483 node.typeParameters, |
| 1484 strongModeOnly: true), |
| 1480 inferredReturnType: scope.getInferredReturnType(node))); | 1485 inferredReturnType: scope.getInferredReturnType(node))); |
| 1481 } | 1486 } |
| 1482 | 1487 |
| 1483 ast.Arguments buildArguments(ArgumentList valueArguments, | 1488 ast.Arguments buildArguments(ArgumentList valueArguments, |
| 1484 {TypeArgumentList explicitTypeArguments, | 1489 {TypeArgumentList explicitTypeArguments, |
| 1485 List<ast.DartType> inferTypeArguments()}) { | 1490 List<ast.DartType> inferTypeArguments()}) { |
| 1486 var positional = <ast.Expression>[]; | 1491 var positional = <ast.Expression>[]; |
| 1487 var named = <ast.NamedExpression>[]; | 1492 var named = <ast.NamedExpression>[]; |
| 1488 for (var argument in valueArguments.arguments) { | 1493 for (var argument in valueArguments.arguments) { |
| 1489 if (argument is NamedExpression) { | 1494 if (argument is NamedExpression) { |
| 1490 named.add(new ast.NamedExpression( | 1495 named.add(new ast.NamedExpression( |
| 1491 argument.name.label.name, build(argument.expression))); | 1496 argument.name.label.name, build(argument.expression))); |
| 1492 } else if (named.isNotEmpty) { | 1497 } else if (named.isNotEmpty) { |
| 1493 return scope.emitCompileTimeError( | 1498 return scope.emitCompileTimeError( |
| 1494 ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT); | 1499 ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT); |
| 1495 } else { | 1500 } else { |
| 1496 positional.add(build(argument)); | 1501 positional.add(build(argument)); |
| 1497 } | 1502 } |
| 1498 } | 1503 } |
| 1499 List<ast.DartType> typeArguments; | 1504 List<ast.DartType> typeArguments; |
| 1500 if (explicitTypeArguments != null) { | 1505 if (explicitTypeArguments != null) { |
| 1501 typeArguments = scope.buildTypeArgumentList(explicitTypeArguments); | 1506 typeArguments = scope.buildTypeArgumentList(explicitTypeArguments); |
| 1502 } else if (inferTypeArguments != null) { | 1507 } else if (inferTypeArguments != null) { |
| 1503 typeArguments = inferTypeArguments(); | 1508 typeArguments = inferTypeArguments(); |
| 1504 } | 1509 } |
| 1505 return new ast.Arguments(positional, named: named, types: typeArguments); | 1510 return new ast.Arguments(positional, named: named, types: typeArguments); |
| 1506 } | 1511 } |
| 1507 | 1512 |
| 1508 ast.Arguments buildArgumentsForInvocation(InvocationExpression node) { | 1513 ast.Arguments buildArgumentsForInvocation(InvocationExpression node) { |
| 1509 return buildArguments(node.argumentList, | 1514 if (scope.strongMode) { |
| 1510 explicitTypeArguments: node.typeArguments, | 1515 return buildArguments(node.argumentList, |
| 1511 inferTypeArguments: () => | 1516 explicitTypeArguments: node.typeArguments, |
| 1512 scope.getInferredInvocationTypeArguments(node)); | 1517 inferTypeArguments: () => |
| 1518 scope.getInferredInvocationTypeArguments(node)); |
| 1519 } else { |
| 1520 return buildArguments(node.argumentList); |
| 1521 } |
| 1513 } | 1522 } |
| 1514 | 1523 |
| 1515 static final ast.Name callName = new ast.Name('call'); | 1524 static final ast.Name callName = new ast.Name('call'); |
| 1516 | 1525 |
| 1517 ast.Expression visitFunctionExpressionInvocation( | 1526 ast.Expression visitFunctionExpressionInvocation( |
| 1518 FunctionExpressionInvocation node) { | 1527 FunctionExpressionInvocation node) { |
| 1519 return new ast.MethodInvocation( | 1528 return new ast.MethodInvocation( |
| 1520 build(node.function), | 1529 build(node.function), |
| 1521 callName, | 1530 callName, |
| 1522 buildArgumentsForInvocation(node), | 1531 buildArgumentsForInvocation(node), |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2090 /// to an [ast.DartType]. | 2099 /// to an [ast.DartType]. |
| 2091 ast.DartType buildClosedTypeFromDartType(DartType type) { | 2100 ast.DartType buildClosedTypeFromDartType(DartType type) { |
| 2092 return convertType(type, <TypeParameterElement>[]); | 2101 return convertType(type, <TypeParameterElement>[]); |
| 2093 } | 2102 } |
| 2094 | 2103 |
| 2095 /// Convert to an [ast.DartType] and keep type variables. | 2104 /// Convert to an [ast.DartType] and keep type variables. |
| 2096 ast.DartType buildFromDartType(DartType type) { | 2105 ast.DartType buildFromDartType(DartType type) { |
| 2097 return convertType(type, null); | 2106 return convertType(type, null); |
| 2098 } | 2107 } |
| 2099 | 2108 |
| 2109 /// True if [parameter] should not be reified, because spec mode does not |
| 2110 /// currently reify generic method type parameters. |
| 2111 bool isUnreifiedTypeParameter(TypeParameterElement parameter) { |
| 2112 return !scope.strongMode && parameter.enclosingElement is! ClassElement; |
| 2113 } |
| 2114 |
| 2100 /// Converts [type] to an [ast.DartType], while replacing unbound type | 2115 /// Converts [type] to an [ast.DartType], while replacing unbound type |
| 2101 /// variables with 'dynamic'. | 2116 /// variables with 'dynamic'. |
| 2102 /// | 2117 /// |
| 2103 /// If [boundVariables] is null, no type variables are replaced, otherwise all | 2118 /// If [boundVariables] is null, no type variables are replaced, otherwise all |
| 2104 /// type variables except those in [boundVariables] are replaced. In other | 2119 /// type variables except those in [boundVariables] are replaced. In other |
| 2105 /// words, it represents the bound variables, or "all variables" if omitted. | 2120 /// words, it represents the bound variables, or "all variables" if omitted. |
| 2106 ast.DartType convertType( | 2121 ast.DartType convertType( |
| 2107 DartType type, List<TypeParameterElement> boundVariables) { | 2122 DartType type, List<TypeParameterElement> boundVariables) { |
| 2108 if (type is TypeParameterType) { | 2123 if (type is TypeParameterType) { |
| 2124 if (isUnreifiedTypeParameter(type.element)) { |
| 2125 return const ast.DynamicType(); |
| 2126 } |
| 2109 if (boundVariables == null || boundVariables.contains(type)) { | 2127 if (boundVariables == null || boundVariables.contains(type)) { |
| 2110 var typeParameter = scope.getTypeParameterReference(type.element); | 2128 var typeParameter = scope.getTypeParameterReference(type.element); |
| 2111 if (!scope.allowClassTypeParameters && | 2129 if (!scope.allowClassTypeParameters && |
| 2112 typeParameter.parent is ast.Class) { | 2130 typeParameter.parent is ast.Class) { |
| 2113 return const ast.InvalidType(); | 2131 return const ast.InvalidType(); |
| 2114 } | 2132 } |
| 2115 return new ast.TypeParameterType(typeParameter); | 2133 return new ast.TypeParameterType(typeParameter); |
| 2116 } else { | 2134 } else { |
| 2117 return const ast.DynamicType(); | 2135 return const ast.DynamicType(); |
| 2118 } | 2136 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 case ElementKind.FUNCTION_TYPE_ALIAS: | 2225 case ElementKind.FUNCTION_TYPE_ALIAS: |
| 2208 FunctionTypeAliasElement functionType = element; | 2226 FunctionTypeAliasElement functionType = element; |
| 2209 return buildClosedTypeFromDartType(functionType.type); | 2227 return buildClosedTypeFromDartType(functionType.type); |
| 2210 | 2228 |
| 2211 case ElementKind.TYPE_PARAMETER: | 2229 case ElementKind.TYPE_PARAMETER: |
| 2212 var typeParameter = scope.getTypeParameterReference(element); | 2230 var typeParameter = scope.getTypeParameterReference(element); |
| 2213 if (!scope.allowClassTypeParameters && | 2231 if (!scope.allowClassTypeParameters && |
| 2214 typeParameter.parent is ast.Class) { | 2232 typeParameter.parent is ast.Class) { |
| 2215 return const ast.InvalidType(); | 2233 return const ast.InvalidType(); |
| 2216 } | 2234 } |
| 2235 if (isUnreifiedTypeParameter(element)) { |
| 2236 return const ast.DynamicType(); |
| 2237 } |
| 2217 return new ast.TypeParameterType(typeParameter); | 2238 return new ast.TypeParameterType(typeParameter); |
| 2218 | 2239 |
| 2219 case ElementKind.COMPILATION_UNIT: | 2240 case ElementKind.COMPILATION_UNIT: |
| 2220 case ElementKind.CONSTRUCTOR: | 2241 case ElementKind.CONSTRUCTOR: |
| 2221 case ElementKind.EXPORT: | 2242 case ElementKind.EXPORT: |
| 2222 case ElementKind.IMPORT: | 2243 case ElementKind.IMPORT: |
| 2223 case ElementKind.LABEL: | 2244 case ElementKind.LABEL: |
| 2224 case ElementKind.LIBRARY: | 2245 case ElementKind.LIBRARY: |
| 2225 case ElementKind.PREFIX: | 2246 case ElementKind.PREFIX: |
| 2226 case ElementKind.UNIVERSE: | 2247 case ElementKind.UNIVERSE: |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2691 } | 2712 } |
| 2692 } | 2713 } |
| 2693 | 2714 |
| 2694 visitMethodDeclaration(MethodDeclaration node) { | 2715 visitMethodDeclaration(MethodDeclaration node) { |
| 2695 addAnnotations(node.metadata); | 2716 addAnnotations(node.metadata); |
| 2696 ast.Procedure procedure = currentMember; | 2717 ast.Procedure procedure = currentMember; |
| 2697 procedure.function = scope.buildFunctionNode(node.parameters, node.body, | 2718 procedure.function = scope.buildFunctionNode(node.parameters, node.body, |
| 2698 returnType: node.returnType, | 2719 returnType: node.returnType, |
| 2699 inferredReturnType: scope.buildType( | 2720 inferredReturnType: scope.buildType( |
| 2700 resolutionMap.elementDeclaredByMethodDeclaration(node).returnType), | 2721 resolutionMap.elementDeclaredByMethodDeclaration(node).returnType), |
| 2701 typeParameters: | 2722 typeParameters: scope.buildOptionalTypeParameterList( |
| 2702 scope.buildOptionalTypeParameterList(node.typeParameters)) | 2723 node.typeParameters, |
| 2703 ..parent = procedure; | 2724 strongModeOnly: true))..parent = procedure; |
| 2704 handleNativeBody(node.body); | 2725 handleNativeBody(node.body); |
| 2705 } | 2726 } |
| 2706 | 2727 |
| 2707 visitVariableDeclaration(VariableDeclaration node) { | 2728 visitVariableDeclaration(VariableDeclaration node) { |
| 2708 addAnnotations(node.metadata); | 2729 addAnnotations(node.metadata); |
| 2709 ast.Field field = currentMember; | 2730 ast.Field field = currentMember; |
| 2710 field.type = scope.buildType( | 2731 field.type = scope.buildType( |
| 2711 resolutionMap.elementDeclaredByVariableDeclaration(node).type); | 2732 resolutionMap.elementDeclaredByVariableDeclaration(node).type); |
| 2712 if (node.initializer != null) { | 2733 if (node.initializer != null) { |
| 2713 field.initializer = scope.buildTopLevelExpression(node.initializer) | 2734 field.initializer = scope.buildTopLevelExpression(node.initializer) |
| 2714 ..parent = field; | 2735 ..parent = field; |
| 2715 } else if (field.isStatic) { | 2736 } else if (field.isStatic) { |
| 2716 // Add null initializer to static fields without an initializer. | 2737 // Add null initializer to static fields without an initializer. |
| 2717 // For instance fields, this is handled when building the class. | 2738 // For instance fields, this is handled when building the class. |
| 2718 field.initializer = new ast.NullLiteral()..parent = field; | 2739 field.initializer = new ast.NullLiteral()..parent = field; |
| 2719 } | 2740 } |
| 2720 } | 2741 } |
| 2721 | 2742 |
| 2722 visitFunctionDeclaration(FunctionDeclaration node) { | 2743 visitFunctionDeclaration(FunctionDeclaration node) { |
| 2723 var function = node.functionExpression; | 2744 var function = node.functionExpression; |
| 2724 ast.Procedure procedure = currentMember; | 2745 ast.Procedure procedure = currentMember; |
| 2725 procedure.function = scope.buildFunctionNode( | 2746 procedure.function = scope.buildFunctionNode( |
| 2726 function.parameters, function.body, | 2747 function.parameters, function.body, |
| 2727 returnType: node.returnType, | 2748 returnType: node.returnType, |
| 2728 typeParameters: | 2749 typeParameters: scope.buildOptionalTypeParameterList( |
| 2729 scope.buildOptionalTypeParameterList(function.typeParameters)) | 2750 function.typeParameters, |
| 2730 ..parent = procedure; | 2751 strongModeOnly: true))..parent = procedure; |
| 2731 handleNativeBody(function.body); | 2752 handleNativeBody(function.body); |
| 2732 } | 2753 } |
| 2733 | 2754 |
| 2734 visitNode(AstNode node) { | 2755 visitNode(AstNode node) { |
| 2735 log.severe('Unexpected class or library member: $node'); | 2756 log.severe('Unexpected class or library member: $node'); |
| 2736 } | 2757 } |
| 2737 } | 2758 } |
| 2738 | 2759 |
| 2739 /// Internal exception thrown from the expression or statement builder when a | 2760 /// Internal exception thrown from the expression or statement builder when a |
| 2740 /// compilation error is found. | 2761 /// compilation error is found. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2844 if (list[i - 1].compareTo(item) == 0) { | 2865 if (list[i - 1].compareTo(item) == 0) { |
| 2845 ++deleted; | 2866 ++deleted; |
| 2846 } else if (deleted > 0) { | 2867 } else if (deleted > 0) { |
| 2847 list[i - deleted] = item; | 2868 list[i - deleted] = item; |
| 2848 } | 2869 } |
| 2849 } | 2870 } |
| 2850 if (deleted > 0) { | 2871 if (deleted > 0) { |
| 2851 list.length -= deleted; | 2872 list.length -= deleted; |
| 2852 } | 2873 } |
| 2853 } | 2874 } |
| OLD | NEW |