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 4938b1a2d5ba23a4f76f1151eeb82d8cd02c514f..42a72cac83d53d9cf8441007aab7391a2362f62e 100644 |
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart |
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart |
@@ -74,7 +74,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
final _moduleItems = <JS.ModuleItem>[]; |
/// Table of named and possibly hoisted types. |
- final _typeTable = new TypeTable(); |
+ TypeTable _typeTable; |
/// The global extension type table. |
final ExtensionTypeSet _extensionTypes; |
@@ -97,8 +97,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
final _initializingFormalTemps = |
new HashMap<ParameterElement, JS.TemporaryId>(); |
- final _dartxVar = new JS.Identifier('dartx'); |
- final _runtimeLibVar = new JS.Identifier('dart'); |
+ JS.Identifier _extensionSymbolsModule; |
+ JS.Identifier _runtimeModule; |
final namedArgumentTemp = new JS.TemporaryId('opts'); |
final _hasDeferredSupertype = new HashSet<ClassElement>(); |
@@ -231,6 +231,18 @@ class CodeGenerator extends GeneralizingAstVisitor |
// Transform the AST to make coercions explicit. |
compilationUnits = CoercionReifier.reify(compilationUnits); |
+ if (compilationUnits.any((u) => _isDartRuntime(u.element.library))) { |
+ // Don't allow these to be renamed when we're building the SDK. |
+ // There is JS code in dart:* that depends on their names. |
+ _runtimeModule = new JS.Identifier('dart'); |
+ _extensionSymbolsModule = new JS.Identifier('dartx'); |
+ } else { |
+ // Otherwise allow these to be renamed so users can write them. |
+ _runtimeModule = new JS.TemporaryId('dart'); |
+ _extensionSymbolsModule = new JS.TemporaryId('dartx'); |
+ } |
+ _typeTable = new TypeTable(_runtimeModule); |
+ |
// Initialize our library variables. |
var items = <JS.ModuleItem>[]; |
for (var unit in compilationUnits) { |
@@ -238,7 +250,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (unit.element != library.definingCompilationUnit) continue; |
var libraryTemp = _isDartRuntime(library) |
- ? _runtimeLibVar |
+ ? _runtimeModule |
: new JS.TemporaryId(jsLibraryName(_libraryRoot, library)); |
_libraries[library] = libraryTemp; |
items.add(new JS.ExportDeclaration( |
@@ -247,8 +259,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
// dart:_runtime has a magic module that holds extension method symbols. |
// TODO(jmesserly): find a cleaner design for this. |
if (_isDartRuntime(library)) { |
- items.add(new JS.ExportDeclaration( |
- js.call('const # = Object.create(null)', [_dartxVar]))); |
+ items.add(new JS.ExportDeclaration(js |
+ .call('const # = Object.create(null)', [_extensionSymbolsModule]))); |
} |
} |
@@ -332,7 +344,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
var jsName = _getJSName(e); |
if (jsName == null) return null; |
var fullName = ['global']..addAll(jsName); |
- JS.Expression access = _runtimeLibVar; |
+ JS.Expression access = _runtimeModule; |
for (var part in fullName) { |
access = new JS.PropertyAccess(access, js.string(part)); |
} |
@@ -391,8 +403,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
var imports = |
libraries.map((l) => new JS.NameSpecifier(_imports[l])).toList(); |
if (module == coreModuleName) { |
- imports.add(new JS.NameSpecifier(_runtimeLibVar)); |
- imports.add(new JS.NameSpecifier(_dartxVar)); |
+ imports.add(new JS.NameSpecifier(_runtimeModule)); |
+ imports.add(new JS.NameSpecifier(_extensionSymbolsModule)); |
} |
items.add(new JS.ImportDeclaration( |
namedImports: imports, from: js.string(module, "'"))); |
@@ -508,8 +520,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
} else { |
// top-level fields, getters, setters need to copy the property |
// descriptor. |
- _moduleItems.add(js.statement('dart.export(#, #, #);', |
- [libraryName, name.receiver, name.selector])); |
+ _moduleItems.add(_callHelperStatement( |
+ 'export(#, #, #);', [libraryName, name.receiver, name.selector])); |
} |
} |
@@ -553,7 +565,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
// Make sure to check when converting to int. |
if (from != types.intType && to == types.intType) { |
// TODO(jmesserly): fuse this with notNull check. |
- return js.call('dart.asInt(#)', jsFrom); |
+ return _callHelper('asInt(#)', jsFrom); |
} |
// A no-op in JavaScript. |
@@ -607,7 +619,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
FunctionTypeAliasElement element = node.element; |
JS.Expression body = annotate( |
- js.call('dart.typedef(#, () => #)', [ |
+ _callHelper('typedef(#, () => #)', [ |
js.string(element.name, "'"), |
_emitType(element.type, nameType: false, lowerTypedef: true) |
]), |
@@ -629,7 +641,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
// TODO(jmesserly): if the type fails to resolve, should we generate code |
// that throws instead? |
assert(options.unsafeForceCompile || options.replCompile); |
- return js.call('dart.dynamic'); |
+ return _callHelper('dynamic'); |
} |
return _emitType(node.type); |
} |
@@ -794,7 +806,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
classExpr.name, _emitCallableClassConstructor(unnamedCtor)); |
// Name the constructor function the same as the class. |
- return js.call('dart.callableClass(#, #)', [ctor, classExpr]); |
+ return _callHelper('callableClass(#, #)', [ctor, classExpr]); |
} |
/// Emits a constructor that ensures instances of this class are callable as |
@@ -825,21 +837,21 @@ class CodeGenerator extends GeneralizingAstVisitor |
body.add(js.statement( |
'#.is = function is_Object(o) {' |
' if (o instanceof this) return true;' |
- ' return dart.is(o, this);' |
+ ' return #.is(o, this);' |
'}', |
- className)); |
+ [className, _runtimeModule])); |
body.add(js.statement( |
'#.as = function as_Object(o) {' |
' if (o == null || o instanceof this) return o;' |
- ' return dart.as(o, this);' |
+ ' return #.as(o, this);' |
'}', |
- className)); |
+ [className, _runtimeModule])); |
body.add(js.statement( |
'#._check = function check_Object(o) {' |
' if (o == null || o instanceof this) return o;' |
- ' return dart.check(o, this);' |
+ ' return #.check(o, this);' |
'}', |
- className)); |
+ [className, _runtimeModule])); |
return; |
} |
if (classElem == stringClass) { |
@@ -849,15 +861,15 @@ class CodeGenerator extends GeneralizingAstVisitor |
body.add(js.statement( |
'#.as = function as_String(o) {' |
' if (typeof o == "string" || o == null) return o;' |
- ' return dart.as(o, #);' |
+ ' return #.as(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
body.add(js.statement( |
'#._check = function check_String(o) {' |
' if (typeof o == "string" || o == null) return o;' |
- ' return dart.check(o, #);' |
+ ' return #.check(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
return; |
} |
if (classElem == intClass) { |
@@ -870,16 +882,16 @@ class CodeGenerator extends GeneralizingAstVisitor |
'#.as = function as_int(o) {' |
' if ((typeof o == "number" && Math.floor(o) == o) || o == null)' |
' return o;' |
- ' return dart.as(o, #);' |
+ ' return #.as(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
body.add(js.statement( |
'#._check = function check_int(o) {' |
' if ((typeof o == "number" && Math.floor(o) == o) || o == null)' |
' return o;' |
- ' return dart.check(o, #);' |
+ ' return #.check(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
return; |
} |
if (classElem == nullClass) { |
@@ -888,15 +900,15 @@ class CodeGenerator extends GeneralizingAstVisitor |
body.add(js.statement( |
'#.as = function as_Null(o) {' |
' if (o == null) return o;' |
- ' return dart.as(o, #);' |
+ ' return #.as(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
body.add(js.statement( |
'#._check = function check_Null(o) {' |
' if (o == null) return o;' |
- ' return dart.check(o, #);' |
+ ' return #.check(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
return; |
} |
if (classElem == numClass) { |
@@ -906,15 +918,15 @@ class CodeGenerator extends GeneralizingAstVisitor |
body.add(js.statement( |
'#.as = function as_num(o) {' |
' if (typeof o == "number" || o == null) return o;' |
- ' return dart.as(o, #);' |
+ ' return #.as(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
body.add(js.statement( |
'#._check = function check_num(o) {' |
' if (typeof o == "number" || o == null) return o;' |
- ' return dart.check(o, #);' |
+ ' return #.check(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
return; |
} |
if (classElem == boolClass) { |
@@ -924,15 +936,15 @@ class CodeGenerator extends GeneralizingAstVisitor |
body.add(js.statement( |
'#.as = function as_bool(o) {' |
' if (o === true || o === false || o == null) return o;' |
- ' return dart.as(o, #);' |
+ ' return #.as(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
body.add(js.statement( |
'#._check = function check_bool(o) {' |
' if (o === true || o === false || o == null) return o;' |
- ' return dart.check(o, #);' |
+ ' return #.check(o, #);' |
'}', |
- [className, className])); |
+ [className, _runtimeModule, className])); |
return; |
} |
// TODO(sra): Add special cases for hot tests like `x is html.Element`. |
@@ -945,7 +957,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
// Place non-instanceof version of checks on Interceptor. All |
// interceptor classes will inherit the methods via ES6 class static |
// inheritance. |
- body.add(js.statement('dart.addTypeTests(#);', className)); |
+ body.add(_callHelperStatement('addTypeTests(#);', className)); |
// TODO(sra): We could place on the extension type a pointer to the |
// peer constructor and use that for the `instanceof` check, e.g. |
@@ -983,9 +995,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (thisIsSimple == superIsSimple) return; |
if (thisIsSimple) { |
- body.add(js.statement('dart.addSimpleTypeTests(#);', className)); |
+ body.add(_callHelperStatement('addSimpleTypeTests(#);', className)); |
} else { |
- body.add(js.statement('dart.addTypeTests(#);', className)); |
+ body.add(_callHelperStatement('addTypeTests(#);', className)); |
} |
} |
@@ -1103,8 +1115,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
// Create static fields for each enum value |
for (var i = 0; i < fields.length; ++i) { |
- result.add(js.statement('#.# = dart.const(new #(#));', |
- [id, fields[i].name, id, js.number(i)])); |
+ result.add(js.statement('#.# = #.const(new #(#));', |
+ [id, fields[i].name, _runtimeModule, id, js.number(i)])); |
} |
// Create static values list |
@@ -1114,8 +1126,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
// dart.constList helper internally depends on _interceptors.JSArray. |
_declareBeforeUse(_jsArray); |
- result.add(js.statement( |
- '#.values = dart.constList(#, #);', [id, values, _emitType(type)])); |
+ result.add(js.statement('#.values = #.constList(#, #);', |
+ [id, _runtimeModule, values, _emitType(type)])); |
return _statement(result); |
} |
@@ -1124,7 +1136,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
JS.Statement _defineClassTypeArguments(TypeDefiningElement element, |
List<TypeParameterElement> formals, JS.Statement body) { |
assert(formals.isNotEmpty); |
- var genericCall = js.call('dart.generic((#) => { #; #; return #; })', [ |
+ var genericCall = _callHelper('generic((#) => { #; #; return #; })', [ |
_emitTypeFormals(formals), |
_typeTable.discharge(formals), |
body, |
@@ -1132,7 +1144,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
]); |
if (element.library.isDartAsync && |
(element.name == "Future" || element.name == "_Future")) { |
- genericCall = js.call('dart.flattenFutures(#)', [genericCall]); |
+ genericCall = _callHelper('flattenFutures(#)', [genericCall]); |
} |
var genericDef = js.statement( |
'# = #;', [_emitTopLevelName(element, suffix: r'$'), genericCall]); |
@@ -1190,7 +1202,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
var mixins = |
type.mixins.map((t) => _emitType(t, nameType: false)).toList(); |
mixins.insert(0, heritage); |
- heritage = js.call('dart.mixin(#)', [mixins]); |
+ heritage = _callHelper('mixin(#)', [mixins]); |
} |
_loader.finishTopLevel(element); |
@@ -1410,8 +1422,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
JS.Expression positionalArgs; |
if (method.type.namedParameterTypes.isNotEmpty) { |
- addProperty( |
- 'namedArguments', js.call('dart.extractNamedArgs(#)', [args])); |
+ addProperty('namedArguments', _callHelper('extractNamedArgs(#)', [args])); |
} |
if (method is MethodElement) { |
@@ -1433,8 +1444,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
} |
- var fnBody = |
- js.call('this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [ |
+ var fnBody = js.call('this.noSuchMethod(new #.InvocationImpl(#, #, #))', [ |
+ _runtimeModule, |
_declareMemberName(method), |
positionalArgs, |
new JS.ObjectInitializer(invocationProps) |
@@ -1552,8 +1563,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
// an ES6 iterator. |
return new JS.Method( |
js.call('Symbol.iterator'), |
- js.call('function() { return new dart.JsIterator(this.#); }', |
- [_emitMemberName('iterator', type: t)]) as JS.Fun); |
+ js.call('function() { return new #.JsIterator(this.#); }', |
+ [_runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun); |
} |
JS.Expression _instantiateAnnotation(Annotation node) { |
@@ -1590,8 +1601,11 @@ class CodeGenerator extends GeneralizingAstVisitor |
void _registerExtensionType( |
ClassElement classElem, String jsPeerName, List<JS.Statement> body) { |
if (jsPeerName != null) { |
- body.add(js.statement('dart.registerExtension(dart.global.#, #);', |
- [_propertyName(jsPeerName), _emitTopLevelName(classElem)])); |
+ body.add(_callHelperStatement('registerExtension(#.global.#, #);', [ |
+ _runtimeModule, |
+ _propertyName(jsPeerName), |
+ _emitTopLevelName(classElem) |
+ ])); |
} |
} |
@@ -1600,23 +1614,23 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (jsPeerNames.isNotEmpty && classElem.typeParameters.isNotEmpty) { |
for (var peer in jsPeerNames) { |
// TODO(jmesserly): we should just extend Array in the first place |
- var newBaseClass = js.call('dart.global.#', [peer]); |
- body.add(js.statement( |
- 'dart.setExtensionBaseClass(#, #);', [className, newBaseClass])); |
+ var newBaseClass = _callHelper('global.#', [peer]); |
+ body.add(_callHelperStatement( |
+ 'setExtensionBaseClass(#, #);', [className, newBaseClass])); |
} |
} else if (_hasDeferredSupertype.contains(classElem)) { |
var newBaseClass = _emitType(classElem.type.superclass, |
nameType: false, subClass: classElem, className: className); |
- body.add( |
- js.statement('dart.setBaseClass(#, #);', [className, newBaseClass])); |
+ body.add(_callHelperStatement( |
+ 'setBaseClass(#, #);', [className, newBaseClass])); |
} |
} |
void _defineNamedConstructors(List<ConstructorDeclaration> ctors, |
List<JS.Statement> body, JS.Expression className, bool isCallable) { |
var code = isCallable |
- ? 'dart.defineNamedConstructorCallable(#, #, #);' |
- : 'dart.defineNamedConstructor(#, #)'; |
+ ? 'defineNamedConstructorCallable(#, #, #);' |
+ : 'defineNamedConstructor(#, #)'; |
for (ConstructorDeclaration member in ctors) { |
if (member.name != null && member.factoryKeyword == null) { |
@@ -1625,7 +1639,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
args.add(_emitCallableClassConstructor(member.element)); |
} |
- body.add(js.statement(code, args)); |
+ body.add(_callHelperStatement(code, args)); |
} |
} |
} |
@@ -1658,8 +1672,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
List<JS.Statement> body) { |
// Metadata |
if (options.emitMetadata && metadata.isNotEmpty) { |
- body.add(js.statement('#[dart.metadata] = () => #;', [ |
+ body.add(js.statement('#[#.metadata] = () => #;', [ |
className, |
+ _runtimeModule, |
new JS.ArrayInitializer( |
new List<JS.Expression>.from(metadata.map(_instantiateAnnotation))) |
])); |
@@ -1677,7 +1692,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
for (var e in extensions) { |
methodNames.add(_declareMemberName(e, useExtension: false)); |
} |
- body.add(js.statement('dart.defineExtensionMembers(#, #);', [ |
+ body.add(_callHelperStatement('defineExtensionMembers(#, #);', [ |
className, |
new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) |
])); |
@@ -1694,8 +1709,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
JS.Expression className, |
List<JS.Statement> body) { |
if (classElem.interfaces.isNotEmpty) { |
- body.add(js.statement('#[dart.implements] = () => #;', [ |
+ body.add(js.statement('#[#.implements] = () => #;', [ |
className, |
+ _runtimeModule, |
new JS.ArrayInitializer( |
new List<JS.Expression>.from(classElem.interfaces.map(_emitType))) |
])); |
@@ -1818,12 +1834,12 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
if (!sigFields.isEmpty || extensions.isNotEmpty) { |
var sig = new JS.ObjectInitializer(sigFields); |
- body.add(js.statement('dart.setSignature(#, #);', [className, sig])); |
+ body.add(_callHelperStatement('setSignature(#, #);', [className, sig])); |
} |
// Add static property dart._runtimeType to Object. |
// All other Dart classes will (statically) inherit this property. |
if (classElem == objectClass) { |
- body.add(js.statement('dart.tagComputed(#, () => #.#);', |
+ body.add(_callHelperStatement('tagComputed(#, () => #.#);', |
[className, emitLibraryName(dartCoreLibrary), 'Type'])); |
} |
} |
@@ -1852,7 +1868,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
} |
if (dartxNames.isNotEmpty) { |
- body.add(js.statement('dart.defineExtensionNames(#)', |
+ body.add(_callHelperStatement('defineExtensionNames(#)', |
[new JS.ArrayInitializer(dartxNames, multiline: true)])); |
} |
} |
@@ -2332,7 +2348,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
props.add(_loader.emitDeclaration( |
setter, (node) => _emitTopLevelProperty(node))); |
} |
- return js.statement('dart.copyProperties(#, { # });', |
+ return _callHelperStatement('copyProperties(#, { # });', |
[emitLibraryName(currentLibrary), props]); |
} |
if (node.isSetter) { |
@@ -2343,7 +2359,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
props.add(_loader.emitDeclaration( |
getter, (node) => _emitTopLevelProperty(node))); |
} |
- return js.statement('dart.copyProperties(#, { # });', |
+ return _callHelperStatement('copyProperties(#, { # });', |
[emitLibraryName(currentLibrary), props]); |
} |
@@ -2442,9 +2458,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
var lazy = topLevel && !_typeIsLoaded(type); |
var typeRep = _emitFunctionType(type, definite: true); |
if (lazy) { |
- return js.call('dart.lazyFn(#, () => #)', [fn, typeRep]); |
+ return _callHelper('lazyFn(#, () => #)', [fn, typeRep]); |
} else { |
- return js.call('dart.fn(#, #)', [fn, typeRep]); |
+ return _callHelper('fn(#, #)', [fn, typeRep]); |
} |
} |
@@ -2596,7 +2612,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
var T = _emitType(returnType); |
- return js.call('dart.#(#)', [ |
+ return _callHelper('#(#)', [ |
kind, |
[gen, T]..addAll(visitFormalParameterList(parameters, destructure: false)) |
]); |
@@ -2636,7 +2652,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (typeArgs == null) { |
return simpleId; |
} |
- return js.call('dart.gbind(#, #)', [simpleId, typeArgs]); |
+ return _callHelper('gbind(#, #)', [simpleId, typeArgs]); |
} |
/// Emits a simple identifier, handling implicit `this` as well as |
@@ -2663,7 +2679,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
// If the type is a type literal expression in Dart code, wrap the raw |
// runtime type in a "Type" instance. |
if (!_isInForeignJS && _isTypeLiteral(node)) { |
- typeName = js.call('dart.wrapType(#)', typeName); |
+ typeName = _callHelper('wrapType(#)', typeName); |
} |
return typeName; |
@@ -2694,8 +2710,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
// For instance members, we add implicit-this. |
// For method tear-offs, we ensure it's a bound method. |
var tearOff = element is MethodElement && !inInvocationContext(node); |
- var code = (tearOff) ? 'dart.bind(this, #)' : 'this.#'; |
- return js.call(code, member); |
+ if (tearOff) return _callHelper('bind(this, #)', member); |
+ return js.call('this.#', member); |
} |
if (element is ParameterElement) { |
@@ -2812,7 +2828,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
nameType: nameType, |
hoistType: hoistType); |
var helper = (definite) ? 'definiteFunctionType' : 'functionType'; |
- var fullType = js.call('dart.${helper}(#)', [parts]); |
+ var fullType = _callHelper('${helper}(#)', [parts]); |
if (!nameType) return fullType; |
return _typeTable.nameType(type, fullType, |
hoistType: hoistType, definite: definite); |
@@ -2908,11 +2924,11 @@ class CodeGenerator extends GeneralizingAstVisitor |
JS.Expression className}) { |
// The void and dynamic types are not defined in core. |
if (type.isVoid) { |
- return js.call('dart.void'); |
+ return _callHelper('void'); |
} else if (type.isDynamic) { |
- return js.call('dart.dynamic'); |
+ return _callHelper('dynamic'); |
} else if (type.isBottom) { |
- return js.call('dart.bottom'); |
+ return _callHelper('bottom'); |
} |
_declareBeforeUse(type.element); |
@@ -3059,11 +3075,18 @@ class CodeGenerator extends GeneralizingAstVisitor |
var l = _visit(_bindValue(vars, 'l', target)); |
var name = _emitMemberName(id.name); |
return new JS.MetaLet(vars, [ |
- js.call('(#[(#[dart._extensionType]) ? dartx[#] : #] = #)', |
- [l, l, name, name, _visit(rhs)]) |
+ js.call('(#[(#[#._extensionType]) ? #[#] : #] = #)', [ |
+ l, |
+ l, |
+ _runtimeModule, |
+ name, |
+ _extensionSymbolsModule, |
+ name, |
+ _visit(rhs) |
+ ]) |
]); |
} |
- return js.call('dart.#(#, #, #)', [ |
+ return _callHelper('#(#, #, #)', [ |
_emitDynamicOperationName('dput'), |
_visit(target), |
_emitMemberName(id.name), |
@@ -3096,7 +3119,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
// TODO(sra): We should get here only for compiler bugs or weirdness due to |
// --unsafe-force-compile. Once those paths have been addressed, throw at |
// compile time. |
- return js.call('dart.throwUnimplementedError((#, #, #))', |
+ return _callHelper('throwUnimplementedError((#, #, #))', |
[js.string('$lhs ='), _visit(rhs), js.string(problem)]); |
} |
@@ -3346,14 +3369,21 @@ class CodeGenerator extends GeneralizingAstVisitor |
var vars = <JS.MetaLetVariable, JS.Expression>{}; |
var l = _visit(_bindValue(vars, 'l', target)); |
jsTarget = new JS.MetaLet(vars, [ |
- js.call('(#[(#[dart._extensionType]) ? dartx[#] : #]).bind(#)', |
- [l, l, memberName, memberName, l]) |
+ js.call('(#[(#[#._extensionType]) ? #[#] : #]).bind(#)', [ |
+ l, |
+ l, |
+ _runtimeModule, |
+ memberName, |
+ _extensionSymbolsModule, |
+ memberName, |
+ l |
+ ]) |
]); |
if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); |
return new JS.Call(jsTarget, args); |
} |
if (typeArgs != null) { |
- return js.call('dart.#(#, #, #, #)', [ |
+ return _callHelper('#(#, #, #, #)', [ |
_emitDynamicOperationName('dgsend'), |
jsTarget, |
new JS.ArrayInitializer(typeArgs), |
@@ -3361,13 +3391,13 @@ class CodeGenerator extends GeneralizingAstVisitor |
args |
]); |
} else { |
- return js.call('dart.#(#, #, #)', |
+ return _callHelper('#(#, #, #)', |
[_emitDynamicOperationName('dsend'), jsTarget, memberName, args]); |
} |
} |
if (_isObjectMemberCall(target, name)) { |
assert(typeArgs == null); // Object methods don't take type args. |
- return js.call('dart.#(#, #)', [name, jsTarget, args]); |
+ return _callHelper('#(#, #)', [name, jsTarget, args]); |
} |
jsTarget = new JS.PropertyAccess(jsTarget, memberName); |
@@ -3380,13 +3410,13 @@ class CodeGenerator extends GeneralizingAstVisitor |
InvocationExpression node, JS.Expression fn, List<JS.Expression> args) { |
var typeArgs = _emitInvokeTypeArguments(node); |
if (typeArgs != null) { |
- return js.call('dart.dgcall(#, #, #)', |
- [fn, new JS.ArrayInitializer(typeArgs), args]); |
+ return _callHelper( |
+ 'dgcall(#, #, #)', [fn, new JS.ArrayInitializer(typeArgs), args]); |
} else { |
if (_inWhitelistCode(node, isCall: true)) { |
return new JS.Call(fn, args); |
} |
- return js.call('dart.dcall(#, #)', [fn, args]); |
+ return _callHelper('dcall(#, #)', [fn, args]); |
} |
} |
@@ -3629,7 +3659,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
@override |
JS.Statement visitAssertStatement(AssertStatement node) => |
// TODO(jmesserly): only emit in checked mode. |
- js.statement('dart.assert(#);', _visit(node.condition)); |
+ _callHelperStatement('assert(#);', _visit(node.condition)); |
@override |
JS.Statement visitReturnStatement(ReturnStatement node) { |
@@ -3839,7 +3869,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
objExpr = emitLibraryName(target); |
} |
- return js.statement('dart.defineLazy(#, { # });', [objExpr, methods]); |
+ return _callHelperStatement('defineLazy(#, { # });', [objExpr, methods]); |
} |
PropertyAccessorElement _findAccessor(VariableElement element, |
@@ -3956,7 +3986,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (expr == null) return null; |
var jsExpr = _visit(expr); |
if (!isNullable(expr)) return jsExpr; |
- return js.call('dart.notNull(#)', jsExpr); |
+ return _callHelper('notNull(#)', jsExpr); |
} |
@override |
@@ -3986,7 +4016,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
return _emitSend(left, op.lexeme, [right]); |
} else { |
var bang = op.type == TokenType.BANG_EQ ? '!' : ''; |
- code = '${bang}dart.equals(#, #)'; |
+ code = '${bang}#.equals(#, #)'; |
+ return js.call(code, [_runtimeModule, _visit(left), _visit(right)]); |
} |
return js.call(code, [_visit(left), _visit(right)]); |
} |
@@ -4299,7 +4330,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
JS.Expression _emitConst(JS.Expression expr()) => |
- _cacheConst(() => js.call('dart.const(#)', expr())); |
+ _cacheConst(() => _callHelper('const(#)', expr())); |
/// Returns a new expression, which can be be used safely *once* on the |
/// left hand side, and *once* on the right side of an assignment. |
@@ -4561,8 +4592,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
} |
if (tail.isEmpty) return _visit(node); |
- return js.call( |
- 'dart.nullSafe(#, #)', [_visit(node) as JS.Expression, tail.reversed]); |
+ return _callHelper( |
+ 'nullSafe(#, #)', [_visit(node) as JS.Expression, tail.reversed]); |
} |
static Token _getOperator(Expression node) { |
@@ -4659,11 +4690,11 @@ class CodeGenerator extends GeneralizingAstVisitor |
var vars = <JS.MetaLetVariable, JS.Expression>{}; |
var l = _visit(_bindValue(vars, 'l', target)); |
return new JS.MetaLet(vars, [ |
- js.call('(#[dart._extensionType]) ? #[dartx[#]] : #.#', |
- [l, l, name, l, name]) |
+ js.call('(#[#._extensionType]) ? #[#[#]] : #.#', |
+ [l, _runtimeModule, l, _extensionSymbolsModule, name, l, name]) |
]); |
} |
- return js.call('dart.#(#, #)', |
+ return _callHelper('#(#, #)', |
[_emitDynamicOperationName('dload'), _visit(target), name]); |
} |
@@ -4680,22 +4711,22 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (member != null && member is MethodElement && !isStatic) { |
// Tear-off methods: explicitly bind it. |
if (isSuper) { |
- result = js.call('dart.bind(this, #, #.#)', [name, jsTarget, name]); |
+ result = _callHelper('bind(this, #, #.#)', [name, jsTarget, name]); |
} else if (_isObjectMemberCall(target, memberName)) { |
- result = js.call('dart.bind(#, #, dart.#)', |
- [jsTarget, _propertyName(memberName), memberName]); |
+ result = _callHelper('bind(#, #, #.#)', |
+ [jsTarget, _propertyName(memberName), _runtimeModule, memberName]); |
} else { |
- result = js.call('dart.bind(#, #)', [jsTarget, name]); |
+ result = _callHelper('bind(#, #)', [jsTarget, name]); |
} |
} else if (_isObjectMemberCall(target, memberName)) { |
- result = js.call('dart.#(#)', [memberName, jsTarget]); |
+ result = _callHelper('#(#)', [memberName, jsTarget]); |
} else { |
result = js.call('#.#', [jsTarget, name]); |
} |
if (typeArgs == null) { |
return result; |
} |
- return js.call('dart.gbind(#, #)', [result, typeArgs]); |
+ return _callHelper('gbind(#, #)', [result, typeArgs]); |
} |
/// Emits a generic send, like an operator method. |
@@ -4712,18 +4743,26 @@ class CodeGenerator extends GeneralizingAstVisitor |
var vars = <JS.MetaLetVariable, JS.Expression>{}; |
var l = _visit(_bindValue(vars, 'l', target)); |
return new JS.MetaLet(vars, [ |
- js.call('(#[(#[dart._extensionType]) ? dartx[#] : #]).call(#, #)', |
- [l, l, memberName, memberName, l, _visitList(args)]) |
+ js.call('(#[(#[#._extensionType]) ? #[#] : #]).call(#, #)', [ |
+ l, |
+ l, |
+ _runtimeModule, |
+ memberName, |
+ _extensionSymbolsModule, |
+ memberName, |
+ l, |
+ _visitList(args) |
+ ]) |
]); |
} |
// dynamic dispatch |
var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name]; |
if (dynamicHelper != null) { |
- return js.call('dart.$dynamicHelper(#, #)', |
+ return _callHelper('$dynamicHelper(#, #)', |
[_visit(target) as JS.Expression, _visitList(args)]); |
} else { |
- return js.call('dart.dsend(#, #, #)', |
- [_visit(target), memberName, _visitList(args)]); |
+ return _callHelper( |
+ 'dsend(#, #, #)', [_visit(target), memberName, _visitList(args)]); |
} |
} |
@@ -4767,9 +4806,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
visitThrowExpression(ThrowExpression node) { |
var expr = _visit(node.expression); |
if (node.parent is ExpressionStatement) { |
- return js.statement('dart.throw(#);', expr); |
+ return _callHelperStatement('throw(#);', expr); |
} else { |
- return js.call('dart.throw(#)', expr); |
+ return _callHelper('throw(#)', expr); |
} |
} |
@@ -4972,8 +5011,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
if (node.stackTraceParameter != null) { |
var stackVar = node.stackTraceParameter.name; |
- body.add(js.statement( |
- 'let # = dart.stackTrace(#);', [stackVar, _visit(name)])); |
+ body.add(js.statement('let # = #.stackTrace(#);', |
+ [stackVar, _runtimeModule, _visit(name)])); |
} |
} |
@@ -5055,7 +5094,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
_declareBeforeUse(_jsArray); |
if (isConst) { |
var typeRep = _emitType(elementType); |
- list = js.call('dart.constList(#, #)', [list, typeRep]); |
+ list = _callHelper('constList(#, #)', [list, typeRep]); |
} else { |
// Call `new JSArray<E>.of(list)` |
var jsArrayType = _jsArray.type.instantiate(type.typeArguments); |
@@ -5101,7 +5140,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
if (reifyTypeArgs) { |
types.addAll(typeArgs.map((e) => _emitType(e))); |
} |
- return js.call('dart.map(#, #)', [mapArguments, types]); |
+ return _callHelper('map(#, #)', [mapArguments, types]); |
} |
if (node.constKeyword != null) return _emitConst(emitMap); |
@@ -5119,7 +5158,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
@override |
JS.Expression visitStringInterpolation(StringInterpolation node) { |
return new JS.TaggedTemplate( |
- js.call('dart.str'), new JS.TemplateString(_visitList(node.elements))); |
+ _callHelper('str'), new JS.TemplateString(_visitList(node.elements))); |
} |
@override |
@@ -5141,7 +5180,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
_unimplementedCall('Unimplemented ${node.runtimeType}: $node'); |
JS.Expression _unimplementedCall(String comment) { |
- return js.call('dart.throw(#)', [js.escapedString(comment)]); |
+ return _callHelper('throw(#)', [js.escapedString(comment)]); |
} |
@override |
@@ -5198,10 +5237,10 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
if (node is AsExpression && CoercionReifier.isImplicitCast(node)) { |
assert(node.staticType == types.boolType); |
- return js.call('dart.test(#)', _visit(node.expression)); |
+ return _callHelper('test(#)', _visit(node.expression)); |
} |
JS.Expression result = _visit(node); |
- if (isNullable(node)) result = js.call('dart.test(#)', result); |
+ if (isNullable(node)) result = _callHelper('test(#)', result); |
return result; |
} |
@@ -5302,7 +5341,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
!isObjectMember(name); |
} |
- return useExtension ? js.call('dartx.#', result) : result; |
+ return useExtension |
+ ? js.call('#.#', [_extensionSymbolsModule, result]) |
+ : result; |
} |
JS.TemporaryId _emitPrivateNameSymbol(LibraryElement library, String name) { |
@@ -5405,6 +5446,26 @@ class CodeGenerator extends GeneralizingAstVisitor |
} |
} |
+ JS.Expression _callHelper(String code, [args]) { |
+ if (args is List) { |
+ args.insert(0, _runtimeModule); |
+ } else if (args != null) { |
+ args = [_runtimeModule, args]; |
+ } else { |
+ args = _runtimeModule; |
+ } |
+ return js.call('#.$code', args); |
+ } |
+ |
+ JS.Statement _callHelperStatement(String code, args) { |
+ if (args is List) { |
+ args.insert(0, _runtimeModule); |
+ } else { |
+ args = [_runtimeModule, args]; |
+ } |
+ return js.statement('#.$code', args); |
+ } |
+ |
/// Maps whitelisted files to a list of whitelisted methods |
/// within the file. |
/// |