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

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

Issue 2465263002: Always store the type of a conditional expression on the node. (Closed)
Patch Set: Update test expectation Created 4 years, 1 month 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 | 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 ast.Supertype buildSupertype(DartType type) { 323 ast.Supertype buildSupertype(DartType type) {
324 if (type is InterfaceType) { 324 if (type is InterfaceType) {
325 var classElement = type.element; 325 var classElement = type.element;
326 if (classElement == null) return getRootClassReference().asRawSupertype; 326 if (classElement == null) return getRootClassReference().asRawSupertype;
327 var classNode = getClassReference(classElement); 327 var classNode = getClassReference(classElement);
328 if (classNode.typeParameters.isEmpty || 328 if (classNode.typeParameters.isEmpty ||
329 classNode.typeParameters.length != type.typeArguments.length) { 329 classNode.typeParameters.length != type.typeArguments.length) {
330 return classNode.asRawSupertype; 330 return classNode.asRawSupertype;
331 } else { 331 } else {
332 return new ast.Supertype(classNode, 332 return new ast.Supertype(classNode,
333 type.typeArguments.map(buildType).toList(growable: false)); 333 type.typeArguments.map(buildType).toList(growable: false));
334 } 334 }
335 } 335 }
336 return getRootClassReference().asRawSupertype; 336 return getRootClassReference().asRawSupertype;
337 } 337 }
338 338
339 ast.DartType buildTypeAnnotation(AstNode node) { 339 ast.DartType buildTypeAnnotation(AstNode node) {
340 return new TypeAnnotationBuilder(this).build(node); 340 return new TypeAnnotationBuilder(this).build(node);
341 } 341 }
342 342
343 ast.DartType buildOptionalTypeAnnotation(AstNode node) { 343 ast.DartType buildOptionalTypeAnnotation(AstNode node) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 } 396 }
397 397
398 List<ast.TypeParameter> buildOptionalTypeParameterList( 398 List<ast.TypeParameter> buildOptionalTypeParameterList(
399 TypeParameterList node) { 399 TypeParameterList node) {
400 if (node == null) return <ast.TypeParameter>[]; 400 if (node == null) return <ast.TypeParameter>[];
401 return node.typeParameters.map(buildTypeParameter).toList(); 401 return node.typeParameters.map(buildTypeParameter).toList();
402 } 402 }
403 403
404 ast.TypeParameter buildTypeParameter(TypeParameter node) { 404 ast.TypeParameter buildTypeParameter(TypeParameter node) {
405 return makeTypeParameter(node.element, 405 return makeTypeParameter(node.element,
406 bound: 406 bound: buildOptionalTypeAnnotation(node.bound) ??
407 buildOptionalTypeAnnotation(node.bound) ??
408 defaultTypeParameterBound); 407 defaultTypeParameterBound);
409 } 408 }
410 409
411 ConstructorElement findDefaultConstructor(ClassElement class_) { 410 ConstructorElement findDefaultConstructor(ClassElement class_) {
412 for (var constructor in class_.constructors) { 411 for (var constructor in class_.constructors) {
413 // Note: isDefaultConstructor checks if the constructor is suitable for 412 // Note: isDefaultConstructor checks if the constructor is suitable for
414 // being invoked without arguments. It does not imply that it is 413 // being invoked without arguments. It does not imply that it is
415 // synthetic. 414 // synthetic.
416 if (constructor.isDefaultConstructor && !constructor.isFactory) { 415 if (constructor.isDefaultConstructor && !constructor.isFactory) {
417 return constructor; 416 return constructor;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 if (positionals.isNotEmpty && 674 if (positionals.isNotEmpty &&
676 parameters[positionals.length - 1].parameterKind == named) { 675 parameters[positionals.length - 1].parameterKind == named) {
677 return false; // Too many positional arguments. 676 return false; // Too many positional arguments.
678 } 677 }
679 if (arguments.named.isEmpty) return true; 678 if (arguments.named.isEmpty) return true;
680 int firstNamedParameter = positionals.length; 679 int firstNamedParameter = positionals.length;
681 while (firstNamedParameter < parameters.length && 680 while (firstNamedParameter < parameters.length &&
682 parameters[firstNamedParameter].parameterKind != ParameterKind.NAMED) { 681 parameters[firstNamedParameter].parameterKind != ParameterKind.NAMED) {
683 ++firstNamedParameter; 682 ++firstNamedParameter;
684 } 683 }
685 namedLoop: for (int i = 0; i < arguments.named.length; ++i) { 684 namedLoop:
685 for (int i = 0; i < arguments.named.length; ++i) {
686 String name = arguments.named[i].name; 686 String name = arguments.named[i].name;
687 for (int j = firstNamedParameter; j < parameters.length; ++j) { 687 for (int j = firstNamedParameter; j < parameters.length; ++j) {
688 if (parameters[j].parameterKind == ParameterKind.NAMED && 688 if (parameters[j].parameterKind == ParameterKind.NAMED &&
689 parameters[j].name == name) { 689 parameters[j].name == name) {
690 continue namedLoop; 690 continue namedLoop;
691 } 691 }
692 } 692 }
693 return false; 693 return false;
694 } 694 }
695 return true; 695 return true;
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 } 1317 }
1318 1318
1319 ast.Expression visitAssignmentExpression(AssignmentExpression node) { 1319 ast.Expression visitAssignmentExpression(AssignmentExpression node) {
1320 bool voidContext = isInVoidContext(node); 1320 bool voidContext = isInVoidContext(node);
1321 String operator = node.operator.value(); 1321 String operator = node.operator.value();
1322 var leftHand = buildLeftHandValue(node.leftHandSide); 1322 var leftHand = buildLeftHandValue(node.leftHandSide);
1323 var rightHand = build(node.rightHandSide); 1323 var rightHand = build(node.rightHandSide);
1324 if (operator == '=') { 1324 if (operator == '=') {
1325 return leftHand.buildAssignment(rightHand, voidContext: voidContext); 1325 return leftHand.buildAssignment(rightHand, voidContext: voidContext);
1326 } else if (operator == '??=') { 1326 } else if (operator == '??=') {
1327 return leftHand.buildNullAwareAssignment(rightHand, 1327 return leftHand.buildNullAwareAssignment(
1328 rightHand, scope.buildType(node.staticType),
1328 voidContext: voidContext); 1329 voidContext: voidContext);
1329 } else { 1330 } else {
1330 // Cut off the trailing '='. 1331 // Cut off the trailing '='.
1331 var name = new ast.Name(operator.substring(0, operator.length - 1)); 1332 var name = new ast.Name(operator.substring(0, operator.length - 1));
1332 return leftHand.buildCompoundAssignment(name, rightHand, 1333 return leftHand.buildCompoundAssignment(name, rightHand,
1333 voidContext: voidContext, 1334 voidContext: voidContext,
1334 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); 1335 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
1335 } 1336 }
1336 } 1337 }
1337 1338
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 var inferredType = scope.getInferredType(node); 1684 var inferredType = scope.getInferredType(node);
1684 if (inferredType is ast.InterfaceType) { 1685 if (inferredType is ast.InterfaceType) {
1685 return inferredType.typeArguments.toList(); 1686 return inferredType.typeArguments.toList();
1686 } 1687 }
1687 int numberOfTypeArguments = 1688 int numberOfTypeArguments =
1688 classElement == null ? 0 : classElement.typeParameters.length; 1689 classElement == null ? 0 : classElement.typeParameters.length;
1689 return new List<ast.DartType>.filled( 1690 return new List<ast.DartType>.filled(
1690 numberOfTypeArguments, const ast.DynamicType(), 1691 numberOfTypeArguments, const ast.DynamicType(),
1691 growable: true); 1692 growable: true);
1692 } 1693 }
1694
1693 var arguments = buildArguments(node.argumentList, 1695 var arguments = buildArguments(node.argumentList,
1694 explicitTypeArguments: node.constructorName.type.typeArguments, 1696 explicitTypeArguments: node.constructorName.type.typeArguments,
1695 inferTypeArguments: inferTypeArguments); 1697 inferTypeArguments: inferTypeArguments);
1696 ast.Expression noSuchMethodError() { 1698 ast.Expression noSuchMethodError() {
1697 return node.isConst 1699 return node.isConst
1698 ? scope.emitInvalidConstant() 1700 ? scope.emitInvalidConstant()
1699 : scope.buildThrowNoSuchMethodError( 1701 : scope.buildThrowNoSuchMethodError(
1700 new ast.NullLiteral(), '${node.constructorName}', arguments, 1702 new ast.NullLiteral(), '${node.constructorName}', arguments,
1701 candidateTarget: element); 1703 candidateTarget: element);
1702 } 1704 }
1705
1703 if (element == null) { 1706 if (element == null) {
1704 return noSuchMethodError(); 1707 return noSuchMethodError();
1705 } 1708 }
1706 assert(classElement != null); 1709 assert(classElement != null);
1707 var redirect = getEffectiveFactoryTarget(element); 1710 var redirect = getEffectiveFactoryTarget(element);
1708 if (redirect == null) { 1711 if (redirect == null) {
1709 return scope.buildThrowCompileTimeError( 1712 return scope.buildThrowCompileTimeError(
1710 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT.message); 1713 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT.message);
1711 } 1714 }
1712 if (redirect != element) { 1715 if (redirect != element) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 var receiver = makeOrReuseVariable(build(target)); 1847 var receiver = makeOrReuseVariable(build(target));
1845 return makeLet( 1848 return makeLet(
1846 receiver, 1849 receiver,
1847 new ast.ConditionalExpression( 1850 new ast.ConditionalExpression(
1848 buildIsNull(new ast.VariableGet(receiver)), 1851 buildIsNull(new ast.VariableGet(receiver)),
1849 new ast.NullLiteral(), 1852 new ast.NullLiteral(),
1850 buildDecomposableMethodInvocation( 1853 buildDecomposableMethodInvocation(
1851 new ast.VariableGet(receiver), 1854 new ast.VariableGet(receiver),
1852 scope.buildName(node.methodName), 1855 scope.buildName(node.methodName),
1853 buildArgumentsForInvocation(node), 1856 buildArgumentsForInvocation(node),
1854 element))); 1857 element),
1858 scope.buildType(node.staticType)));
1855 } else { 1859 } else {
1856 return buildDecomposableMethodInvocation( 1860 return buildDecomposableMethodInvocation(
1857 build(node.target), 1861 build(node.target),
1858 scope.buildName(node.methodName), 1862 scope.buildName(node.methodName),
1859 buildArgumentsForInvocation(node), 1863 buildArgumentsForInvocation(node),
1860 element); 1864 element);
1861 } 1865 }
1862 } 1866 }
1863 1867
1864 ast.Expression visitNamedExpression(NamedExpression node) { 1868 ast.Expression visitNamedExpression(NamedExpression node) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 return new SuperPropertyAccessor( 1943 return new SuperPropertyAccessor(
1940 scope.buildName(node.propertyName), 1944 scope.buildName(node.propertyName),
1941 scope.resolveConcreteGet(element, auxiliary), 1945 scope.resolveConcreteGet(element, auxiliary),
1942 scope.resolveConcreteSet(element, auxiliary)); 1946 scope.resolveConcreteSet(element, auxiliary));
1943 } else if (target is Identifier && target.staticElement is ClassElement) { 1947 } else if (target is Identifier && target.staticElement is ClassElement) {
1944 // Note that this case also covers null-aware static access on a class, 1948 // Note that this case also covers null-aware static access on a class,
1945 // which is equivalent to a regular static access. 1949 // which is equivalent to a regular static access.
1946 return scope.staticAccess(node.propertyName.name, element, auxiliary); 1950 return scope.staticAccess(node.propertyName.name, element, auxiliary);
1947 } else if (node.operator.value() == '?.') { 1951 } else if (node.operator.value() == '?.') {
1948 return new NullAwarePropertyAccessor( 1952 return new NullAwarePropertyAccessor(
1949 build(target), scope.buildName(node.propertyName), getter, setter); 1953 build(target), scope.buildName(node.propertyName), getter, setter,
1954 scope.buildType(node.staticType));
1950 } else { 1955 } else {
1951 return PropertyAccessor.make( 1956 return PropertyAccessor.make(
1952 build(target), scope.buildName(node.propertyName), getter, setter); 1957 build(target), scope.buildName(node.propertyName), getter, setter);
1953 } 1958 }
1954 } 1959 }
1955 1960
1956 ast.Expression visitRethrowExpression(RethrowExpression node) { 1961 ast.Expression visitRethrowExpression(RethrowExpression node) {
1957 return new ast.Rethrow(); 1962 return new ast.Rethrow();
1958 } 1963 }
1959 1964
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 // Redirecting factories with resolved targets don't show up here. 2629 // Redirecting factories with resolved targets don't show up here.
2625 assert(node.element.redirectedConstructor == null); 2630 assert(node.element.redirectedConstructor == null);
2626 var function = procedure.function; 2631 var function = procedure.function;
2627 var name = node.redirectedConstructor.type.name.name; 2632 var name = node.redirectedConstructor.type.name.name;
2628 if (node.redirectedConstructor.name != null) { 2633 if (node.redirectedConstructor.name != null) {
2629 name += '.' + node.redirectedConstructor.name.name; 2634 name += '.' + node.redirectedConstructor.name.name;
2630 } 2635 }
2631 // TODO(asgerf): Sometimes a TypeError should be thrown. 2636 // TODO(asgerf): Sometimes a TypeError should be thrown.
2632 function.body = new ast.ExpressionStatement( 2637 function.body = new ast.ExpressionStatement(
2633 scope.buildThrowNoSuchMethodError( 2638 scope.buildThrowNoSuchMethodError(
2634 new ast.NullLiteral(), 2639 new ast.NullLiteral(), name, new ast.Arguments.empty()))
2635 name, 2640 ..parent = function;
2636 new ast.Arguments.empty()))..parent = function;
2637 } 2641 }
2638 } 2642 }
2639 2643
2640 visitMethodDeclaration(MethodDeclaration node) { 2644 visitMethodDeclaration(MethodDeclaration node) {
2641 addAnnotations(node.metadata); 2645 addAnnotations(node.metadata);
2642 ast.Procedure procedure = currentMember; 2646 ast.Procedure procedure = currentMember;
2643 procedure.function = scope.buildFunctionNode(node.parameters, node.body, 2647 procedure.function = scope.buildFunctionNode(node.parameters, node.body,
2644 returnType: node.returnType, 2648 returnType: node.returnType,
2645 inferredReturnType: scope.buildType(node.element.returnType), 2649 inferredReturnType: scope.buildType(node.element.returnType),
2646 typeParameters: 2650 typeParameters:
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 if (element is FieldElement) return element.getter; 2776 if (element is FieldElement) return element.getter;
2773 return element; 2777 return element;
2774 } 2778 }
2775 2779
2776 Element desynthesizeSetter(Element element) { 2780 Element desynthesizeSetter(Element element) {
2777 if (element == null || !element.isSynthetic) return element; 2781 if (element == null || !element.isSynthetic) return element;
2778 if (element is PropertyAccessorElement) return element.variable; 2782 if (element is PropertyAccessorElement) return element.variable;
2779 if (element is FieldElement) return element.setter; 2783 if (element is FieldElement) return element.setter;
2780 return element; 2784 return element;
2781 } 2785 }
OLDNEW
« no previous file with comments | « no previous file | lib/ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698