@@ -65,7 +65,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
65
65
/// The variable for the current catch clause
66
66
SimpleIdentifier _catchParameter;
67
67
68
- ClassDeclaration currentClass;
69
68
ConstantEvaluator _constEvaluator;
70
69
71
70
final _exports = new Set <String >();
@@ -319,8 +318,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
319
318
var jsName = getAnnotationValue (node, _isJsNameAnnotation);
320
319
if (jsName != null ) return _emitJsType (node.name.name, jsName);
321
320
322
- currentClass = node;
323
-
324
321
var ctors = < ConstructorDeclaration > [];
325
322
var fields = < FieldDeclaration > [];
326
323
var staticFields = < FieldDeclaration > [];
@@ -337,7 +334,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
337
334
338
335
var body =
339
336
_finishClassMembers (classElem, classExpr, ctors, fields, staticFields);
340
- currentClass = null ;
341
337
342
338
return _finishClassDef (type, body);
343
339
}
@@ -1016,49 +1012,55 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
1016
1012
/// going through the qualified library name if necessary.
1017
1013
@override
1018
1014
JS .Expression visitSimpleIdentifier (SimpleIdentifier node) {
1019
- var e = node.staticElement;
1020
- if (e == null ) {
1015
+ var accessor = node.staticElement;
1016
+ if (accessor == null ) {
1021
1017
return js.commentExpression (
1022
1018
'Unimplemented unknown name' , new JS .Identifier (node.name));
1023
1019
}
1024
1020
1025
- var variable = e is PropertyAccessorElement ? e.variable : e;
1026
- var name = variable.name;
1021
+ // Get the original declaring element. If we had a property accessor, this
1022
+ // indirects back to a (possibly synthetic) field.
1023
+ var element = accessor;
1024
+ if (element is PropertyAccessorElement ) element = accessor.variable;
1025
+ var name = element.name;
1027
1026
1028
1027
// library member
1029
- if (e .enclosingElement is CompilationUnitElement &&
1030
- (e .library != libraryInfo.library ||
1031
- variable is TopLevelVariableElement && ! variable .isConst)) {
1032
- return js.call ('#.#' , [_libraryName (e .library), name]);
1028
+ if (element .enclosingElement is CompilationUnitElement &&
1029
+ (element .library != libraryInfo.library ||
1030
+ element is TopLevelVariableElement && ! element .isConst)) {
1031
+ return js.call ('#.#' , [_libraryName (element .library), name]);
1033
1032
}
1034
1033
1035
- // instance member
1036
- if (currentClass != null && _needsImplicitThis (e)) {
1037
- return js. call (
1038
- 'this.#' , _emitMemberName (name, type : currentClass. element.type)) ;
1039
- }
1034
+ // Unqualified class member. This could mean implicit-this, or implicit
1035
+ // call to a static from the same class.
1036
+ if (element is ClassMemberElement && element is ! ConstructorElement ) {
1037
+ bool isStatic = element.isStatic ;
1038
+ var type = element.enclosingElement.type;
1040
1039
1041
- // static member
1042
- if (e is ExecutableElement &&
1043
- e.isStatic &&
1044
- variable.enclosingElement is ClassElement ) {
1045
- var className = (variable.enclosingElement as ClassElement ).name;
1046
- return js.call ('#.#' , [className, _emitMemberName (name, isStatic: true )]);
1040
+ // For instance methods, we add implicit-this.
1041
+ // For static methods, we add the raw type name, without generics or
1042
+ // library prefix. We don't need those because static calls can't use
1043
+ // the generic type.
1044
+ var target = isStatic ? new JS .Identifier (type.name) : new JS .This ();
1045
+ var member = _emitMemberName (name, isStatic: isStatic, type: type);
1046
+ return new JS .PropertyAccess (target, member);
1047
1047
}
1048
1048
1049
1049
// initializing formal parameter, e.g. `Point(this.x)`
1050
- if (e is ParameterElement && e.isInitializingFormal && e.isPrivate) {
1050
+ if (element is ParameterElement &&
1051
+ element.isInitializingFormal &&
1052
+ element.isPrivate) {
1051
1053
/// Rename private names so they don't shadow the private field symbol.
1052
1054
/// The renamer would handle this, but it would prefer to rename the
1053
1055
/// temporary used for the private symbol. Instead rename the parameter.
1054
- return _getTemp (e , '${name .substring (1 )}' );
1056
+ return _getTemp (element , '${name .substring (1 )}' );
1055
1057
}
1056
1058
1057
- if (_isTemporary (e )) {
1059
+ if (_isTemporary (element )) {
1058
1060
if (name[0 ] == '#' ) {
1059
1061
return new JS .InterpolatedExpression (name.substring (1 ));
1060
1062
} else {
1061
- return _getTemp (e , name);
1063
+ return _getTemp (element , name);
1062
1064
}
1063
1065
}
1064
1066
@@ -2312,10 +2314,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
2312
2314
}
2313
2315
2314
2316
DartType getStaticType (Expression e) => rules.getStaticType (e);
2315
-
2316
- static bool _needsImplicitThis (Element e) =>
2317
- e is PropertyAccessorElement && ! e.variable.isStatic ||
2318
- e is ClassMemberElement && ! e.isStatic && e is ! ConstructorElement ;
2319
2317
}
2320
2318
2321
2319
class JSGenerator extends CodeGenerator {
0 commit comments