Chromium Code Reviews| 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..105f4c9088ce453203598669240aa023882edbac 100644 |
| --- a/lib/src/compiler/code_generator.dart |
| +++ b/lib/src/compiler/code_generator.dart |
| @@ -116,6 +116,9 @@ class CodeGenerator extends GeneralizingAstVisitor |
| String _buildRoot; |
| + /// Whether we are currently generating code for the body of a `JS()` call. |
| + bool _isInForeignJS = false; |
| + |
| CodeGenerator(AnalysisContext c, this.options, this._extensionTypes) |
| : context = c, |
| types = c.typeProvider, |
| @@ -219,7 +222,6 @@ class CodeGenerator extends GeneralizingAstVisitor |
| // Add implicit dart:core dependency so it is first. |
| emitLibraryName(dartCoreLibrary); |
| - // |
| // Visit each compilation unit and emit its code. |
| // |
| // NOTE: declarations are not necessarily emitted in this order. |
| @@ -2009,7 +2011,19 @@ class CodeGenerator extends GeneralizingAstVisitor |
| // type literal |
| if (element is TypeDefiningElement) { |
| - return _emitTypeName(fillDynamicTypeArgs(element.type)); |
| + var typeName = _emitTypeName(fillDynamicTypeArgs(element.type)); |
| + |
| + // If the type is a type literal expression in Dart code, wrap the raw |
| + // runtime type in a "Type" instance. |
| + if (!_isInForeignJS && |
| + node.parent is! MethodInvocation && |
| + node.parent is! PrefixedIdentifier && |
| + node.parent is! PropertyAccess) { |
| + // A type literal expression in use. Wrap the runtime type in a "Type" object. |
|
Jennifer Messerly
2016/05/03 20:59:54
long line.
Bob Nystrom
2016/05/03 21:24:32
Oops. Meant to delete that comment (I moved it out
|
| + typeName = js.call('dart.wrapType(#)', typeName); |
| + } |
| + |
| + return typeName; |
| } |
| // library member |
| @@ -2477,11 +2491,22 @@ class CodeGenerator extends GeneralizingAstVisitor |
| source = (code as StringLiteral).stringValue; |
| } |
| - var template = js.parseForeignJS(source); |
| - var result = template.instantiate(_visitList(templateArgs)); |
| - // `throw` is emitted as a statement by `parseForeignJS`. |
| - assert(result is JS.Expression || node.parent is ExpressionStatement); |
| - return result; |
| + // TODO(rnystrom): The JS() calls are almost never nested, and probably |
| + // really shouldn't be, but there are at least a couple of calls in the |
| + // HTML library where an argument to JS() is itself a JS() call. If those |
|
Jennifer Messerly
2016/05/03 20:59:54
haha, wow. The crazy stuff you find sometimes :)
Bob Nystrom
2016/05/03 21:24:32
Acknowledged.
|
| + // go away, this can just assert(!_isInForeignJS). |
| + var wasInForeignJS = _isInForeignJS; |
| + try { |
|
Jennifer Messerly
2016/05/03 20:59:54
nit: try/finally is not needed. We will never try
Bob Nystrom
2016/05/03 21:24:32
Done.
|
| + _isInForeignJS = true; |
| + |
| + var template = js.parseForeignJS(source); |
| + var result = template.instantiate(_visitList(templateArgs)); |
| + // `throw` is emitted as a statement by `parseForeignJS`. |
| + assert(result is JS.Expression || node.parent is ExpressionStatement); |
| + return result; |
| + } finally { |
| + _isInForeignJS = wasInForeignJS; |
| + } |
| } |
| return null; |
| } |