Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index a4e3c60ce577433dc4d86e18af80e6ae9988bb8c..6ac84ed451de2d5dd97a1ab51668701a16716b50 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -2,6 +2,8 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
+library js_codegen; |
+ |
import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
@@ -41,6 +43,8 @@ import 'module_builder.dart'; |
import 'nullability_inferrer.dart'; |
import 'side_effect_analysis.dart'; |
+part 'js_typeref_codegen.dart'; |
+ |
// Various dynamic helpers we call. |
// If renaming these, make sure to check other places like the |
// _runtime.js file and comments. |
@@ -53,7 +57,8 @@ const DSETINDEX = 'dsetindex'; |
const DCALL = 'dcall'; |
const DSEND = 'dsend'; |
-class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
+class JSCodegenVisitor extends GeneralizingAstVisitor |
+ with ClosureAnnotator, JsTypeRefCodegen { |
final AbstractCompiler compiler; |
final CodegenOptions options; |
final LibraryElement currentLibrary; |
@@ -348,12 +353,13 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var type = element.type; |
var name = element.name; |
- var fnType = annotateTypeDef( |
+ var fnType = annotate( |
js.statement('const # = dart.typedef(#, () => #);', [ |
name, |
js.string(name, "'"), |
_emitTypeName(type, lowerTypedef: true) |
]), |
+ node, |
node.element); |
return _finishClassDef(type, fnType); |
@@ -423,8 +429,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
} |
- var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), |
- _classHeritage(classElem), _emitClassMethods(node, ctors, fields)); |
+ var classExpr = new JS.ClassExpression( |
+ new JS.Identifier(type.name), |
+ _classHeritage(classElem), |
+ _emitClassMethods(node, ctors, fields), |
+ _emitTypeArgs(classElem).toList(), |
+ _emitFieldDeclarations(classElem, fields, staticFields).toList()); |
String jsPeerName; |
var jsPeer = findAnnotation(classElem, isJsPeerInterface); |
@@ -457,6 +467,39 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
return result; |
} |
+ Iterable<JS.Identifier> _emitTypeArgs(TypeParameterizedElement e) sync* { |
+ if (!options.closure) return; |
+ for (var typeParam in e.typeParameters) { |
+ yield new JS.Identifier(typeParam.name); |
+ } |
+ } |
+ |
+ /// Emit field declarations for TypeScript & Closure's ES6_TYPED |
+ /// (e.g. `class Foo { i: string; }`) |
+ Iterable<JS.VariableDeclarationList> _emitFieldDeclarations( |
+ ClassElement classElem, |
+ List<FieldDeclaration> fields, |
+ List<FieldDeclaration> staticFields) sync* { |
+ if (!options.closure) return; |
+ |
+ makeInitialization(VariableDeclaration decl) => |
+ new JS.VariableInitialization( |
+ new JS.Identifier( |
+ // TODO(ochafik): use a refactored _emitMemberName instead. |
+ decl.name.name, |
+ type: emitTypeRef(decl.element.type)), |
+ null); |
+ |
+ for (var field in fields) { |
+ yield new JS.VariableDeclarationList( |
+ null, field.fields.variables.map(makeInitialization).toList()); |
+ } |
+ for (var field in staticFields) { |
+ yield new JS.VariableDeclarationList( |
+ 'static', field.fields.variables.map(makeInitialization).toList()); |
+ } |
+ } |
+ |
@override |
JS.Statement visitEnumDeclaration(EnumDeclaration node) { |
var element = node.element; |
@@ -689,8 +732,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var superVar = new JS.TemporaryId(cls.name.name + r'$super'); |
return _statement([ |
js.statement('const # = #;', [superVar, cls.heritage]), |
- new JS.ClassDeclaration( |
- new JS.ClassExpression(cls.name, superVar, cls.methods)) |
+ new JS.ClassDeclaration(new JS.ClassExpression( |
+ cls.name, superVar, cls.methods, cls.typeArgs, cls.fields)) |
]); |
} |
return new JS.ClassDeclaration(cls); |
@@ -935,8 +978,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
]; |
} |
var name = _constructorName(node.element.unnamedConstructor); |
- return annotateDefaultConstructor( |
+ return annotate( |
new JS.Method(name, js.call('function() { #; }', body) as JS.Fun), |
+ node, |
node.element); |
} |
@@ -945,6 +989,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (_externalOrNative(node)) return null; |
var name = _constructorName(node.element); |
+ var returnType = emitTypeRef(node.element.enclosingElement.type); |
// Wacky factory redirecting constructors: factory Foo.q(x, y) = Bar.baz; |
var redirect = node.redirectedConstructor; |
@@ -956,11 +1001,13 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var params = |
_emitFormalParameterList(node.parameters, allowDestructuring: false); |
- var fun = js.call('function(#) { return $newKeyword #(#); }', |
- [params, _visit(redirect), params]) as JS.Fun; |
+ var fun = new JS.Fun( |
+ params, |
+ js.statement( |
+ '{ return $newKeyword #(#); }', [_visit(redirect), params]), |
+ returnType: returnType); |
return annotate( |
- new JS.Method(name, fun, isStatic: true)..sourceInformation = node, |
- node.element); |
+ new JS.Method(name, fun, isStatic: true), node, node.element); |
} |
// Factory constructors are essentially static methods. |
@@ -970,10 +1017,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (init != null) body.add(init); |
body.add(_visit(node.body)); |
var fun = new JS.Fun( |
- _visit(node.parameters) as List<JS.Parameter>, new JS.Block(body)); |
+ _visit(node.parameters) as List<JS.Parameter>, new JS.Block(body), |
+ returnType: returnType); |
return annotate( |
- new JS.Method(name, fun, isStatic: true)..sourceInformation = node, |
- node.element); |
+ new JS.Method(name, fun, isStatic: true), node, node.element); |
} |
// Code generation for Object's constructor. |
@@ -1009,9 +1056,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// this allows use of `super` for instance methods/properties. |
// It also avoids V8 restrictions on `super` in default constructors. |
return annotate( |
- new JS.Method(name, |
- new JS.Fun(_visit(node.parameters) as List<JS.Parameter>, body)) |
- ..sourceInformation = node, |
+ new JS.Method( |
+ name, |
+ new JS.Fun(_visit(node.parameters) as List<JS.Parameter>, body, |
+ returnType: returnType)), |
+ node, |
node.element); |
} |
@@ -1108,7 +1157,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var name = _constructorName(superCtor); |
var args = node != null ? _visit(node.argumentList) : []; |
- return js.statement('super.#(#);', [name, args])..sourceInformation = node; |
+ return annotate(js.statement('super.#(#);', [name, args]), node); |
} |
bool _shouldCallUnnamedSuperCtor(ClassElement e) { |
@@ -1160,7 +1209,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
for (var p in ctor.parameters.parameters) { |
var element = p.element; |
if (element is FieldFormalParameterElement) { |
- fields[element.field] = _visit(p); |
+ fields[element.field] = _emitFormalParameter(p, allowType: false); |
} |
} |
@@ -1216,12 +1265,13 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var parameters = _parametersOf(node); |
if (parameters == null) return null; |
+ var destructure = _canDestructureParams(parameters); |
var body = <JS.Statement>[]; |
for (var param in parameters.parameters) { |
- var jsParam = _visit(param.identifier); |
+ var jsParam = _emitSimpleIdentifier(param.identifier, allowType: false); |
if (param.kind == ParameterKind.NAMED) { |
- if (!_isDestructurableNamedParam(param)) { |
+ if (!destructure) { |
// Parameters will be passed using their real names, not the (possibly |
// renamed) local variable. |
var paramName = js.string(param.identifier.name, "'"); |
@@ -1276,7 +1326,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var params = _visit(node.parameters) as List<JS.Parameter>; |
if (params == null) params = <JS.Parameter>[]; |
- JS.Fun fn = _emitFunctionBody(params, node.body); |
+ var typeArgs = _emitTypeArgs(node.element).toList(); |
+ var returnType = emitTypeRef(node.element.returnType); |
+ JS.Fun fn = _emitFunctionBody(params, node.body, typeArgs, returnType); |
if (node.operatorKeyword != null && |
node.name.name == '[]=' && |
params.isNotEmpty) { |
@@ -1292,8 +1344,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
body = new JS.Call(new JS.ArrowFun([], fn.body), []).toStatement(); |
} |
// Rewrite the function to include the return. |
- fn = new JS.Fun(fn.params, new JS.Block([body, returnValue])) |
- ..sourceInformation = fn.sourceInformation; |
+ fn = new JS.Fun(fn.params, new JS.Block([body, returnValue]), |
+ typeArgs: fn.typeArgs, |
+ returnType: fn.returnType)..sourceInformation = fn.sourceInformation; |
} |
return annotate( |
@@ -1301,6 +1354,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
isGetter: node.isGetter, |
isSetter: node.isSetter, |
isStatic: node.isStatic), |
+ node, |
node.element); |
} |
@@ -1308,7 +1362,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
/// the SDK), or `null` if there's none. This is used to control the name |
/// under which functions are compiled and exported. |
String _getJSExportName(Element e) { |
- if (!currentLibrary.source.isInSystemLibrary) { |
+ if (!e.source.isInSystemLibrary) { |
return null; |
} |
var jsName = findAnnotation(e, isJSExportNameAnnotation); |
@@ -1340,7 +1394,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
var id = new JS.Identifier(name); |
- body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); |
+ body.add(annotate(new JS.FunctionDeclaration(id, fn), node, node.element)); |
if (!_isDartRuntime) { |
body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) |
.toStatement()); |
@@ -1381,7 +1435,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (call.target is JS.ArrowFun && call.arguments.isEmpty) { |
JS.ArrowFun innerFun = call.target; |
if (innerFun.params.isEmpty) { |
- return new JS.Fun(fn.params, innerFun.body); |
+ return new JS.Fun(fn.params, innerFun.body, |
+ typeArgs: fn.typeArgs, returnType: fn.returnType); |
} |
} |
} |
@@ -1394,6 +1449,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
return annotate( |
new JS.Method(_propertyName(name), _visit(node.functionExpression), |
isGetter: node.isGetter, isSetter: node.isSetter), |
+ node, |
node.element); |
} |
@@ -1446,8 +1502,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var parent = node.parent; |
var inStmt = parent.parent is FunctionDeclarationStatement; |
+ var typeArgs = _emitTypeArgs(node.element).toList(); |
+ var returnType = emitTypeRef(node.element.returnType); |
if (parent is FunctionDeclaration) { |
- return _emitFunctionBody(params, node.body); |
+ return _emitFunctionBody(params, node.body, typeArgs, returnType); |
} else { |
// Chrome Canary does not accept default values with destructuring in |
// arrow functions yet (e.g. `({a} = {}) => 1`) but happily accepts them |
@@ -1456,18 +1514,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// TODO(ochafik): Simplify this code when Chrome Canary catches up. |
var canUseArrowFun = !node.parameters.parameters.any(_isNamedParam); |
- String code = canUseArrowFun ? '(#) => #' : 'function(#) { return # }'; |
JS.Node jsBody; |
var body = node.body; |
if (body.isGenerator || body.isAsynchronous) { |
- jsBody = _emitGeneratorFunctionBody(params, body); |
+ jsBody = _emitGeneratorFunctionBody(params, body, returnType); |
} else if (body is ExpressionFunctionBody) { |
jsBody = _visit(body.expression); |
} else { |
- code = canUseArrowFun ? '(#) => { #; }' : 'function(#) { #; }'; |
jsBody = _visit(body); |
} |
- var clos = js.call(code, [params, jsBody]); |
+ if (jsBody is JS.Expression && !canUseArrowFun) { |
+ jsBody = js.statement("{ return #; }", [jsBody]); |
+ } |
+ var clos = canUseArrowFun |
+ ? new JS.ArrowFun(params, jsBody, |
+ typeArgs: typeArgs, returnType: returnType) |
+ : new JS.Fun(params, jsBody, |
+ typeArgs: typeArgs, returnType: returnType); |
if (!inStmt) { |
var type = getStaticType(node); |
return _emitFunctionTagged(clos, type, |
@@ -1477,20 +1540,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
} |
- JS.Fun _emitFunctionBody(List<JS.Parameter> params, FunctionBody body) { |
+ JS.Fun _emitFunctionBody(List<JS.Parameter> params, FunctionBody body, |
+ List<JS.Identifier> typeArgs, JS.TypeRef returnType) { |
// sync*, async, async* |
if (body.isAsynchronous || body.isGenerator) { |
return new JS.Fun( |
params, |
- js.statement( |
- '{ return #; }', [_emitGeneratorFunctionBody(params, body)])); |
+ js.statement('{ return #; }', |
+ [_emitGeneratorFunctionBody(params, body, returnType)]), |
+ returnType: returnType); |
} |
// normal function (sync) |
- return new JS.Fun(params, _visit(body)); |
+ return new JS.Fun(params, _visit(body), |
+ typeArgs: typeArgs, returnType: returnType); |
} |
JS.Expression _emitGeneratorFunctionBody( |
- List<JS.Parameter> params, FunctionBody body) { |
+ List<JS.Parameter> params, FunctionBody body, JS.TypeRef returnType) { |
var kind = body.isSynchronous ? 'sync' : 'async'; |
if (body.isGenerator) kind += 'Star'; |
@@ -1534,7 +1600,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
_asyncStarController = null; |
jsParams = params; |
} |
- JS.Expression gen = new JS.Fun(jsParams, _visit(body), isGenerator: true); |
+ JS.Expression gen = new JS.Fun(jsParams, _visit(body), |
+ isGenerator: true, returnType: returnType); |
if (JS.This.foundIn(gen)) { |
gen = js.call('#.bind(this)', gen); |
} |
@@ -1564,7 +1631,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} else { |
declareFn = new JS.FunctionDeclaration(name, fn); |
} |
- declareFn = annotate(declareFn, node.functionDeclaration.element); |
+ declareFn = annotate(declareFn, node, node.functionDeclaration.element); |
return new JS.Block([ |
declareFn, |
@@ -1572,10 +1639,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
]); |
} |
+ @override |
+ JS.Expression visitSimpleIdentifier(SimpleIdentifier node) => |
+ _emitSimpleIdentifier(node); |
+ |
/// Writes a simple identifier. This can handle implicit `this` as well as |
/// going through the qualified library name if necessary. |
- @override |
- JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { |
+ JS.Expression _emitSimpleIdentifier(SimpleIdentifier node, |
+ {bool allowType: false}) { |
var accessor = node.staticElement; |
if (accessor == null) { |
return js.commentExpression( |
@@ -1644,7 +1715,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
} |
- return new JS.Identifier(name); |
+ return annotate( |
+ new JS.Identifier(name, |
+ type: allowType ? emitTypeRef(node.bestType) : null), |
+ node); |
} |
JS.TemporaryId _getTemp(Element key, String name) => |
@@ -2044,12 +2118,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
bool _isNamedParam(FormalParameter param) => |
param.kind == ParameterKind.NAMED; |
- /// We cannot destructure named params that clash with JS reserved names: |
- /// see discussion in https://github.com/dart-lang/dev_compiler/issues/392. |
- bool _isDestructurableNamedParam(FormalParameter param) => |
- _isNamedParam(param) && |
- !invalidVariableName(param.identifier.name) && |
- options.destructureNamedParams; |
+ bool _canDestructureParams(FormalParameterList params) => |
+ canDestructureNamedParams( |
+ params.parameters.where(_isNamedParam).map((p) => p.identifier.name), |
+ options); |
@override |
List<JS.Parameter> visitFormalParameterList(FormalParameterList node) => |
@@ -2060,8 +2132,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var result = <JS.Parameter>[]; |
var namedVars = <JS.DestructuredVariable>[]; |
- var destructure = allowDestructuring && |
- node.parameters.where(_isNamedParam).every(_isDestructurableNamedParam); |
+ var destructure = allowDestructuring && _canDestructureParams(node); |
var hasNamedArgsConflictingWithObjectProperties = false; |
var needsOpts = false; |
@@ -2072,7 +2143,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
hasNamedArgsConflictingWithObjectProperties = true; |
} |
namedVars.add(new JS.DestructuredVariable( |
- name: _visit(param.identifier), |
+ name: _emitSimpleIdentifier(param.identifier), |
defaultValue: _defaultParamValue(param))); |
} else { |
needsOpts = true; |
@@ -2093,6 +2164,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
: js.call('{}'); |
result.add(new JS.DestructuredVariable( |
structure: new JS.ObjectBindingPattern(namedVars), |
+ type: emitNamedParamsArgType(node.parameterElements), |
defaultValue: defaultOpts)); |
} |
return result; |
@@ -2224,7 +2296,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
return _emitTopLevelField(node); |
} |
- var name = new JS.Identifier(node.name.name); |
+ var name = |
+ new JS.Identifier(node.name.name, type: emitTypeRef(node.element.type)); |
return new JS.VariableInitialization(name, _visitInitializer(node)); |
} |
@@ -2260,12 +2333,13 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var fieldName = field.name.name; |
if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { |
- return annotateVariable( |
+ return annotate( |
js.statement('#.# = #;', [ |
classElem.name, |
_emitMemberName(fieldName, isStatic: true), |
jsInit |
]), |
+ field, |
field.element); |
} |
@@ -2313,15 +2387,22 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (isPublic(fieldName)) _addExport(fieldName, exportName); |
var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; |
- return annotateVariable( |
- js.statement( |
- '$declKeyword # = #;', [new JS.Identifier(fieldName), jsInit]), |
- field.element); |
+ return js.statement('#;', [ |
+ annotate( |
+ new JS.VariableDeclarationList(declKeyword, [ |
+ new JS.VariableInitialization( |
+ new JS.Identifier(fieldName, |
+ type: emitTypeRef(field.element.type)), |
+ jsInit) |
+ ]), |
+ field, |
+ field.element) |
+ ]); |
} |
if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { |
- return annotateVariable( |
- js.statement('# = #;', [_visit(field.name), jsInit]), field.element); |
+ return annotate(js.statement('# = #;', [_visit(field.name), jsInit]), |
+ field, field.element); |
} |
return _emitLazyFields(currentLibrary, [field]); |
@@ -2347,6 +2428,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
js.call('function() { return #; }', _visit(node.initializer)) |
as JS.Fun, |
isGetter: true), |
+ node, |
_findAccessor(element, getter: true))); |
// TODO(jmesserly): currently uses a dummy setter to indicate writable. |
@@ -2354,6 +2436,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
methods.add(annotate( |
new JS.Method(access, js.call('function(_) {}') as JS.Fun, |
isSetter: true), |
+ node, |
_findAccessor(element, getter: false))); |
} |
} |
@@ -2742,8 +2825,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
_visit(node.expression); |
@override |
- visitFormalParameter(FormalParameter node) { |
- var id = visitSimpleIdentifier(node.identifier); |
+ visitFormalParameter(FormalParameter node) => _emitFormalParameter(node); |
+ |
+ _emitFormalParameter(FormalParameter node, {bool allowType: true}) { |
+ var id = _emitSimpleIdentifier(node.identifier, allowType: allowType); |
var isRestArg = findAnnotation(node.element, isJsRestAnnotation) != null; |
return isRestArg ? new JS.RestParameter(id) : id; |
@@ -3303,7 +3388,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
_visit(AstNode node) { |
if (node == null) return null; |
var result = node.accept(this); |
- if (result is JS.Node) result.sourceInformation = node; |
+ if (result is JS.Node) result = annotate(result, node); |
return result; |
} |
@@ -3446,34 +3531,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
DartType getStaticType(Expression e) => |
e.staticType ?? DynamicTypeImpl.instance; |
- @override |
- String getQualifiedName(TypeDefiningElement type) { |
- JS.TemporaryId id = _imports[type.library]; |
- return id == null ? type.name : '${id.name}.${type.name}'; |
+ JS.Node annotate(JS.Node node, AstNode original, [Element element]) { |
+ if (options.closure && element != null) { |
+ node = node.withClosureAnnotation( |
+ closureAnnotationFor(node, original, element, _namedArgTemp.name)); |
+ } |
+ return node..sourceInformation = original; |
} |
- JS.Node annotate(JS.Node method, ExecutableElement e) => |
- options.closure && e != null |
- ? method.withClosureAnnotation( |
- closureAnnotationFor(e, _namedArgTemp.name)) |
- : method; |
- |
- JS.Node annotateDefaultConstructor(JS.Node method, ClassElement e) => |
- options.closure && e != null |
- ? method |
- .withClosureAnnotation(closureAnnotationForDefaultConstructor(e)) |
- : method; |
- |
- JS.Node annotateVariable(JS.Node node, VariableElement e) => |
- options.closure && e != null |
- ? node.withClosureAnnotation(closureAnnotationForVariable(e)) |
- : node; |
- |
- JS.Node annotateTypeDef(JS.Node node, FunctionTypeAliasElement e) => |
- options.closure && e != null |
- ? node.withClosureAnnotation(closureAnnotationForTypeDef(e)) |
- : node; |
- |
/// Returns true if this is any kind of object represented by `Number` in JS. |
/// |
/// In practice, this is 4 types: num, int, double, and JSNumber. |