| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 9650a36306b195dc94a98398d8b63c6e0951ea0b..005808114b65eefe3e35961473b15a75dcb16424 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);
|
| @@ -424,7 +430,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| }
|
|
|
| var classExpr = new JS.ClassExpression(new JS.Identifier(type.name),
|
| - _classHeritage(classElem), _emitClassMethods(node, ctors, fields));
|
| + _classHeritage(classElem), _emitClassMethods(node, ctors, fields),
|
| + typeParams: _emitTypeParams(classElem).toList(),
|
| + fields:
|
| + _emitFieldDeclarations(classElem, fields, staticFields).toList());
|
|
|
| String jsPeerName;
|
| var jsPeer = findAnnotation(classElem, isJsPeerInterface);
|
| @@ -457,6 +466,39 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| return result;
|
| }
|
|
|
| + Iterable<JS.Identifier> _emitTypeParams(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 +731,9 @@ 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,
|
| + typeParams: cls.typeParams, fields: 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);
|
| }
|
|
|
| // For const constructors we need to ensure default values are
|
| @@ -976,10 +1023,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| var init = _emitArgumentInitializers(node, constructor: true);
|
| if (init != null) body.add(init);
|
| body.add(_visit(node.body));
|
| - var fun = new JS.Fun(params, new JS.Block(body));
|
| + var fun = new JS.Fun(params, 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.
|
| @@ -1015,7 +1061,8 @@ 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(params, body))..sourceInformation = node,
|
| + new JS.Method(name, new JS.Fun(params, body, returnType: returnType)),
|
| + node,
|
| node.element);
|
| }
|
|
|
| @@ -1112,7 +1159,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) {
|
| @@ -1164,7 +1211,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);
|
| }
|
| }
|
|
|
| @@ -1222,7 +1269,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
|
|
| 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 (!options.destructureNamedParams) {
|
| @@ -1281,7 +1328,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 typeParams = _emitTypeParams(node.element).toList();
|
| + var returnType = emitTypeRef(node.element.returnType);
|
| + JS.Fun fn = _emitFunctionBody(params, node.body, typeParams, returnType);
|
| if (node.operatorKeyword != null &&
|
| node.name.name == '[]=' &&
|
| params.isNotEmpty) {
|
| @@ -1297,8 +1346,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]),
|
| + typeParams: fn.typeParams,
|
| + returnType: fn.returnType)..sourceInformation = fn.sourceInformation;
|
| }
|
|
|
| return annotate(
|
| @@ -1306,6 +1356,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| isGetter: node.isGetter,
|
| isSetter: node.isSetter,
|
| isStatic: node.isStatic),
|
| + node,
|
| node.element);
|
| }
|
|
|
| @@ -1313,7 +1364,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);
|
| @@ -1345,7 +1396,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());
|
| @@ -1386,7 +1437,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,
|
| + typeParams: fn.typeParams, returnType: fn.returnType);
|
| }
|
| }
|
| }
|
| @@ -1399,6 +1451,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);
|
| }
|
|
|
| @@ -1451,8 +1504,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
|
|
| var parent = node.parent;
|
| var inStmt = parent.parent is FunctionDeclarationStatement;
|
| + var typeParams = _emitTypeParams(node.element).toList();
|
| + var returnType = emitTypeRef(node.element.returnType);
|
| if (parent is FunctionDeclaration) {
|
| - return _emitFunctionBody(params, node.body);
|
| + return _emitFunctionBody(params, node.body, typeParams, returnType);
|
| } else {
|
| // Chrome Canary does not accept default values with destructuring in
|
| // arrow functions yet (e.g. `({a} = {}) => 1`) but happily accepts them
|
| @@ -1461,18 +1516,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,
|
| + typeParams: typeParams, returnType: returnType)
|
| + : new JS.Fun(params, jsBody,
|
| + typeParams: typeParams, returnType: returnType);
|
| if (!inStmt) {
|
| var type = getStaticType(node);
|
| return _emitFunctionTagged(clos, type,
|
| @@ -1482,20 +1542,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> typeParams, 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),
|
| + typeParams: typeParams, 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';
|
|
|
| @@ -1539,7 +1602,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);
|
| }
|
| @@ -1569,7 +1633,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,
|
| @@ -1577,10 +1641,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(
|
| @@ -1649,7 +1717,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) =>
|
| @@ -2105,6 +2176,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;
|
| @@ -2236,7 +2308,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));
|
| }
|
|
|
| @@ -2272,12 +2345,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);
|
| }
|
|
|
| @@ -2325,15 +2399,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]);
|
| @@ -2359,6 +2440,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.
|
| @@ -2366,6 +2448,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)));
|
| }
|
| }
|
| @@ -2754,8 +2837,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;
|
| @@ -3315,7 +3400,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;
|
| }
|
|
|
| @@ -3458,34 +3543,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.
|
|
|