| 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 361f5ec0198127d03ab3f0f684ebeaa356228e5d..f325aab49335f3f870d4273d7a126a8baf5c4db1 100644
|
| --- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| +++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| @@ -324,11 +324,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| elementJSName = getAnnotationName(e, isPublicJSAnnotation) ?? '';
|
| }
|
|
|
| - if (e is TopLevelVariableElement &&
|
| - e.getter != null &&
|
| - (e.getter.isExternal ||
|
| - findAnnotation(e.getter, isPublicJSAnnotation) != null)) {
|
| - elementJSName = getAnnotationName(e.getter, isPublicJSAnnotation) ?? '';
|
| + if (e is TopLevelVariableElement) {
|
| + elementJSName = _jsInteropStaticMemberName(e);
|
| }
|
| if (elementJSName == null) return null;
|
|
|
| @@ -353,6 +350,38 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return access;
|
| }
|
|
|
| + String _jsInteropStaticMemberName(Element e, {String name}) {
|
| + if (e == null ||
|
| + e.library == null ||
|
| + findAnnotation(e.library, isPublicJSAnnotation) == null) {
|
| + return null;
|
| + }
|
| + if (e is PropertyInducingElement) {
|
| + // Assume properties have consistent JS names for getters and setters.
|
| + return _jsInteropStaticMemberName(e.getter, name: e.name) ??
|
| + _jsInteropStaticMemberName(e.setter, name: e.name);
|
| + }
|
| + if (e is ExecutableElement &&
|
| + e.isExternal &&
|
| + findAnnotation(e, isPublicJSAnnotation) != null) {
|
| + return getAnnotationName(e, isPublicJSAnnotation) ?? name ?? e.name;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + JS.Expression _emitJSInteropStaticMemberName(Element e) {
|
| + var name = _jsInteropStaticMemberName(e);
|
| + if (name == null) return null;
|
| + // We do not support statics names with JS annotations containing dots.
|
| + // See https://github.com/dart-lang/sdk/issues/27926
|
| + if (name.contains('.')) {
|
| + throw new UnimplementedError(
|
| + 'We do not support JS annotations containing dots on static members. '
|
| + 'See https://github.com/dart-lang/sdk/issues/27926');
|
| + }
|
| + return js.string(name);
|
| + }
|
| +
|
| /// Flattens blocks in [items] to a single list.
|
| ///
|
| /// This will not flatten blocks that are marked as being scopes.
|
| @@ -2705,7 +2734,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| if (element is ClassMemberElement && element is! ConstructorElement) {
|
| bool isStatic = element.isStatic;
|
| var type = element.enclosingElement.type;
|
| - var member = _emitMemberName(name, isStatic: isStatic, type: type);
|
| + var member = _emitMemberName(name,
|
| + isStatic: isStatic, type: type, element: element);
|
|
|
| if (isStatic) {
|
| var dynType = _emitStaticAccess(type);
|
| @@ -3271,7 +3301,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| ClassElement classElement = element.enclosingElement;
|
| var type = classElement.type;
|
| var dynType = _emitStaticAccess(type);
|
| - var member = _emitMemberName(element.name, isStatic: true, type: type);
|
| + var member = _emitMemberName(element.name,
|
| + isStatic: true, type: type, element: element);
|
| return _visit(rhs).toAssignExpression(
|
| annotate(new JS.PropertyAccess(dynType, member), lhs));
|
| }
|
| @@ -3282,7 +3313,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| JS.Expression jsTarget, Element element, JS.Expression value) {
|
| String memberName = element.name;
|
| var type = (element.enclosingElement as ClassElement).type;
|
| - var name = _emitMemberName(memberName, type: type);
|
| + var name = _emitMemberName(memberName, type: type, element: element);
|
| return value.toAssignExpression(
|
| annotate(new JS.PropertyAccess(jsTarget, name), lhs));
|
| }
|
| @@ -3430,21 +3461,25 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return _emitStaticAccess(
|
| (element.enclosingElement as ClassElement).type);
|
| }
|
| + if (element is FieldElement) {
|
| + return _emitStaticAccess(element.enclosingElement.type);
|
| + }
|
| }
|
| return _visit(target);
|
| }
|
|
|
| - /// Emits a (possibly generic) instance method call.
|
| + /// Emits a (possibly generic) instance, or static method call.
|
| JS.Expression _emitMethodCallInternal(
|
| Expression target,
|
| MethodInvocation node,
|
| List<JS.Expression> args,
|
| List<JS.Expression> typeArgs) {
|
| var type = getStaticType(target);
|
| - var name = node.methodName.name;
|
| var element = node.methodName.staticElement;
|
| bool isStatic = element is ExecutableElement && element.isStatic;
|
| - var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
|
| + var name = node.methodName.name;
|
| + var memberName =
|
| + _emitMemberName(name, type: type, isStatic: isStatic, element: element);
|
|
|
| JS.Expression jsTarget = _emitTarget(target, element, isStatic);
|
| if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
|
| @@ -4807,7 +4842,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| String memberName, List<JS.Expression> typeArgs) {
|
| bool isStatic = member is ClassMemberElement && member.isStatic;
|
| var name = _emitMemberName(memberName,
|
| - type: getStaticType(target), isStatic: isStatic);
|
| + type: getStaticType(target), isStatic: isStatic, element: member);
|
| if (isDynamicInvoke(target)) {
|
| if (_inWhitelistCode(target)) {
|
| var vars = <JS.MetaLetVariable, JS.Expression>{};
|
| @@ -5426,9 +5461,14 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| /// helper, that checks for null. The user defined method is called '=='.
|
| ///
|
| JS.Expression _emitMemberName(String name,
|
| - {DartType type, bool isStatic: false, bool useExtension}) {
|
| - // Static members skip the rename steps.
|
| - if (isStatic) return _propertyName(name);
|
| + {DartType type,
|
| + bool isStatic: false,
|
| + bool useExtension,
|
| + Element element}) {
|
| + // Static members skip the rename steps and may require JS interop renames.
|
| + if (isStatic) {
|
| + return _emitJSInteropStaticMemberName(element) ?? _propertyName(name);
|
| + }
|
|
|
| if (name.startsWith('_')) {
|
| return _emitPrivateNameSymbol(currentLibrary, name);
|
|
|