@@ -642,12 +642,15 @@ $name.prototype[Symbol.iterator] = function() {
642
642
out.write (') ' );
643
643
node.body.accept (this );
644
644
} else {
645
+ var bindThis = _needsBindThis (node.body);
646
+ if (bindThis) out.write ("(" );
645
647
out.write ("(" );
646
648
_visitNode (node.parameters);
647
649
out.write (") => " );
648
650
var body = node.body;
649
651
if (body is ExpressionFunctionBody ) body = body.expression;
650
652
body.accept (this );
653
+ if (bindThis) out.write (").bind(this)" );
651
654
}
652
655
}
653
656
@@ -674,11 +677,8 @@ $name.prototype[Symbol.iterator] = function() {
674
677
if (e.enclosingElement is CompilationUnitElement &&
675
678
(e.library != libraryInfo.library || _needsModuleGetter (e))) {
676
679
out.write ('${_jsLibraryName (e .library )}.' );
677
- } else if (currentClass != null ) {
678
- if (e is PropertyAccessorElement && ! e.variable.isStatic ||
679
- e is ClassMemberElement && ! e.isStatic && e is ! ConstructorElement ) {
680
- out.write ('this.' );
681
- }
680
+ } else if (currentClass != null && _needsImplicitThis (e)) {
681
+ out.write ('this.' );
682
682
}
683
683
out.write (node.name);
684
684
}
@@ -1244,7 +1244,9 @@ $name.prototype[Symbol.iterator] = function() {
1244
1244
if (node.parent is ! ExpressionStatement ) {
1245
1245
out.write ('return ${_cascadeTarget .name };\n ' );
1246
1246
}
1247
- out.write ('})(' , - 2 );
1247
+ out.write ('})' , - 2 );
1248
+ if (_needsBindThis (node.cascadeSections)) out.write ('.bind(this)' );
1249
+ out.write ('(' );
1248
1250
node.target.accept (this );
1249
1251
out.write (')' );
1250
1252
}
@@ -1850,6 +1852,18 @@ $name.prototype[Symbol.iterator] = function() {
1850
1852
name = _canonicalMethodName (name);
1851
1853
return name.startsWith ('[' ) ? name : '.$name ' ;
1852
1854
}
1855
+
1856
+ bool _needsBindThis (node) {
1857
+ if (currentClass == null ) return false ;
1858
+ var visitor = _BindThisVisitor ._instance;
1859
+ visitor._bindThis = false ;
1860
+ node.accept (visitor);
1861
+ return visitor._bindThis;
1862
+ }
1863
+
1864
+ static bool _needsImplicitThis (Element e) =>
1865
+ e is PropertyAccessorElement && ! e.variable.isStatic ||
1866
+ e is ClassMemberElement && ! e.isStatic && e is ! ConstructorElement ;
1853
1867
}
1854
1868
1855
1869
/// Returns true if the local variable is potentially mutated within [context] .
@@ -1901,6 +1915,25 @@ class _AssignmentFinder extends RecursiveAstVisitor {
1901
1915
}
1902
1916
}
1903
1917
1918
+ /// This is a workaround for V8 arrow function bindings being not yet
1919
+ /// implemented. See issue #43
1920
+ class _BindThisVisitor extends RecursiveAstVisitor {
1921
+ static _BindThisVisitor _instance = new _BindThisVisitor ();
1922
+ bool _bindThis = false ;
1923
+
1924
+ @override
1925
+ visitSimpleIdentifier (SimpleIdentifier node) {
1926
+ if (JSCodegenVisitor ._needsImplicitThis (node.staticElement)) {
1927
+ _bindThis = true ;
1928
+ }
1929
+ }
1930
+
1931
+ @override
1932
+ visitThisExpression (ThisExpression node) {
1933
+ _bindThis = true ;
1934
+ }
1935
+ }
1936
+
1904
1937
class JSGenerator extends CodeGenerator {
1905
1938
JSGenerator (String outDir, Uri root, TypeRules rules)
1906
1939
: super (outDir, root, rules);
0 commit comments