Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(562)

Unified Diff: lib/src/compiler/code_generator.dart

Issue 1948563002: allow 'super' in async and finally blocks (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/src/compiler/source_map_printer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/compiler/code_generator.dart
diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
index 1276c85eaeaeed3e9b6f4a7bbe8d4cff67e002fc..753a7d464f297b54006304ed7a75b992447c0639 100644
--- a/lib/src/compiler/code_generator.dart
+++ b/lib/src/compiler/code_generator.dart
@@ -116,6 +116,10 @@ class CodeGenerator extends GeneralizingAstVisitor
String _buildRoot;
+ bool _superAllowed = true;
+
+ List<JS.Method> _superHelpers = <JS.Method>[];
+
CodeGenerator(AnalysisContext c, this.options, this._extensionTypes)
: context = c,
types = c.typeProvider,
@@ -832,7 +836,7 @@ class CodeGenerator extends GeneralizingAstVisitor
jsMethods
.add(_emitConstructor(m, type, fields, virtualFields, isObject));
} else if (m is MethodDeclaration) {
- jsMethods.add(_emitMethodDeclaration(type, m));
+ jsMethods.add(_emitMethodDeclaration(m));
if (m.element is PropertyAccessorElement) {
jsMethods.add(_emitSuperAccessorWrapper(m, type, superclasses));
@@ -868,6 +872,10 @@ class CodeGenerator extends GeneralizingAstVisitor
jsMethods.add(_emitIterable(type));
}
+ // Add all of the super helper methods
+ jsMethods.addAll(_superHelpers);
+ _superHelpers.clear();
+
return jsMethods.where((m) => m != null).toList(growable: false);
}
@@ -1616,7 +1624,7 @@ class CodeGenerator extends GeneralizingAstVisitor
}
}
- JS.Method _emitMethodDeclaration(DartType type, MethodDeclaration node) {
+ JS.Method _emitMethodDeclaration(MethodDeclaration node) {
if (node.isAbstract) {
return null;
}
@@ -1939,8 +1947,11 @@ class CodeGenerator extends GeneralizingAstVisitor
} else {
_asyncStarController = null;
}
+ var savedSuperAllowed = _superAllowed;
+ _superAllowed = false;
// Visit the body with our async* controller set.
var jsBody = _visit(body);
+ _superAllowed = savedSuperAllowed;
_asyncStarController = savedController;
DartType returnType = _getExpectedReturnType(element);
@@ -2359,6 +2370,11 @@ class CodeGenerator extends GeneralizingAstVisitor
}
jsTarget = new JS.PropertyAccess(jsTarget, memberName);
+
+ if (target is SuperExpression && !_superAllowed) {
+ return _emitSuperForwarder(node, jsTarget, typeArgs, args);
+ }
+
if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs);
if (DynamicInvoke.get(node.methodName)) {
Jennifer Messerly 2016/05/03 18:56:18 Is there a way to restructure this code so it's re
Harry Terkelsen 2016/05/05 23:37:35 There is a way ;)
@@ -2371,6 +2387,56 @@ class CodeGenerator extends GeneralizingAstVisitor
return new JS.Call(jsTarget, args);
}
+ JS.Expression _emitSuperForwarder(
+ MethodInvocation node,
+ JS.PropertyAccess jsTarget,
+ List<JS.Expression> typeArgs,
+ List<JS.Expression> args) {
+ var helperMethod = _getSuperHelperFor(node, jsTarget, typeArgs, args);
+ var newTarget = new JS.PropertyAccess(new JS.This(), helperMethod);
+ var helperArgs = <JS.Expression>[];
+ if (typeArgs != null) {
+ helperArgs.addAll(typeArgs);
+ }
+ helperArgs.addAll(args);
+ return new JS.Call(newTarget, helperArgs);
Jennifer Messerly 2016/05/03 18:56:18 FYI: you could build these like: return js.call('
Harry Terkelsen 2016/05/05 23:37:34 Done.
+ }
+
+ JS.Expression _getSuperHelperFor(
Jennifer Messerly 2016/05/03 18:56:18 Probably worth a doc comment about what this metho
+ MethodInvocation node,
+ JS.PropertyAccess jsTarget,
+ List<JS.Expression> typeArgs,
Jennifer Messerly 2016/05/03 18:56:18 Hmmm, this is an interesting approach. It's one su
+ List<JS.Expression> args) {
+ var counter = 0;
+ var helperArgs =
+ new List.generate(typeArgs?.length ?? 0 + args.length, (index) {
+ new JS.Identifier('a${counter++}');
Jennifer Messerly 2016/05/03 18:56:18 this should be symbolized so it doesn't collide wi
Harry Terkelsen 2016/05/05 23:37:34 Done.
+ }, growable: false);
+
+ var newTarget;
+ if (typeArgs != null) {
+ newTarget = new JS.Call(jsTarget, helperArgs.sublist(0, typeArgs.length));
+ } else {
+ newTarget = jsTarget;
+ }
+
+ var forwardedCall;
+ if (DynamicInvoke.get(node.methodName)) {
+ forwardedCall = js.call('dart.dcall(#, #)',
+ [newTarget, helperArgs.sublist(typeArgs?.length ?? 0)]);
+ } else {
+ forwardedCall =
+ new JS.Call(newTarget, helperArgs.sublist(typeArgs?.length ?? 0));
+ }
+
+ var helperMethod =
+ new JS.Fun(helperArgs, new JS.Block([new JS.Return(forwardedCall)]));
+ var helperMethodName =
+ js.string('super\$${node.methodName.name}${_superHelpers.length}', "'");
Jennifer Messerly 2016/05/03 18:56:18 based on comment above, "helperMethodName" will ju
Harry Terkelsen 2016/05/05 23:37:34 Done.
+ _superHelpers.add(new JS.Method(helperMethodName, helperMethod));
+ return helperMethodName;
+ }
+
/// Emits a function call, to a top-level function, local function, or
/// an expression.
JS.Expression _emitFunctionCall(InvocationExpression node) {
@@ -3723,8 +3789,12 @@ class CodeGenerator extends GeneralizingAstVisitor
@override
visitTryStatement(TryStatement node) {
- return new JS.Try(_visit(node.body), _visitCatch(node.catchClauses),
- _visit(node.finallyBlock));
+ var savedSuperAllowed = _superAllowed;
+ _superAllowed = false;
+ var finallyBlock = _visit(node.finallyBlock);
+ _superAllowed = savedSuperAllowed;
+ return new JS.Try(
+ _visit(node.body), _visitCatch(node.catchClauses), finallyBlock);
}
_visitCatch(NodeList<CatchClause> clauses) {
« no previous file with comments | « no previous file | lib/src/compiler/source_map_printer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698