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 |