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

Unified Diff: pkg/dev_compiler/lib/src/compiler/code_generator.dart

Issue 2994203002: Optimize DDC private library files. (Closed)
Patch Set: Address comments Created 3 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: pkg/dev_compiler/lib/src/compiler/code_generator.dart
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index 9deaaa4fa053320d93a13df21a5d4f3fb4bdeee7..ef3e808719eb39089e9ed141107b44d38baaa13e 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -44,7 +44,7 @@ import 'js_interop.dart';
import 'js_metalet.dart' as JS;
import 'js_names.dart' as JS;
import 'js_typeref_codegen.dart' show JsTypeRefCodegen;
-import 'js_typerep.dart' show JSTypeRep;
+import 'js_typerep.dart' show JSTypeRep, JSType;
import 'module_builder.dart' show pathToJSIdentifier;
import 'nullable_type_inference.dart' show NullableTypeInference;
import 'property_model.dart';
@@ -135,8 +135,11 @@ class CodeGenerator extends Object
/// The dart:core `identical` element.
final FunctionElement _coreIdentical;
- /// The dart:_interceptors JSArray element.
+ /// The dart:_interceptors implementation elements.
final ClassElement _jsArray;
+ final ClassElement _jsBool;
+ final ClassElement _jsNumber;
+ final ClassElement _jsString;
final ClassElement boolClass;
final ClassElement intClass;
@@ -205,6 +208,9 @@ class CodeGenerator extends Object
_coreIdentical =
_getLibrary(c, 'dart:core').publicNamespace.get('identical'),
_jsArray = _getLibrary(c, 'dart:_interceptors').getType('JSArray'),
+ _jsBool = _getLibrary(c, 'dart:_interceptors').getType('JSBool'),
+ _jsString = _getLibrary(c, 'dart:_interceptors').getType('JSString'),
+ _jsNumber = _getLibrary(c, 'dart:_interceptors').getType('JSNumber'),
interceptorClass =
_getLibrary(c, 'dart:_interceptors').getType('Interceptor'),
dartCoreLibrary = _getLibrary(c, 'dart:core'),
@@ -2432,6 +2438,9 @@ class CodeGenerator extends Object
var castType = _emitType(paramElement.type);
body.add(js.statement('#._check(#);', [castType, jsParam]));
}
+ if (_annotatedNullCheck(paramElement)) {
+ body.add(nullParameterCheck(jsParam));
+ }
}
return body.isEmpty ? null : _statement(body);
}
@@ -3267,6 +3276,9 @@ class CodeGenerator extends Object
// (for example, x is IndexExpression) we evaluate those once.
var vars = <JS.MetaLetVariable, JS.Expression>{};
var lhs = _bindLeftHandSide(vars, left, context: context);
+ // TODO(leafp): The element for lhs here will be the setter element
+ // instead of the getter element if lhs is a property access. This
+ // interferes with nullability analysis.
Expression inc = AstBuilder.binaryExpression(lhs, op, right)
..staticElement = element
..staticType = getStaticType(lhs);
@@ -4050,7 +4062,10 @@ class CodeGenerator extends Object
var v = variables[0];
if (v.initializer != null) {
var name = new JS.Identifier(v.name.name);
- return _visit<JS.Expression>(v.initializer).toVariableDeclaration(name);
+ var value = _annotatedNullCheck(v.element)
+ ? notNull(v.initializer)
+ : _visit<JS.Expression>(v.initializer);
+ return value.toVariableDeclaration(name);
}
}
return _visit<JS.Expression>(node.variables).toStatement();
@@ -4093,7 +4108,9 @@ class CodeGenerator extends Object
}
JS.Expression _visitInitializer(VariableDeclaration node) {
- var value = _visit(node.initializer);
+ var value = _annotatedNullCheck(node.element)
+ ? notNull(node.initializer)
+ : _visit(node.initializer);
// explicitly initialize to null, to avoid getting `undefined`.
// TODO(jmesserly): do this only for vars that aren't definitely assigned.
return value ?? new JS.LiteralNull();
@@ -4254,6 +4271,24 @@ class CodeGenerator extends Object
bool isPrimitiveType(DartType t) => typeRep.isPrimitive(t);
+ /// Given a Dart type return the known implementation type, if any.
+ /// Given `bool`, `String`, or `num`/`int`/`double`,
+ /// returns the corresponding type in `dart:_interceptors`:
+ /// `JSBool`, `JSString`, and `JSNumber` respectively, otherwise null.
+ InterfaceType getImplementationType(DartType t) {
+ JSType rep = typeRep.typeFor(t);
+ // Number, String, and Bool are final
+ if (rep == JSType.jsNumber) return _jsNumber.type;
+ if (rep == JSType.jsBoolean) return _jsBool.type;
+ if (rep == JSType.jsString) return _jsString.type;
+ return null;
+ }
+
+ JS.Statement nullParameterCheck(JS.Expression param) {
+ var call = _callHelper('argumentError((#))', [param]);
+ return js.statement('if (# == null) #;', [param, call]);
+ }
+
JS.Expression notNull(Expression expr) {
if (expr == null) return null;
var jsExpr = _visit(expr);
@@ -5116,10 +5151,17 @@ class CodeGenerator extends Object
}
var init = _visit(node.identifier);
+ var iterable = _visit(node.iterable);
+ var body = _visitScope(node.body);
if (init == null) {
- init = js.call('let #', node.loopVariable.identifier.name);
+ var name = node.loopVariable.identifier.name;
+ init = js.call('let #', name);
+ if (_annotatedNullCheck(node.loopVariable.element)) {
+ body =
+ new JS.Block([nullParameterCheck(new JS.Identifier(name)), body]);
+ }
}
- return new JS.ForOf(init, _visit(node.iterable), _visitScope(node.body));
+ return new JS.ForOf(init, iterable, body);
}
JS.Statement _emitAwaitFor(ForEachStatement node) {
@@ -5999,3 +6041,6 @@ bool _isDeferredLoadLibrary(Expression target, SimpleIdentifier name) {
var imports = containingLibrary.getImportsWithPrefix(prefix);
return imports.length == 1 && imports[0].isDeferred;
}
+
+bool _annotatedNullCheck(Element e) =>
+ e != null && findAnnotation(e, isNullCheckAnnotation) != null;

Powered by Google App Engine
This is Rietveld 408576698