| 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 2334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 void _buildMemberBody(ast.Member member, Element element, AstNode node) { | 2345 void _buildMemberBody(ast.Member member, Element element, AstNode node) { |
| 2346 new MemberBodyBuilder(scope.loader, member, element).build(node); | 2346 new MemberBodyBuilder(scope.loader, member, element).build(node); |
| 2347 } | 2347 } |
| 2348 | 2348 |
| 2349 /// True if the given class member should not be emitted, and does not | 2349 /// True if the given class member should not be emitted, and does not |
| 2350 /// correspond to any Kernel member. | 2350 /// correspond to any Kernel member. |
| 2351 /// | 2351 /// |
| 2352 /// This is true for redirecting factories with a resolved target. These are | 2352 /// This is true for redirecting factories with a resolved target. These are |
| 2353 /// always bypassed at the call site. | 2353 /// always bypassed at the call site. |
| 2354 bool _isIgnoredMember(ClassMember node) { | 2354 bool _isIgnoredMember(ClassMember node) { |
| 2355 return node is ConstructorDeclaration && | 2355 if (node is ConstructorDeclaration && node.factoryKeyword != null) { |
| 2356 node.factoryKeyword != null && | 2356 var element = resolutionMap.elementDeclaredByConstructorDeclaration(node); |
| 2357 resolutionMap | 2357 return element.redirectedConstructor != null && |
| 2358 .elementDeclaredByConstructorDeclaration(node) | 2358 (element.isSynthetic || scope.loader.ignoreRedirectingFactories); |
| 2359 .redirectedConstructor != | 2359 } else { |
| 2360 null; | 2360 return false; |
| 2361 } |
| 2361 } | 2362 } |
| 2362 | 2363 |
| 2363 visitClassDeclaration(ClassDeclaration node) { | 2364 visitClassDeclaration(ClassDeclaration node) { |
| 2364 addAnnotations(node.metadata); | 2365 addAnnotations(node.metadata); |
| 2365 ast.Class classNode = currentClass; | 2366 ast.Class classNode = currentClass; |
| 2366 assert(classNode.members.isEmpty); // All members will be added here. | 2367 assert(classNode.members.isEmpty); // All members will be added here. |
| 2367 | 2368 |
| 2368 bool foundConstructor = false; | 2369 bool foundConstructor = false; |
| 2369 for (var member in node.members) { | 2370 for (var member in node.members) { |
| 2370 if (_isIgnoredMember(member)) continue; | 2371 if (_isIgnoredMember(member)) continue; |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2666 classNode, | 2667 classNode, |
| 2667 types.freshTypeParameters | 2668 types.freshTypeParameters |
| 2668 .map(makeTypeParameterType) | 2669 .map(makeTypeParameterType) |
| 2669 .toList(growable: false)); | 2670 .toList(growable: false)); |
| 2670 var function = scope.buildFunctionNode(node.parameters, node.body, | 2671 var function = scope.buildFunctionNode(node.parameters, node.body, |
| 2671 typeParameters: types.freshTypeParameters, | 2672 typeParameters: types.freshTypeParameters, |
| 2672 inferredReturnType: inferredReturnType); | 2673 inferredReturnType: inferredReturnType); |
| 2673 procedure.function = function..parent = procedure; | 2674 procedure.function = function..parent = procedure; |
| 2674 handleNativeBody(node.body); | 2675 handleNativeBody(node.body); |
| 2675 if (node.redirectedConstructor != null) { | 2676 if (node.redirectedConstructor != null) { |
| 2676 // Redirecting factories with resolved targets don't show up here. | 2677 // Add a new synthetic field to [classNode] for representing factory |
| 2677 assert(resolutionMap | 2678 // constructors. This is used by the new frontend engine to support |
| 2678 .elementDeclaredByConstructorDeclaration(node) | 2679 // resolving source code. |
| 2679 .redirectedConstructor == | 2680 // |
| 2680 null); | 2681 // The synthetic field looks like this: |
| 2682 // |
| 2683 // final _redirecting# = [c1, ..., cn]; |
| 2684 // |
| 2685 // Where each c1 ... cn are an instance of [StaticGet] whose target is |
| 2686 // the redirecting factory created above. The new frontend engine reads |
| 2687 // this field and rewrites them. |
| 2688 // |
| 2689 // TODO(ahe): Generate the correct factory body instead. This requires |
| 2690 // access to default values from other files, we'll probably never do |
| 2691 // that in this file, and instead rely on the new compiler for this. |
| 2692 var element = resolutionMap.elementDeclaredByConstructorDeclaration(node); |
| 2693 assert(!element.isSynthetic); |
| 2694 var expression; |
| 2695 if (node.element.redirectedConstructor != null) { |
| 2696 assert(!scope.loader.ignoreRedirectingFactories); |
| 2697 ConstructorElement element = node.element.redirectedConstructor; |
| 2698 while (element.isFactory && element.redirectedConstructor != null) { |
| 2699 element = element.redirectedConstructor; |
| 2700 } |
| 2701 ast.Member target = scope.getMemberReference(element); |
| 2702 assert(target != null); |
| 2703 expression = new ast.Let( |
| 2704 new ast.VariableDeclaration.forValue(new ast.StaticGet(target)), |
| 2705 new ast.InvalidExpression()); |
| 2706 ast.Name constructors = |
| 2707 new ast.Name("_redirecting#", scope.currentLibrary); |
| 2708 ast.Field constructorsField; |
| 2709 for (ast.Field field in classNode.fields) { |
| 2710 if (field.name == constructors) { |
| 2711 constructorsField = field; |
| 2712 break; |
| 2713 } |
| 2714 } |
| 2715 if (constructorsField == null) { |
| 2716 ast.ListLiteral literal = new ast.ListLiteral(<ast.Expression>[]); |
| 2717 constructorsField = new ast.Field(constructors, isStatic: true, |
| 2718 initializer: literal, fileUri: classNode.fileUri) |
| 2719 ..fileOffset = classNode.fileOffset; |
| 2720 classNode.addMember(constructorsField); |
| 2721 } |
| 2722 ast.ListLiteral literal = constructorsField.initializer; |
| 2723 literal.expressions.add(new ast.StaticGet(procedure)..parent = literal); |
| 2724 } else { |
| 2725 var name = node.redirectedConstructor.type.name.name; |
| 2726 if (node.redirectedConstructor.name != null) { |
| 2727 name += '.' + node.redirectedConstructor.name.name; |
| 2728 } |
| 2729 // TODO(asgerf): Sometimes a TypeError should be thrown. |
| 2730 expression = scope.buildThrowNoSuchMethodError( |
| 2731 new ast.NullLiteral(), name, new ast.Arguments.empty()); |
| 2732 } |
| 2681 var function = procedure.function; | 2733 var function = procedure.function; |
| 2682 var name = node.redirectedConstructor.type.name.name; | 2734 function.body = new ast.ExpressionStatement(expression) |
| 2683 if (node.redirectedConstructor.name != null) { | 2735 ..parent = function; |
| 2684 name += '.' + node.redirectedConstructor.name.name; | |
| 2685 } | |
| 2686 // TODO(asgerf): Sometimes a TypeError should be thrown. | |
| 2687 function.body = new ast.ExpressionStatement( | |
| 2688 scope.buildThrowNoSuchMethodError( | |
| 2689 new ast.NullLiteral(), name, new ast.Arguments.empty())) | |
| 2690 ..parent = function; | |
| 2691 } | 2736 } |
| 2692 } | 2737 } |
| 2693 | 2738 |
| 2694 visitMethodDeclaration(MethodDeclaration node) { | 2739 visitMethodDeclaration(MethodDeclaration node) { |
| 2695 addAnnotations(node.metadata); | 2740 addAnnotations(node.metadata); |
| 2696 ast.Procedure procedure = currentMember; | 2741 ast.Procedure procedure = currentMember; |
| 2697 procedure.function = scope.buildFunctionNode(node.parameters, node.body, | 2742 procedure.function = scope.buildFunctionNode(node.parameters, node.body, |
| 2698 returnType: node.returnType, | 2743 returnType: node.returnType, |
| 2699 inferredReturnType: scope.buildType( | 2744 inferredReturnType: scope.buildType( |
| 2700 resolutionMap.elementDeclaredByMethodDeclaration(node).returnType), | 2745 resolutionMap.elementDeclaredByMethodDeclaration(node).returnType), |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2844 if (list[i - 1].compareTo(item) == 0) { | 2889 if (list[i - 1].compareTo(item) == 0) { |
| 2845 ++deleted; | 2890 ++deleted; |
| 2846 } else if (deleted > 0) { | 2891 } else if (deleted > 0) { |
| 2847 list[i - deleted] = item; | 2892 list[i - deleted] = item; |
| 2848 } | 2893 } |
| 2849 } | 2894 } |
| 2850 if (deleted > 0) { | 2895 if (deleted > 0) { |
| 2851 list.length -= deleted; | 2896 list.length -= deleted; |
| 2852 } | 2897 } |
| 2853 } | 2898 } |
| OLD | NEW |