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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1752193002: Add a few more known non-null cases (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 9 months 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 | « lib/runtime/dart/html_common.js ('k') | lib/src/codegen/nullable_type_inference.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 4
5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
6 6
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
8 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 9 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/constant.dart'; 10 import 'package:analyzer/src/generated/constant.dart';
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can 49 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can
50 // import and generate calls to, rather than dart_runtime.js 50 // import and generate calls to, rather than dart_runtime.js
51 const DPUT = 'dput'; 51 const DPUT = 'dput';
52 const DLOAD = 'dload'; 52 const DLOAD = 'dload';
53 const DINDEX = 'dindex'; 53 const DINDEX = 'dindex';
54 const DSETINDEX = 'dsetindex'; 54 const DSETINDEX = 'dsetindex';
55 const DCALL = 'dcall'; 55 const DCALL = 'dcall';
56 const DSEND = 'dsend'; 56 const DSEND = 'dsend';
57 57
58 class JSCodegenVisitor extends GeneralizingAstVisitor 58 class JSCodegenVisitor extends GeneralizingAstVisitor
59 with ClosureAnnotator, JsTypeRefCodegen { 59 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference {
60 final AbstractCompiler compiler; 60 final AbstractCompiler compiler;
61 final CodegenOptions options; 61 final CodegenOptions options;
62 final LibraryElement currentLibrary; 62 final LibraryElement currentLibrary;
63 final StrongTypeSystemImpl rules; 63 final StrongTypeSystemImpl rules;
64 64
65 /// The global extension type table. 65 /// The global extension type table.
66 final ExtensionTypeSet _extensionTypes; 66 final ExtensionTypeSet _extensionTypes;
67 67
68 /// Information that is precomputed for this library, indicates which fields 68 /// Information that is precomputed for this library, indicates which fields
69 /// need storage slots. 69 /// need storage slots.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 ModuleItemLoadOrder _loader; 104 ModuleItemLoadOrder _loader;
105 105
106 /// _interceptors.JSArray<E>, used for List literals. 106 /// _interceptors.JSArray<E>, used for List literals.
107 ClassElement _jsArray; 107 ClassElement _jsArray;
108 108
109 /// The default value of the module object. See [visitLibraryDirective]. 109 /// The default value of the module object. See [visitLibraryDirective].
110 String _jsModuleValue; 110 String _jsModuleValue;
111 111
112 bool _isDartRuntime; 112 bool _isDartRuntime;
113 113
114 NullableTypeInference _nullInference;
115
116 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary, 114 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
117 this._extensionTypes, this._fieldsNeedingStorage) 115 this._extensionTypes, this._fieldsNeedingStorage)
118 : compiler = compiler, 116 : compiler = compiler,
119 options = compiler.options.codegenOptions, 117 options = compiler.options.codegenOptions,
120 _types = compiler.context.typeProvider { 118 _types = compiler.context.typeProvider {
121 _loader = new ModuleItemLoadOrder(_emitModuleItem); 119 _loader = new ModuleItemLoadOrder(_emitModuleItem);
122 120
123 var context = compiler.context; 121 var context = compiler.context;
124 var src = context.sourceFactory.forUri('dart:_interceptors'); 122 var src = context.sourceFactory.forUri('dart:_interceptors');
125 var interceptors = context.computeLibraryElement(src); 123 var interceptors = context.computeLibraryElement(src);
(...skipping 22 matching lines...) Expand all
148 // visit them. It has the ability to sort elements on demand, so 146 // visit them. It has the ability to sort elements on demand, so
149 // dependencies between top level items are handled with a minimal 147 // dependencies between top level items are handled with a minimal
150 // reordering of the user's input code. The loader will call back into 148 // reordering of the user's input code. The loader will call back into
151 // this visitor via [_emitModuleItem] when it's ready to visit the item 149 // this visitor via [_emitModuleItem] when it's ready to visit the item
152 // for real. 150 // for real.
153 _loader.collectElements(currentLibrary, units); 151 _loader.collectElements(currentLibrary, units);
154 152
155 // TODO(jmesserly): ideally we could do this at a smaller granularity. 153 // TODO(jmesserly): ideally we could do this at a smaller granularity.
156 // We'll need to be consistent about when we're generating functions, and 154 // We'll need to be consistent about when we're generating functions, and
157 // only run this on the outermost function. 155 // only run this on the outermost function.
158 _nullInference = 156 inferNullableTypesInLibrary(units);
159 new NullableTypeInference.forLibrary(_isPrimitiveType, units);
160 157
161 _constField = new ConstFieldVisitor(types, library.library.element.source); 158 _constField = new ConstFieldVisitor(types, library.library.element.source);
162 159
163 for (var unit in units) { 160 for (var unit in units) {
164 for (var decl in unit.declarations) { 161 for (var decl in unit.declarations) {
165 if (decl is TopLevelVariableDeclaration) { 162 if (decl is TopLevelVariableDeclaration) {
166 visitTopLevelVariableDeclaration(decl); 163 visitTopLevelVariableDeclaration(decl);
167 } else { 164 } else {
168 _loader.loadDeclaration(decl, decl.element); 165 _loader.loadDeclaration(decl, decl.element);
169 } 166 }
(...skipping 2463 matching lines...) Expand 10 before | Expand all | Expand 10 after
2633 var name = constructor.name; 2630 var name = constructor.name;
2634 var type = constructor.type.type; 2631 var type = constructor.type.type;
2635 return _emitInstanceCreationExpression( 2632 return _emitInstanceCreationExpression(
2636 element, type, name, node.argumentList, node.isConst); 2633 element, type, name, node.argumentList, node.isConst);
2637 } 2634 }
2638 2635
2639 /// True if this type is built-in to JS, and we use the values unwrapped. 2636 /// True if this type is built-in to JS, and we use the values unwrapped.
2640 /// For these types we generate a calling convention via static 2637 /// For these types we generate a calling convention via static
2641 /// "extension methods". This allows types to be extended without adding 2638 /// "extension methods". This allows types to be extended without adding
2642 /// extensions directly on the prototype. 2639 /// extensions directly on the prototype.
2643 bool _isPrimitiveType(DartType t) => 2640 bool isPrimitiveType(DartType t) =>
2644 typeIsPrimitiveInJS(t) || t == _types.stringType; 2641 typeIsPrimitiveInJS(t) || t == _types.stringType;
2645 2642
2646 bool typeIsPrimitiveInJS(DartType t) => 2643 bool typeIsPrimitiveInJS(DartType t) =>
2647 _isNumberInJS(t) || t == _types.boolType; 2644 _isNumberInJS(t) || t == _types.boolType;
2648 2645
2649 bool binaryOperationIsPrimitive(DartType leftT, DartType rightT) => 2646 bool binaryOperationIsPrimitive(DartType leftT, DartType rightT) =>
2650 typeIsPrimitiveInJS(leftT) && typeIsPrimitiveInJS(rightT); 2647 typeIsPrimitiveInJS(leftT) && typeIsPrimitiveInJS(rightT);
2651 2648
2652 bool unaryOperationIsPrimitive(DartType t) => typeIsPrimitiveInJS(t); 2649 bool unaryOperationIsPrimitive(DartType t) => typeIsPrimitiveInJS(t);
2653 2650
2654 JS.Expression notNull(Expression expr) { 2651 JS.Expression notNull(Expression expr) {
2655 if (expr == null) return null; 2652 if (expr == null) return null;
2656 var jsExpr = _visit(expr); 2653 var jsExpr = _visit(expr);
2657 if (!_isNullable(expr)) return jsExpr; 2654 if (!isNullable(expr)) return jsExpr;
2658 return js.call('dart.notNull(#)', jsExpr); 2655 return js.call('dart.notNull(#)', jsExpr);
2659 } 2656 }
2660 2657
2661 /// Returns true if [expr] can be null, optionally using [localIsNullable]
2662 /// for locals.
2663 ///
2664 /// This analysis is conservative and incomplete, but it can optimize many
2665 /// common patterns.
2666 bool _isNullable(Expression expr) => _nullInference.isNullable(expr);
2667
2668 @override 2658 @override
2669 JS.Expression visitBinaryExpression(BinaryExpression node) { 2659 JS.Expression visitBinaryExpression(BinaryExpression node) {
2670 var op = node.operator; 2660 var op = node.operator;
2671 var left = node.leftOperand; 2661 var left = node.leftOperand;
2672 var right = node.rightOperand; 2662 var right = node.rightOperand;
2673 2663
2674 var leftType = getStaticType(left); 2664 var leftType = getStaticType(left);
2675 var rightType = getStaticType(right); 2665 var rightType = getStaticType(right);
2676 2666
2677 var code; 2667 var code;
2678 if (op.type.isEqualityOperator) { 2668 if (op.type.isEqualityOperator) {
2679 // If we statically know LHS or RHS is null we can generate a clean check. 2669 // If we statically know LHS or RHS is null we can generate a clean check.
2680 // We can also do this if both sides are the same primitive type. 2670 // We can also do this if both sides are the same primitive type.
2681 if (_canUsePrimitiveEquality(left, right)) { 2671 if (_canUsePrimitiveEquality(left, right)) {
2682 code = op.type == TokenType.EQ_EQ ? '# == #' : '# != #'; 2672 code = op.type == TokenType.EQ_EQ ? '# == #' : '# != #';
2683 } else if (left is SuperExpression) { 2673 } else if (left is SuperExpression) {
2684 return _emitSend(left, op.lexeme, [right]); 2674 return _emitSend(left, op.lexeme, [right]);
2685 } else { 2675 } else {
2686 var bang = op.type == TokenType.BANG_EQ ? '!' : ''; 2676 var bang = op.type == TokenType.BANG_EQ ? '!' : '';
2687 code = '${bang}dart.equals(#, #)'; 2677 code = '${bang}dart.equals(#, #)';
2688 } 2678 }
2689 return js.call(code, [_visit(left), _visit(right)]); 2679 return js.call(code, [_visit(left), _visit(right)]);
2690 } 2680 }
2691 2681
2692 if (op.type.lexeme == '??') { 2682 if (op.type.lexeme == '??') {
2693 // TODO(jmesserly): leave RHS for debugging? 2683 // TODO(jmesserly): leave RHS for debugging?
2694 // This should be a hint or warning for dead code. 2684 // This should be a hint or warning for dead code.
2695 if (!_isNullable(left)) return _visit(left); 2685 if (!isNullable(left)) return _visit(left);
2696 2686
2697 var vars = <String, JS.Expression>{}; 2687 var vars = <String, JS.Expression>{};
2698 // Desugar `l ?? r` as `l != null ? l : r` 2688 // Desugar `l ?? r` as `l != null ? l : r`
2699 var l = _visit(_bindValue(vars, 'l', left, context: left)); 2689 var l = _visit(_bindValue(vars, 'l', left, context: left));
2700 return new JS.MetaLet(vars, [ 2690 return new JS.MetaLet(vars, [
2701 js.call('# != null ? # : #', [l, l, _visit(right)]) 2691 js.call('# != null ? # : #', [l, l, _visit(right)])
2702 ]); 2692 ]);
2703 } 2693 }
2704 2694
2705 if (binaryOperationIsPrimitive(leftType, rightType) || 2695 if (binaryOperationIsPrimitive(leftType, rightType) ||
(...skipping 24 matching lines...) Expand all
2730 var numType = types.numType; 2720 var numType = types.numType;
2731 if (rules.isSubtypeOf(t, numType)) return numType; 2721 if (rules.isSubtypeOf(t, numType)) return numType;
2732 return t; 2722 return t;
2733 } 2723 }
2734 2724
2735 bool _canUsePrimitiveEquality(Expression left, Expression right) { 2725 bool _canUsePrimitiveEquality(Expression left, Expression right) {
2736 if (_isNull(left) || _isNull(right)) return true; 2726 if (_isNull(left) || _isNull(right)) return true;
2737 2727
2738 var leftType = _canonicalizeNumTypes(getStaticType(left)); 2728 var leftType = _canonicalizeNumTypes(getStaticType(left));
2739 var rightType = _canonicalizeNumTypes(getStaticType(right)); 2729 var rightType = _canonicalizeNumTypes(getStaticType(right));
2740 return _isPrimitiveType(leftType) && leftType == rightType; 2730 return isPrimitiveType(leftType) && leftType == rightType;
2741 } 2731 }
2742 2732
2743 bool _isNull(Expression expr) => expr is NullLiteral; 2733 bool _isNull(Expression expr) => expr is NullLiteral;
2744 2734
2745 SimpleIdentifier _createTemporary(String name, DartType type, 2735 SimpleIdentifier _createTemporary(String name, DartType type,
2746 {bool nullable: true}) { 2736 {bool nullable: true}) {
2747 // We use an invalid source location to signal that this is a temporary. 2737 // We use an invalid source location to signal that this is a temporary.
2748 // See [_isTemporary]. 2738 // See [_isTemporary].
2749 // TODO(jmesserly): alternatives are 2739 // TODO(jmesserly): alternatives are
2750 // * (ab)use Element.isSynthetic, which isn't currently used for 2740 // * (ab)use Element.isSynthetic, which isn't currently used for
2751 // LocalVariableElementImpl, so we could repurpose to mean "temp". 2741 // LocalVariableElementImpl, so we could repurpose to mean "temp".
2752 // * add a new property to LocalVariableElementImpl. 2742 // * add a new property to LocalVariableElementImpl.
2753 // * create a new subtype of LocalVariableElementImpl to mark a temp. 2743 // * create a new subtype of LocalVariableElementImpl to mark a temp.
2754 var id = 2744 var id =
2755 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); 2745 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1));
2756 id.staticElement = new TemporaryVariableElement.forNode(id); 2746 id.staticElement = new TemporaryVariableElement.forNode(id);
2757 id.staticType = type; 2747 id.staticType = type;
2758 DynamicInvoke.set(id, type.isDynamic); 2748 DynamicInvoke.set(id, type.isDynamic);
2759 _nullInference.addVariable(id.staticElement, nullable: nullable); 2749 addTemporaryVariable(id.staticElement, nullable: nullable);
2760 return id; 2750 return id;
2761 } 2751 }
2762 2752
2763 JS.Expression _emitConst(JS.Expression expr()) { 2753 JS.Expression _emitConst(JS.Expression expr()) {
2764 // TODO(jmesserly): emit the constants at top level if possible. 2754 // TODO(jmesserly): emit the constants at top level if possible.
2765 // This wasn't quite working, so disabled for now. 2755 // This wasn't quite working, so disabled for now.
2766 return js.call('dart.const(#)', expr()); 2756 return js.call('dart.const(#)', expr());
2767 } 2757 }
2768 2758
2769 /// Returns a new expression, which can be be used safely *once* on the 2759 /// Returns a new expression, which can be be used safely *once* on the
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2856 /// 2846 ///
2857 /// The [JS.MetaLet] nodes automatically simplify themselves if they can. 2847 /// The [JS.MetaLet] nodes automatically simplify themselves if they can.
2858 /// For example, if the result value is not used, then `t` goes away. 2848 /// For example, if the result value is not used, then `t` goes away.
2859 @override 2849 @override
2860 JS.Expression visitPostfixExpression(PostfixExpression node) { 2850 JS.Expression visitPostfixExpression(PostfixExpression node) {
2861 var op = node.operator; 2851 var op = node.operator;
2862 var expr = node.operand; 2852 var expr = node.operand;
2863 2853
2864 var dispatchType = getStaticType(expr); 2854 var dispatchType = getStaticType(expr);
2865 if (unaryOperationIsPrimitive(dispatchType)) { 2855 if (unaryOperationIsPrimitive(dispatchType)) {
2866 if (!_isNullable(expr)) { 2856 if (!isNullable(expr)) {
2867 return js.call('#$op', _visit(expr)); 2857 return js.call('#$op', _visit(expr));
2868 } 2858 }
2869 } 2859 }
2870 2860
2871 assert(op.lexeme == '++' || op.lexeme == '--'); 2861 assert(op.lexeme == '++' || op.lexeme == '--');
2872 2862
2873 // Handle the left hand side, to ensure each of its subexpressions are 2863 // Handle the left hand side, to ensure each of its subexpressions are
2874 // evaluated only once. 2864 // evaluated only once.
2875 var vars = <String, JS.Expression>{}; 2865 var vars = <String, JS.Expression>{};
2876 var left = _bindLeftHandSide(vars, expr, context: expr); 2866 var left = _bindLeftHandSide(vars, expr, context: expr);
(...skipping 11 matching lines...) Expand all
2888 return new JS.MetaLet(vars, body, statelessResult: true); 2878 return new JS.MetaLet(vars, body, statelessResult: true);
2889 } 2879 }
2890 2880
2891 @override 2881 @override
2892 JS.Expression visitPrefixExpression(PrefixExpression node) { 2882 JS.Expression visitPrefixExpression(PrefixExpression node) {
2893 var op = node.operator; 2883 var op = node.operator;
2894 var expr = node.operand; 2884 var expr = node.operand;
2895 2885
2896 var dispatchType = getStaticType(expr); 2886 var dispatchType = getStaticType(expr);
2897 if (unaryOperationIsPrimitive(dispatchType)) { 2887 if (unaryOperationIsPrimitive(dispatchType)) {
2898 if (!_isNullable(expr)) { 2888 if (!isNullable(expr)) {
2899 return js.call('$op#', _visit(expr)); 2889 return js.call('$op#', _visit(expr));
2900 } else if (op.lexeme == '++' || op.lexeme == '--') { 2890 } else if (op.lexeme == '++' || op.lexeme == '--') {
2901 // We need a null check, so the increment must be expanded out. 2891 // We need a null check, so the increment must be expanded out.
2902 var vars = <String, JS.Expression>{}; 2892 var vars = <String, JS.Expression>{};
2903 var x = _bindLeftHandSide(vars, expr, context: expr); 2893 var x = _bindLeftHandSide(vars, expr, context: expr);
2904 2894
2905 var one = AstBuilder.integerLiteral(1)..staticType = types.intType; 2895 var one = AstBuilder.integerLiteral(1)..staticType = types.intType;
2906 var increment = AstBuilder.binaryExpression(x, op.lexeme[0], one) 2896 var increment = AstBuilder.binaryExpression(x, op.lexeme[0], one)
2907 ..staticElement = node.staticElement 2897 ..staticElement = node.staticElement
2908 ..staticType = getStaticType(expr); 2898 ..staticType = getStaticType(expr);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 // This pattern has the benefit of preserving order, as well as minimizing 2977 // This pattern has the benefit of preserving order, as well as minimizing
2988 // code expansion: each `?.` becomes `, _ => _`, plus one helper call. 2978 // code expansion: each `?.` becomes `, _ => _`, plus one helper call.
2989 // 2979 //
2990 // TODO(jmesserly): we could desugar with MetaLet instead, which may 2980 // TODO(jmesserly): we could desugar with MetaLet instead, which may
2991 // lead to higher performing code, but at the cost of readability. 2981 // lead to higher performing code, but at the cost of readability.
2992 var tail = <JS.Expression>[]; 2982 var tail = <JS.Expression>[];
2993 for (;;) { 2983 for (;;) {
2994 var op = _getOperator(node); 2984 var op = _getOperator(node);
2995 if (op != null && op.lexeme == '?.') { 2985 if (op != null && op.lexeme == '?.') {
2996 var nodeTarget = _getTarget(node); 2986 var nodeTarget = _getTarget(node);
2997 if (!_isNullable(nodeTarget)) { 2987 if (!isNullable(nodeTarget)) {
2998 node = _stripNullAwareOp(node, nodeTarget); 2988 node = _stripNullAwareOp(node, nodeTarget);
2999 break; 2989 break;
3000 } 2990 }
3001 2991
3002 var param = 2992 var param =
3003 _createTemporary('_', nodeTarget.staticType, nullable: false); 2993 _createTemporary('_', nodeTarget.staticType, nullable: false);
3004 var baseNode = _stripNullAwareOp(node, param); 2994 var baseNode = _stripNullAwareOp(node, param);
3005 tail.add(new JS.ArrowFun([_visit(param)], _visit(baseNode))); 2995 tail.add(new JS.ArrowFun([_visit(param)], _visit(baseNode)));
3006 node = nodeTarget; 2996 node = nodeTarget;
3007 } else { 2997 } else {
(...skipping 16 matching lines...) Expand all
3024 return AstBuilder.propertyAccess(newTarget, node.propertyName); 3014 return AstBuilder.propertyAccess(newTarget, node.propertyName);
3025 } else { 3015 } else {
3026 var invoke = node as MethodInvocation; 3016 var invoke = node as MethodInvocation;
3027 return AstBuilder.methodInvoke( 3017 return AstBuilder.methodInvoke(
3028 newTarget, invoke.methodName, invoke.argumentList.arguments); 3018 newTarget, invoke.methodName, invoke.argumentList.arguments);
3029 } 3019 }
3030 } 3020 }
3031 3021
3032 bool _requiresStaticDispatch(Expression target, String memberName) { 3022 bool _requiresStaticDispatch(Expression target, String memberName) {
3033 var type = getStaticType(target); 3023 var type = getStaticType(target);
3034 if (!_isObjectProperty(memberName)) { 3024 if (!isObjectProperty(memberName)) {
3035 return false; 3025 return false;
3036 } 3026 }
3037 3027
3038 // If the target could be `null`, we need static dispatch. 3028 // If the target could be `null`, we need static dispatch.
3039 // If the target may be an extension type, we also use static dispatch 3029 // If the target may be an extension type, we also use static dispatch
3040 // as we don't symbolize object properties like hashCode. 3030 // as we don't symbolize object properties like hashCode.
3041 return _isNullable(target) || 3031 return isNullable(target) ||
3042 (_extensionTypes.contains(type.element) && target is! SuperExpression); 3032 (_extensionTypes.contains(type.element) && target is! SuperExpression);
3043 } 3033 }
3044 3034
3045 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. 3035 /// Shared code for [PrefixedIdentifier] and [PropertyAccess].
3046 JS.Expression _emitGet(Expression target, SimpleIdentifier memberId) { 3036 JS.Expression _emitGet(Expression target, SimpleIdentifier memberId) {
3047 var member = memberId.staticElement; 3037 var member = memberId.staticElement;
3048 if (member is PropertyAccessorElement) { 3038 if (member is PropertyAccessorElement) {
3049 member = (member as PropertyAccessorElement).variable; 3039 member = (member as PropertyAccessorElement).variable;
3050 } 3040 }
3051 bool isStatic = member is ClassMemberElement && member.isStatic; 3041 bool isStatic = member is ClassMemberElement && member.isStatic;
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
3622 } 3612 }
3623 3613
3624 // Dart "extension" methods. Used for JS Array, Boolean, Number, String. 3614 // Dart "extension" methods. Used for JS Array, Boolean, Number, String.
3625 var baseType = type; 3615 var baseType = type;
3626 while (baseType is TypeParameterType) { 3616 while (baseType is TypeParameterType) {
3627 baseType = baseType.element.bound; 3617 baseType = baseType.element.bound;
3628 } 3618 }
3629 if (allowExtensions && 3619 if (allowExtensions &&
3630 baseType != null && 3620 baseType != null &&
3631 _extensionTypes.contains(baseType.element) && 3621 _extensionTypes.contains(baseType.element) &&
3632 !_isObjectProperty(name)) { 3622 !isObjectProperty(name)) {
3633 return js.call('dartx.#', _propertyName(name)); 3623 return js.call('dartx.#', _propertyName(name));
3634 } 3624 }
3635 3625
3636 return _propertyName(name); 3626 return _propertyName(name);
3637 } 3627 }
3638 3628
3639 bool _externalOrNative(node) => 3629 bool _externalOrNative(node) =>
3640 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; 3630 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody;
3641 3631
3642 FunctionBody _functionBody(node) => 3632 FunctionBody _functionBody(node) =>
(...skipping 28 matching lines...) Expand all
3671 bool _isObjectGetter(String name) { 3661 bool _isObjectGetter(String name) {
3672 PropertyAccessorElement element = _types.objectType.element.getGetter(name); 3662 PropertyAccessorElement element = _types.objectType.element.getGetter(name);
3673 return (element != null && !element.isStatic); 3663 return (element != null && !element.isStatic);
3674 } 3664 }
3675 3665
3676 bool _isObjectMethod(String name) { 3666 bool _isObjectMethod(String name) {
3677 MethodElement element = _types.objectType.element.getMethod(name); 3667 MethodElement element = _types.objectType.element.getMethod(name);
3678 return (element != null && !element.isStatic); 3668 return (element != null && !element.isStatic);
3679 } 3669 }
3680 3670
3681 bool _isObjectProperty(String name) { 3671 bool isObjectProperty(String name) {
3682 return _isObjectGetter(name) || _isObjectMethod(name); 3672 return _isObjectGetter(name) || _isObjectMethod(name);
3683 } 3673 }
3684 3674
3685 // TODO(leafp): Various analyzer pieces computed similar things. 3675 // TODO(leafp): Various analyzer pieces computed similar things.
3686 // Share this logic somewhere? 3676 // Share this logic somewhere?
3687 DartType _getExpectedReturnType(ExecutableElement element) { 3677 DartType _getExpectedReturnType(ExecutableElement element) {
3688 FunctionType functionType = element.type; 3678 FunctionType functionType = element.type;
3689 if (functionType == null) { 3679 if (functionType == null) {
3690 return DynamicTypeImpl.instance; 3680 return DynamicTypeImpl.instance;
3691 } 3681 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
3861 3851
3862 /// A special kind of element created by the compiler, signifying a temporary 3852 /// A special kind of element created by the compiler, signifying a temporary
3863 /// variable. These objects use instance equality, and should be shared 3853 /// variable. These objects use instance equality, and should be shared
3864 /// everywhere in the tree where they are treated as the same variable. 3854 /// everywhere in the tree where they are treated as the same variable.
3865 class TemporaryVariableElement extends LocalVariableElementImpl { 3855 class TemporaryVariableElement extends LocalVariableElementImpl {
3866 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3856 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3867 3857
3868 int get hashCode => identityHashCode(this); 3858 int get hashCode => identityHashCode(this);
3869 bool operator ==(Object other) => identical(this, other); 3859 bool operator ==(Object other) => identical(this, other);
3870 } 3860 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/html_common.js ('k') | lib/src/codegen/nullable_type_inference.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698