Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index 663786a19e0ae958168aef9fda664f2a612da0fa..ec7a4d39a05ade92044b7205b9ddee296ab4cc74 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -669,6 +669,34 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
hasIterator = true; |
jsMethods.add(_emitIterable(type)); |
} |
+ } else if (m is FieldDeclaration) { |
+ // TODO(vsm): Refactor common logic out. |
Jennifer Messerly
2016/02/16 17:46:38
yeah if this was in a method like _emitRenamedNati
vsm
2016/02/18 01:13:09
Refactored and added a TODO to look into metaprogr
|
+ if (!m.isStatic && _extensionTypes.contains(element)) { |
+ for (var decl in m.fields.variables) { |
+ FieldElement field = decl.element; |
Jacob
2016/02/16 17:47:35
nit: change these to variables to var?
vsm
2016/02/18 01:13:09
Done.
|
+ String name = decl.name.name; |
+ var annotation = findAnnotation(field, isJsName); |
+ if (annotation != null) { |
+ name = getConstantField(annotation, 'name', types.stringType) |
+ ?.toStringValue(); |
+ } |
+ // Generate getter |
+ var fn = new JS.Fun([], js.statement('{ return this.#; }', [name])); |
+ var method = new JS.Method(_elementMemberName(field.getter), fn, |
+ isGetter: true); |
+ jsMethods.add(method); |
+ |
+ // Generate setter |
+ if (!decl.isFinal) { |
+ var value = new JS.TemporaryId('value'); |
+ fn = new JS.Fun( |
+ [value], js.statement('{ this.# = #; }', [name, value])); |
+ method = new JS.Method(_elementMemberName(field.setter), fn, |
+ isSetter: true); |
+ jsMethods.add(method); |
+ } |
+ } |
+ } |
} |
} |
@@ -769,6 +797,16 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); |
} |
} |
+ for (var f in fields) { |
+ if (!f.isStatic) { |
+ for (var d in f.fields.variables) { |
+ if (d.element.isPublic) { |
+ dartxNames.add( |
+ _elementMemberName(d.element.getter, allowExtensions: false)); |
+ } |
+ } |
+ } |
+ } |
if (dartxNames.isNotEmpty) { |
body.add(js.statement('dart.defineExtensionNames(#)', |
[new JS.ArrayInitializer(dartxNames, multiline: true)])); |
@@ -965,8 +1003,13 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
JS.Statement _overrideField(FieldElement e) { |
var cls = e.enclosingElement; |
- return js.statement('dart.virtualField(#, #)', |
- [cls.name, _emitMemberName(e.name, type: cls.type)]); |
+ var name; |
+ if (_extensionTypes.contains(cls)) { |
Jennifer Messerly
2016/02/16 17:46:38
eeep. This is a little bit sketchy :). We try and
vsm
2016/02/18 01:13:09
Hmm, seems to work now if I revert. I had probabl
|
+ name = js.call('dart.getExtensionSymbol(#)', js.string(e.name)); |
+ } else { |
+ name = _emitMemberName(e.name, type: cls.type); |
+ } |
Jacob
2016/02/16 17:47:35
nit: consider
var name = _extensionTypes.contain
vsm
2016/02/18 01:13:09
Removed change altogether.
|
+ return js.statement('dart.virtualField(#, #)', [cls.name, name]); |
} |
/// Generates the implicit default constructor for class C of the form |
@@ -1328,9 +1371,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
} |
- JS.Fun _emitNativeFunctionBody( |
- List<JS.Parameter> params, List<JS.Expression> paramRefs, |
- MethodDeclaration node) { |
+ JS.Fun _emitNativeFunctionBody(List<JS.Parameter> params, |
+ List<JS.Expression> paramRefs, MethodDeclaration node) { |
if (node.isStatic) { |
// TODO(vsm): Do we need to handle this case? |
return null; |
@@ -1565,8 +1607,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
var body = node.body; |
if (body.isGenerator || body.isAsynchronous) { |
var paramRefs = _emitParameterReferences(node.parameters); |
- jsBody = _emitGeneratorFunctionBody( |
- params, paramRefs, body, returnType); |
+ jsBody = |
+ _emitGeneratorFunctionBody(params, paramRefs, body, returnType); |
} else if (body is ExpressionFunctionBody) { |
jsBody = _visit(body.expression); |
} else { |
@@ -1589,9 +1631,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
} |
- JS.Fun _emitFunctionBody(List<JS.Parameter> params, |
- List<JS.Expression> paramRefs, FunctionBody body, |
- List<JS.Identifier> typeParams, JS.TypeRef returnType) { |
+ JS.Fun _emitFunctionBody( |
+ List<JS.Parameter> params, |
+ List<JS.Expression> paramRefs, |
+ FunctionBody body, |
+ List<JS.Identifier> typeParams, |
+ JS.TypeRef returnType) { |
// sync*, async, async* |
if (body.isAsynchronous || body.isGenerator) { |
// TODO(ochafik): Refine params: we don't need default values in the |
@@ -1609,9 +1654,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
typeParams: typeParams, returnType: returnType); |
} |
- JS.Expression _emitGeneratorFunctionBody( |
- List<JS.Parameter> params, List<JS.Expression> paramRefs, |
- FunctionBody body, JS.TypeRef returnType) { |
+ JS.Expression _emitGeneratorFunctionBody(List<JS.Parameter> params, |
+ List<JS.Expression> paramRefs, FunctionBody body, JS.TypeRef returnType) { |
var kind = body.isSynchronous ? 'sync' : 'async'; |
if (body.isGenerator) kind += 'Star'; |
@@ -2180,13 +2224,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
// TODO(ochafik): Decouple Parameter from Identifier. |
List<JS.Expression> _emitParameterReferences(FormalParameterList node) => |
node == null |
- ? <JS.Expression>[] |
- : _emitFormalParameterList(node, allowDestructuring: false) |
- .map((JS.Parameter p) { |
- if (p is JS.RestParameter) return new JS.Spread(p.parameter); |
- return p as JS.Identifier; |
- }) |
- .toList(); |
+ ? <JS.Expression>[] |
+ : _emitFormalParameterList(node, allowDestructuring: false) |
+ .map((JS.Parameter p) { |
+ if (p is JS.RestParameter) return new JS.Spread(p.parameter); |
+ return p as JS.Identifier; |
+ }).toList(); |
List<JS.Parameter> _emitFormalParameterList(FormalParameterList node, |
{bool allowDestructuring: true}) { |
@@ -2221,11 +2264,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
} else { |
var jsParam = _visit(param); |
- result.add( |
- param is DefaultFormalParameter && destructure |
- ? new JS.DestructuredVariable( |
- name: jsParam, defaultValue: _defaultParamValue(param)) |
- : jsParam); |
+ result.add(param is DefaultFormalParameter && destructure |
+ ? new JS.DestructuredVariable( |
+ name: jsParam, defaultValue: _defaultParamValue(param)) |
+ : jsParam); |
} |
} |
@@ -2990,7 +3032,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
bool _requiresStaticDispatch(Expression target, String memberName) { |
var type = getStaticType(target); |
- if (!_isObjectProperty(memberName)) { |
+ if (!_isObjectProperty(memberName) || target is SuperExpression) { |
Jennifer Messerly
2016/02/16 17:46:38
nice fix.
Jacob
2016/02/16 17:47:35
Why does target is SuperExpression require static
Jennifer Messerly
2016/02/16 18:22:00
Yup, that's what the CL is fixing, if I understand
|
return false; |
} |
if (!type.isObject && |
Jennifer Messerly
2016/02/16 18:22:01
wow, this code is confusing. Can we rewrite it lik
vsm
2016/02/18 01:13:09
Excellent point - cleaned up code! The explicit s
vsm
2016/02/18 15:23:55
Ugh, had to back off this a little bit. We don't
|
@@ -3586,6 +3628,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
baseType = baseType.element.bound; |
} |
if (allowExtensions && |
+ baseType != null && |
_extensionTypes.contains(baseType.element) && |
!_isObjectProperty(name)) { |
return js.call('dartx.#', _propertyName(name)); |
@@ -3732,6 +3775,12 @@ class JSGenerator extends CodeGenerator { |
var finder = new _ExtensionFinder(context, _extensionTypes, _types); |
finder._addExtensionTypes('dart:_interceptors'); |
finder._addExtensionTypes('dart:_native_typed_data'); |
+ finder._addExtensionTypes('dart:html'); |
+ finder._addExtensionTypes('dart:indexed_db'); |
+ finder._addExtensionTypes('dart:svg'); |
+ finder._addExtensionTypes('dart:web_audio'); |
+ finder._addExtensionTypes('dart:web_gl'); |
+ finder._addExtensionTypes('dart:web_sql'); |
// TODO(vsm): If we're analyzing against the main SDK, those |
// types are not explicitly annotated. |