Skip to content

Commit 51c3bcb

Browse files
author
Olivier Chafik
committed
Add a @JSExportName annotation for internal use in the runtime (use it to export dart.assert instead of assert_)
BUG= [email protected] Review URL: https://codereview.chromium.org/1580413002 .
1 parent bccc3c2 commit 51c3bcb

File tree

8 files changed

+70
-18
lines changed

8 files changed

+70
-18
lines changed

pkg/dev_compiler/lib/runtime/dart/_classes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ dart_library.library('dart/_classes', null, /* Imports */[
2020
], function(exports, dart_utils, core, _interceptors, types, rtti) {
2121
'use strict';
2222

23-
const assert = dart_utils.assert_;
23+
const assert = dart_utils.assert;
2424
const copyProperties = dart_utils.copyProperties;
2525
const copyTheseProperties = dart_utils.copyTheseProperties;
2626
const defineMemoizedGetter = dart_utils.defineMemoizedGetter;

pkg/dev_compiler/lib/runtime/dart/_foreign_helper.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ dart_library.library('dart/_foreign_helper', null, /* Imports */[
2020
if (arg11 === void 0) arg11 = null;
2121
}
2222
dart.fn(JS, dart.dynamic, [core.String, core.String], [dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic, dart.dynamic]);
23+
class JSExportName extends core.Object {
24+
JSExportName(name) {
25+
this.name = name;
26+
}
27+
}
28+
dart.setSignature(JSExportName, {
29+
constructors: () => ({JSExportName: [JSExportName, [core.String]]})
30+
});
2331
function JS_CURRENT_ISOLATE_CONTEXT() {
2432
}
2533
dart.fn(JS_CURRENT_ISOLATE_CONTEXT, () => dart.definiteFunctionType(IsolateContext, []));
@@ -111,6 +119,7 @@ dart_library.library('dart/_foreign_helper', null, /* Imports */[
111119
dart.fn(JS_STRING_CONCAT, core.String, [core.String, core.String]);
112120
// Exports:
113121
exports.JS = JS;
122+
exports.JSExportName = JSExportName;
114123
exports.JS_CURRENT_ISOLATE_CONTEXT = JS_CURRENT_ISOLATE_CONTEXT;
115124
exports.IsolateContext = IsolateContext;
116125
exports.JS_CALL_IN_ISOLATE = JS_CALL_IN_ISOLATE;

pkg/dev_compiler/lib/runtime/dart/_types.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dart_library.library('dart/_types', null, /* Imports */[
1616

1717
const getOwnPropertyNames = Object.getOwnPropertyNames;
1818

19-
const assert = dart_utils.assert_;
19+
const assert = dart_utils.assert;
2020

2121
/**
2222
* Types in dart are represented at runtime as follows.

pkg/dev_compiler/lib/runtime/dart/_utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dart_library.library('dart/_utils', null, /* Imports */[
2222
function throwInternalError(message) {
2323
throw Error(message);
2424
}
25-
function assert_(condition) {
25+
function assert(condition) {
2626
if (!condition) throwInternalError("The compiler is broken: failed assert");
2727
}
2828
function getOwnNamesAndSymbols(obj) {
@@ -95,7 +95,7 @@ dart_library.library('dart/_utils', null, /* Imports */[
9595
exports.StrongModeError = StrongModeError;
9696
exports.throwStrongModeError = throwStrongModeError;
9797
exports.throwInternalError = throwInternalError;
98-
exports.assert_ = assert_;
98+
exports.assert = assert;
9999
exports.getOwnNamesAndSymbols = getOwnNamesAndSymbols;
100100
exports.safeGetOwnProperty = safeGetOwnProperty;
101101
exports.defineLazyProperty = defineLazyProperty;

pkg/dev_compiler/lib/src/codegen/js_codegen.dart

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
12941294
node.element);
12951295
}
12961296

1297+
/// Returns the name value of the `JSExportName` annotation (when compiling
1298+
/// the SDK), or `null` if there's none. This is used to control the name
1299+
/// under which functions are compiled and exported.
1300+
String _getJSExportName(Element e) {
1301+
if (e is! FunctionElement || !currentLibrary.source.isInSystemLibrary) {
1302+
return null;
1303+
}
1304+
var jsName = findAnnotation(e, isJSExportNameAnnotation);
1305+
return getConstantField(jsName, 'name', types.stringType)?.toStringValue();
1306+
}
1307+
12971308
@override
12981309
JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
12991310
assert(node.parent is CompilationUnit);
@@ -1309,7 +1320,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
13091320
var body = <JS.Statement>[];
13101321
_flushLibraryProperties(body);
13111322

1312-
var name = node.name.name;
1323+
var name = _getJSExportName(node.element) ?? node.name.name;
13131324

13141325
var fn = _visit(node.functionExpression);
13151326
bool needsTagging = true;
@@ -1575,8 +1586,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
15751586

15761587
_loader.declareBeforeUse(element);
15771588

1578-
var name = element.name;
1579-
15801589
// type literal
15811590
if (element is ClassElement ||
15821591
element is DynamicElementImpl ||
@@ -1587,9 +1596,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
15871596

15881597
// library member
15891598
if (element.enclosingElement is CompilationUnitElement) {
1590-
return _maybeQualifiedName(element);
1599+
return _emitTopLevelName(element);
15911600
}
15921601

1602+
var name = element.name;
1603+
15931604
// Unqualified class member. This could mean implicit-this, or implicit
15941605
// call to a static from the same class.
15951606
if (element is ClassMemberElement && element is! ConstructorElement) {
@@ -1757,17 +1768,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
17571768
jsArgs = [];
17581769
}
17591770
if (jsArgs != null) {
1760-
var genericName = _maybeQualifiedName(element, '$name\$');
1771+
var genericName = _emitTopLevelName(element, suffix: '\$');
17611772
return js.call('#(#)', [genericName, jsArgs]);
17621773
}
17631774
}
17641775

1765-
return _maybeQualifiedName(element);
1776+
return _emitTopLevelName(element);
17661777
}
17671778

1768-
JS.Expression _maybeQualifiedName(Element e, [String name]) {
1779+
JS.Expression _emitTopLevelName(Element e, {String suffix : ''}) {
17691780
var libName = _libraryName(e.library);
1770-
var nameExpr = _propertyName(name ?? e.name);
1781+
var nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix);
17711782

17721783
// Always qualify:
17731784
// * mutable top-level fields
@@ -2231,6 +2242,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
22312242
if (isJSTopLevel) eagerInit = true;
22322243

22332244
var fieldName = field.name.name;
2245+
if (element is TopLevelVariableElement) {
2246+
fieldName = _getJSExportName(element) ?? fieldName;
2247+
}
22342248
if ((field.isConst && eagerInit && element is TopLevelVariableElement) ||
22352249
isJSTopLevel) {
22362250
// constant fields don't change, so we can generate them as `let`

pkg/dev_compiler/lib/src/codegen/js_interop.dart

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,40 @@ import 'package:analyzer/src/generated/constant.dart';
1111
bool _isJsLibType(String expectedName, Element e) =>
1212
e?.name == expectedName && _isJsLib(e.library);
1313

14+
/// Returns true if [e] represents any library from `package:js` or is the
15+
/// internal `dart:_js_helper` library.
1416
bool _isJsLib(LibraryElement e) {
15-
var libName = e?.name;
16-
return libName == 'js' ||
17-
libName == 'js.varargs' ||
18-
libName == 'dart._js_helper';
17+
if (e == null) return false;
18+
var uri = e.source.uri;
19+
if (uri.scheme == 'package' && uri.path.startsWith('js/')) return true;
20+
if (uri.scheme == 'dart') {
21+
return uri.path == '_js_helper' || uri.path == '_foreign_helper';
22+
}
23+
return false;
1924
}
2025

26+
/// Whether [value] is a `@rest` annotation (to be used on function parameters
27+
/// to have them compiled as `...` rest params in ES6 outputs).
2128
bool isJsRestAnnotation(DartObjectImpl value) =>
2229
_isJsLibType('_Rest', value.type.element);
2330

31+
/// Whether [i] is a `spread` invocation (to be used on function arguments
32+
/// to have them compiled as `...` spread args in ES6 outputs).
2433
bool isJsSpreadInvocation(MethodInvocation i) =>
2534
_isJsLibType('spread', i.methodName?.bestElement);
2635

2736
// TODO(jmesserly): Move JsPeerInterface to package:js (see issue #135).
28-
bool isJSAnnotation(DartObjectImpl value) => value.type.name == 'JS';
37+
bool isJSAnnotation(DartObjectImpl value) =>
38+
_isJsLibType('JS', value.type.element);
39+
40+
/// Whether [value] is a `@JSExportName` (internal annotation used in SDK
41+
/// instead of `@JS` from `package:js`).
42+
bool isJSExportNameAnnotation(DartObjectImpl value) {
43+
var e = value?.type?.element;
44+
if (e?.name != 'JSExportName') return false;
45+
var uri = e.source.uri;
46+
return uri.scheme == 'dart' && uri.path == '_foreign_helper';
47+
}
2948

3049
bool isJsPeerInterface(DartObjectImpl value) =>
3150
value.type.name == 'JsPeerInterface';

pkg/dev_compiler/tool/input_sdk/private/foreign_helper.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ JS(String typeDescription, String codeTemplate,
110110
[arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11])
111111
{}
112112

113+
/// Annotates the compiled Js name for fields and methods.
114+
/// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime
115+
/// files), and not to be confused with `JSName` from `js_helper` (which deals
116+
/// with names of externs).
117+
class JSExportName {
118+
final String name;
119+
const JSExportName(this.name);
120+
}
121+
113122
/**
114123
* Returns the isolate in which this code is running.
115124
*/

pkg/dev_compiler/tool/input_sdk/private/utils.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
library dart._utils;
66

7-
import 'dart:_foreign_helper' show JS;
7+
import 'dart:_foreign_helper' show JS, JSExportName;
88

99
/// This library defines a set of general javascript utilities for us
1010
/// by the Dart runtime.
@@ -39,6 +39,7 @@ void throwInternalError(String message) => JS('', '''(() => {
3939

4040
// TODO(ochafik): Re-introduce a @JS annotation in the SDK (same as package:js)
4141
// so that this is named 'assert' in JavaScript.
42+
@JSExportName('assert')
4243
void assert_(bool condition) => JS('', '''(() => {
4344
if (!condition) throwInternalError("The compiler is broken: failed assert");
4445
})()''');

0 commit comments

Comments
 (0)