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

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

Issue 1396993002: housecleaning: remove nonnullableTypes (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 2 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
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 library dev_compiler.src.codegen.js_codegen; 5 library dev_compiler.src.codegen.js_codegen;
6 6
7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
8 8
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 // Skip the cast if it's not needed. 318 // Skip the cast if it's not needed.
319 if (rules.isSubTypeOf(from, to)) return fromExpr; 319 if (rules.isSubTypeOf(from, to)) return fromExpr;
320 320
321 // All Dart number types map to a JS double. 321 // All Dart number types map to a JS double.
322 if (_isNumberInJS(from) && _isNumberInJS(to)) { 322 if (_isNumberInJS(from) && _isNumberInJS(to)) {
323 // Make sure to check when converting to int. 323 // Make sure to check when converting to int.
324 if (from != _types.intType && to == _types.intType) { 324 if (from != _types.intType && to == _types.intType) {
325 return js.call('dart.asInt(#)', [fromExpr]); 325 return js.call('dart.asInt(#)', [fromExpr]);
326 } 326 }
327 327
328 if (!rules.isNonNullableType(from) && rules.isNonNullableType(to)) { 328 // A no-op in JavaScript.
329 // Converting from a nullable number to a non-nullable number 329 return fromExpr;
330 // only requires a null check.
331 // TODO(jmesserly): a lot of these checks are meaningless, as people use
332 // `num` to mean "any kind of number" rather than "could be null".
333 // The core libraries especially suffer from this problem, with many of
334 // the `num` methods returning `num`.
335 return js.call('dart.notNull(#)', fromExpr);
336 } else {
337 // A no-op in JavaScript.
338 return fromExpr;
339 }
340 } 330 }
341 331
342 return js.call('dart.as(#, #)', [fromExpr, _emitTypeName(to)]); 332 return js.call('dart.as(#, #)', [fromExpr, _emitTypeName(to)]);
343 } 333 }
344 334
345 @override 335 @override
346 visitIsExpression(IsExpression node) { 336 visitIsExpression(IsExpression node) {
347 // Generate `is` as `dart.is` or `typeof` depending on the RHS type. 337 // Generate `is` as `dart.is` or `typeof` depending on the RHS type.
348 JS.Expression result; 338 JS.Expression result;
349 var type = node.type.type; 339 var type = node.type.type;
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 } 1109 }
1120 1110
1121 for (var f in fields.keys) unsetFields.remove(f); 1111 for (var f in fields.keys) unsetFields.remove(f);
1122 1112
1123 // Initialize all remaining fields 1113 // Initialize all remaining fields
1124 unsetFields.forEach((element, fieldNode) { 1114 unsetFields.forEach((element, fieldNode) {
1125 JS.Expression value; 1115 JS.Expression value;
1126 if (fieldNode.initializer != null) { 1116 if (fieldNode.initializer != null) {
1127 value = _visit(fieldNode.initializer); 1117 value = _visit(fieldNode.initializer);
1128 } else { 1118 } else {
1129 var type = rules.elementType(element);
1130 value = new JS.LiteralNull(); 1119 value = new JS.LiteralNull();
1131 if (rules.maybeNonNullableType(type)) {
1132 value = js.call('dart.as(#, #)', [value, _emitTypeName(type)]);
1133 }
1134 } 1120 }
1135 fields[element] = value; 1121 fields[element] = value;
1136 }); 1122 });
1137 1123
1138 var body = <JS.Statement>[]; 1124 var body = <JS.Statement>[];
1139 fields.forEach((FieldElement e, JS.Expression initialValue) { 1125 fields.forEach((FieldElement e, JS.Expression initialValue) {
1140 var access = _emitMemberName(e.name, type: e.enclosingElement.type); 1126 var access = _emitMemberName(e.name, type: e.enclosingElement.type);
1141 body.add(js.statement('this.# = #;', [access, initialValue])); 1127 body.add(js.statement('this.# = #;', [access, initialValue]));
1142 }); 1128 });
1143 1129
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 /// True if this type is built-in to JS, and we use the values unwrapped. 2154 /// True if this type is built-in to JS, and we use the values unwrapped.
2169 /// For these types we generate a calling convention via static 2155 /// For these types we generate a calling convention via static
2170 /// "extension methods". This allows types to be extended without adding 2156 /// "extension methods". This allows types to be extended without adding
2171 /// extensions directly on the prototype. 2157 /// extensions directly on the prototype.
2172 bool _isJSBuiltinType(DartType t) => 2158 bool _isJSBuiltinType(DartType t) =>
2173 typeIsPrimitiveInJS(t) || t == _types.stringType; 2159 typeIsPrimitiveInJS(t) || t == _types.stringType;
2174 2160
2175 bool typeIsPrimitiveInJS(DartType t) => 2161 bool typeIsPrimitiveInJS(DartType t) =>
2176 _isNumberInJS(t) || t == _types.boolType; 2162 _isNumberInJS(t) || t == _types.boolType;
2177 2163
2178 bool typeIsNonNullablePrimitiveInJS(DartType t) =>
2179 typeIsPrimitiveInJS(t) && rules.isNonNullableType(t);
2180
2181 bool binaryOperationIsPrimitive(DartType leftT, DartType rightT) => 2164 bool binaryOperationIsPrimitive(DartType leftT, DartType rightT) =>
2182 typeIsPrimitiveInJS(leftT) && typeIsPrimitiveInJS(rightT); 2165 typeIsPrimitiveInJS(leftT) && typeIsPrimitiveInJS(rightT);
2183 2166
2184 bool unaryOperationIsPrimitive(DartType t) => typeIsPrimitiveInJS(t); 2167 bool unaryOperationIsPrimitive(DartType t) => typeIsPrimitiveInJS(t);
2185 2168
2186 bool _isNonNullableExpression(Expression expr) { 2169 bool _isNonNullableExpression(Expression expr) {
2187 // If the type is non-nullable, no further checking needed.
2188 if (rules.isNonNullableType(getStaticType(expr))) return true;
2189
2190 // TODO(vsm): Revisit whether we really need this when we get 2170 // TODO(vsm): Revisit whether we really need this when we get
2191 // better non-nullability in the type system. 2171 // better non-nullability in the type system.
2192 // TODO(jmesserly): we do recursive calls in a few places. This could 2172 // TODO(jmesserly): we do recursive calls in a few places. This could
2193 // leads to O(depth) cost for calling this function. We could store the 2173 // leads to O(depth) cost for calling this function. We could store the
2194 // resulting value if that becomes an issue, so we maintain the invariant 2174 // resulting value if that becomes an issue, so we maintain the invariant
2195 // that each node is visited once. 2175 // that each node is visited once.
2196 2176
2197 if (expr is Literal && expr is! NullLiteral) return true; 2177 if (expr is Literal && expr is! NullLiteral) return true;
2198 if (expr is IsExpression) return true; 2178 if (expr is IsExpression) return true;
2199 if (expr is ThisExpression) return true; 2179 if (expr is ThisExpression) return true;
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3333 3313
3334 /// A special kind of element created by the compiler, signifying a temporary 3314 /// A special kind of element created by the compiler, signifying a temporary
3335 /// variable. These objects use instance equality, and should be shared 3315 /// variable. These objects use instance equality, and should be shared
3336 /// everywhere in the tree where they are treated as the same variable. 3316 /// everywhere in the tree where they are treated as the same variable.
3337 class TemporaryVariableElement extends LocalVariableElementImpl { 3317 class TemporaryVariableElement extends LocalVariableElementImpl {
3338 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3318 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3339 3319
3340 int get hashCode => identityHashCode(this); 3320 int get hashCode => identityHashCode(this);
3341 bool operator ==(Object other) => identical(this, other); 3321 bool operator ==(Object other) => identical(this, other);
3342 } 3322 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698