| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index f40e27065ff31d72dbae4836cab4221d027e966f..5de52be15ed167191e55a7c85fd916fe5383f9e2 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -56,7 +56,7 @@ const DCALL = 'dcall';
|
| const DSEND = 'dsend';
|
|
|
| class JSCodegenVisitor extends GeneralizingAstVisitor
|
| - with ClosureAnnotator, JsTypeRefCodegen {
|
| + with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference {
|
| final AbstractCompiler compiler;
|
| final CodegenOptions options;
|
| final LibraryElement currentLibrary;
|
| @@ -111,8 +111,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
|
|
| bool _isDartRuntime;
|
|
|
| - NullableTypeInference _nullInference;
|
| -
|
| JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
|
| this._extensionTypes, this._fieldsNeedingStorage)
|
| : compiler = compiler,
|
| @@ -155,8 +153,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| // TODO(jmesserly): ideally we could do this at a smaller granularity.
|
| // We'll need to be consistent about when we're generating functions, and
|
| // only run this on the outermost function.
|
| - _nullInference =
|
| - new NullableTypeInference.forLibrary(_isPrimitiveType, units);
|
| + inferNullableTypesInLibrary(units);
|
|
|
| _constField = new ConstFieldVisitor(types, library.library.element.source);
|
|
|
| @@ -2640,7 +2637,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| /// For these types we generate a calling convention via static
|
| /// "extension methods". This allows types to be extended without adding
|
| /// extensions directly on the prototype.
|
| - bool _isPrimitiveType(DartType t) =>
|
| + bool isPrimitiveType(DartType t) =>
|
| typeIsPrimitiveInJS(t) || t == _types.stringType;
|
|
|
| bool typeIsPrimitiveInJS(DartType t) =>
|
| @@ -2654,17 +2651,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| JS.Expression notNull(Expression expr) {
|
| if (expr == null) return null;
|
| var jsExpr = _visit(expr);
|
| - if (!_isNullable(expr)) return jsExpr;
|
| + if (!isNullable(expr)) return jsExpr;
|
| return js.call('dart.notNull(#)', jsExpr);
|
| }
|
|
|
| - /// Returns true if [expr] can be null, optionally using [localIsNullable]
|
| - /// for locals.
|
| - ///
|
| - /// This analysis is conservative and incomplete, but it can optimize many
|
| - /// common patterns.
|
| - bool _isNullable(Expression expr) => _nullInference.isNullable(expr);
|
| -
|
| @override
|
| JS.Expression visitBinaryExpression(BinaryExpression node) {
|
| var op = node.operator;
|
| @@ -2692,7 +2682,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| if (op.type.lexeme == '??') {
|
| // TODO(jmesserly): leave RHS for debugging?
|
| // This should be a hint or warning for dead code.
|
| - if (!_isNullable(left)) return _visit(left);
|
| + if (!isNullable(left)) return _visit(left);
|
|
|
| var vars = <String, JS.Expression>{};
|
| // Desugar `l ?? r` as `l != null ? l : r`
|
| @@ -2737,7 +2727,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
|
|
| var leftType = _canonicalizeNumTypes(getStaticType(left));
|
| var rightType = _canonicalizeNumTypes(getStaticType(right));
|
| - return _isPrimitiveType(leftType) && leftType == rightType;
|
| + return isPrimitiveType(leftType) && leftType == rightType;
|
| }
|
|
|
| bool _isNull(Expression expr) => expr is NullLiteral;
|
| @@ -2756,7 +2746,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| id.staticElement = new TemporaryVariableElement.forNode(id);
|
| id.staticType = type;
|
| DynamicInvoke.set(id, type.isDynamic);
|
| - _nullInference.addVariable(id.staticElement, nullable: nullable);
|
| + addTemporaryVariable(id.staticElement, nullable: nullable);
|
| return id;
|
| }
|
|
|
| @@ -2863,7 +2853,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
|
|
| var dispatchType = getStaticType(expr);
|
| if (unaryOperationIsPrimitive(dispatchType)) {
|
| - if (!_isNullable(expr)) {
|
| + if (!isNullable(expr)) {
|
| return js.call('#$op', _visit(expr));
|
| }
|
| }
|
| @@ -2895,7 +2885,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
|
|
| var dispatchType = getStaticType(expr);
|
| if (unaryOperationIsPrimitive(dispatchType)) {
|
| - if (!_isNullable(expr)) {
|
| + if (!isNullable(expr)) {
|
| return js.call('$op#', _visit(expr));
|
| } else if (op.lexeme == '++' || op.lexeme == '--') {
|
| // We need a null check, so the increment must be expanded out.
|
| @@ -2994,7 +2984,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| var op = _getOperator(node);
|
| if (op != null && op.lexeme == '?.') {
|
| var nodeTarget = _getTarget(node);
|
| - if (!_isNullable(nodeTarget)) {
|
| + if (!isNullable(nodeTarget)) {
|
| node = _stripNullAwareOp(node, nodeTarget);
|
| break;
|
| }
|
| @@ -3031,14 +3021,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
|
|
| bool _requiresStaticDispatch(Expression target, String memberName) {
|
| var type = getStaticType(target);
|
| - if (!_isObjectProperty(memberName)) {
|
| + if (!isObjectProperty(memberName)) {
|
| return false;
|
| }
|
|
|
| // If the target could be `null`, we need static dispatch.
|
| // If the target may be an extension type, we also use static dispatch
|
| // as we don't symbolize object properties like hashCode.
|
| - return _isNullable(target) ||
|
| + return isNullable(target) ||
|
| (_extensionTypes.contains(type.element) && target is! SuperExpression);
|
| }
|
|
|
| @@ -3629,7 +3619,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| if (allowExtensions &&
|
| baseType != null &&
|
| _extensionTypes.contains(baseType.element) &&
|
| - !_isObjectProperty(name)) {
|
| + !isObjectProperty(name)) {
|
| return js.call('dartx.#', _propertyName(name));
|
| }
|
|
|
| @@ -3678,7 +3668,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| return (element != null && !element.isStatic);
|
| }
|
|
|
| - bool _isObjectProperty(String name) {
|
| + bool isObjectProperty(String name) {
|
| return _isObjectGetter(name) || _isObjectMethod(name);
|
| }
|
|
|
|
|