diff --git a/pkg/dev_compiler/bin/devc.dart b/pkg/dev_compiler/bin/devc.dart index a2d280b8141a..dab78980c242 100755 --- a/pkg/dev_compiler/bin/devc.dart +++ b/pkg/dev_compiler/bin/devc.dart @@ -33,6 +33,8 @@ final ArgParser argParser = new ArgParser() ..addFlag('force-compile', help: 'Compile code with static errors', defaultsTo: false) ..addFlag('help', abbr: 'h', help: 'Display this message') + ..addFlag('ignore-types', + help: 'Ignore types during codegen', defaultsTo: false) ..addOption('log', abbr: 'l', help: 'Logging level', defaultsTo: 'severe') ..addFlag('mock-sdk', abbr: 'm', help: 'Use a mock Dart SDK', defaultsTo: false) @@ -109,6 +111,7 @@ void main(List argv) { dumpSrcDir: args['dump-src-to'], forceCompile: args['force-compile'], formatOutput: args['dart-gen-fmt'], + ignoreTypes: args['ignore-types'], outputDart: args['dart-gen'], outputDir: args['out'], covariantGenerics: args['covariant-generics'], diff --git a/pkg/dev_compiler/lib/src/checker/rules.dart b/pkg/dev_compiler/lib/src/checker/rules.dart index f0b0578e977d..e1da9b8ba486 100644 --- a/pkg/dev_compiler/lib/src/checker/rules.dart +++ b/pkg/dev_compiler/lib/src/checker/rules.dart @@ -37,25 +37,10 @@ abstract class TypeRules { DartType elementType(Element e); - /// Returns `true` if the target expression is dynamic. - bool isDynamicTarget(Expression expr) => getStaticType(expr).isDynamic; - - /// Returns `true` if the expression is a dynamic property access or prefixed - /// identifier. - bool isDynamicGet(Expression expr) { - var t = getStaticType(expr); - // TODO(jmesserly): we should not allow all property gets on `Function` - return t.isDynamic || t.isDartCoreFunction; - } - - /// Returns `true` if the expression is a dynamic function call or method - /// invocation. - bool isDynamicCall(Expression call) { - var t = getStaticType(call); - // TODO(jmesserly): fix handling of types with `call` methods. These are not - // FunctionType, but they also aren't dynamic calls. - return t.isDynamic || t.isDartCoreFunction || t is! FunctionType; - } + bool isDynamic(DartType t); + bool isDynamicTarget(Expression expr); + bool isDynamicGet(Expression expr); + bool isDynamicCall(Expression call); } class DartRules extends TypeRules { @@ -80,6 +65,12 @@ class DartRules extends TypeRules { DartType elementType(Element e) { return (e as dynamic).type; } + + /// By default, all invocations are dynamic in Dart. + bool isDynamic(DartType t) => true; + bool isDynamicTarget(Expression expr) => true; + bool isDynamicGet(Expression expr) => true; + bool isDynamicCall(Expression call) => true; } class RestrictedRules extends TypeRules { @@ -473,4 +464,29 @@ class RestrictedRules extends TypeRules { DartType elementType(Element e) { return (e as dynamic).type; } + + bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic; + + /// Returns `true` if the target expression is dynamic. + bool isDynamicTarget(Expression expr) => + options.ignoreTypes || getStaticType(expr).isDynamic; + + /// Returns `true` if the expression is a dynamic property access or prefixed + /// identifier. + bool isDynamicGet(Expression expr) { + if (options.ignoreTypes) return true; + var t = getStaticType(expr); + // TODO(jmesserly): we should not allow all property gets on `Function` + return t.isDynamic || t.isDartCoreFunction; + } + + /// Returns `true` if the expression is a dynamic function call or method + /// invocation. + bool isDynamicCall(Expression call) { + if (options.ignoreTypes) return true; + var t = getStaticType(call); + // TODO(jmesserly): fix handling of types with `call` methods. These are not + // FunctionType, but they also aren't dynamic calls. + return t.isDynamic || t.isDartCoreFunction || t is! FunctionType; + } } diff --git a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart index 30deb7fe7c63..1ccc69ca2cd1 100644 --- a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart +++ b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart @@ -1052,10 +1052,11 @@ $name.prototype[Symbol.iterator] = function() { bool _isJSBuiltinType(DartType t) => rules.isNumType(t) || rules.isStringType(t) || rules.isBoolType(t); - bool typeIsPrimitiveInJS(DartType t) => rules.isIntType(t) || - rules.isDoubleType(t) || - rules.isBoolType(t) || - rules.isNumType(t); + bool typeIsPrimitiveInJS(DartType t) => !rules.isDynamic(t) && + (rules.isIntType(t) || + rules.isDoubleType(t) || + rules.isBoolType(t) || + rules.isNumType(t)); bool typeIsNonNullablePrimitiveInJS(DartType t) => typeIsPrimitiveInJS(t) && rules.isNonNullableType(t); diff --git a/pkg/dev_compiler/lib/src/options.dart b/pkg/dev_compiler/lib/src/options.dart index a3a580cbd25a..c9f07933649e 100644 --- a/pkg/dev_compiler/lib/src/options.dart +++ b/pkg/dev_compiler/lib/src/options.dart @@ -64,7 +64,11 @@ class RulesOptions extends TypeOptions { /// Whether to inject casts between Dart assignable types. final bool relaxedCasts; - RulesOptions({this.covariantGenerics: true, this.relaxedCasts: true}); + /// Whether to use static types for code generation. + final bool ignoreTypes; + + RulesOptions({this.covariantGenerics: true, this.relaxedCasts: true, + this.ignoreTypes: false}); } /// General options used by the dev compiler. @@ -140,13 +144,18 @@ class CompilerOptions implements RulesOptions, ResolverOptions { @override final List nonnullableTypes; + /// Whether to use static types for code generation. + @override + final bool ignoreTypes; + CompilerOptions({this.checkSdk: false, this.dumpInfo: false, this.dumpInfoFile, this.dumpSrcDir, this.forceCompile: false, - this.formatOutput: false, this.outputDir, this.outputDart: false, - this.useColors: true, this.covariantGenerics: true, - this.relaxedCasts: true, this.useMultiPackage: false, - this.packageRoot: 'packages/', this.packagePaths: const [], - this.inferFromOverrides: true, this.inferStaticsFromIdentifiers: false, + this.formatOutput: false, this.ignoreTypes: false, this.outputDir, + this.outputDart: false, this.useColors: true, + this.covariantGenerics: true, this.relaxedCasts: true, + this.useMultiPackage: false, this.packageRoot: 'packages/', + this.packagePaths: const [], this.inferFromOverrides: true, + this.inferStaticsFromIdentifiers: false, this.inferInNonStableOrder: false, this.onlyInferConstsAndFinalFields: false, this.nonnullableTypes: TypeOptions.NONNULLABLE_TYPES});