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 199a629e74a9a4fbdc601c56b03680ae25dd8ca9..4b386c9eba0ab05dcf008ca0baa9bbe9a7a14c9c 100644 |
| --- a/lib/src/compiler/code_generator.dart |
| +++ b/lib/src/compiler/code_generator.dart |
| @@ -5,39 +5,36 @@ |
| import 'dart:collection' show HashMap, HashSet; |
| import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| +import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator; |
| import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| -import 'package:analyzer/dart/ast/ast.dart' hide ConstantEvaluator; |
| - |
| -//TODO(leafp): Remove deprecated dependency |
| -//ignore: DEPRECATED_MEMBER_USE |
| +import 'package:analyzer/src/dart/ast/token.dart' show StringToken; |
| import 'package:analyzer/src/generated/element.dart' |
| show DynamicTypeImpl, LocalVariableElementImpl; |
| import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| import 'package:analyzer/src/generated/resolver.dart' |
| show TypeProvider, NamespaceBuilder; |
| -import 'package:analyzer/src/dart/ast/token.dart' show StringToken; |
| import 'package:analyzer/src/generated/type_system.dart' |
| show StrongTypeSystemImpl; |
| import 'package:analyzer/src/summary/summarize_elements.dart' |
| show PackageBundleAssembler; |
| import 'package:analyzer/src/task/strong/info.dart' show DynamicInvoke; |
| +import 'package:source_maps/source_maps.dart'; |
| +import '../closure/closure_annotator.dart' show ClosureAnnotator; |
| import '../js_ast/js_ast.dart' as JS; |
| import '../js_ast/js_ast.dart' show js; |
| -import '../closure/closure_annotator.dart' show ClosureAnnotator; |
| - |
| import 'ast_builder.dart' show AstBuilder; |
| import 'compiler.dart' |
| show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat; |
| import 'element_helpers.dart'; |
| import 'element_loader.dart' show ElementLoader; |
| import 'extension_types.dart' show ExtensionTypeSet; |
| -import 'js_field_storage.dart' show findFieldsNeedingStorage; |
| +import 'js_field_storage.dart' show checkForPropertyOverride, getSuperclasses; |
| import 'js_interop.dart'; |
| -import 'js_names.dart' as JS; |
| import 'js_metalet.dart' as JS; |
| +import 'js_names.dart' as JS; |
| import 'js_typeref_codegen.dart' show JsTypeRefCodegen; |
| import 'module_builder.dart' |
| show LegacyModuleBuilder, NodeModuleBuilder, pathToJSIdentifier; |
| @@ -45,7 +42,9 @@ import 'nullable_type_inference.dart' show NullableTypeInference; |
| import 'reify_coercions.dart' show CoercionReifier; |
| import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless; |
| import 'source_map_printer.dart' show SourceMapPrintingContext; |
| -import 'package:source_maps/source_maps.dart'; |
| +//TODO(leafp): Remove deprecated dependency |
|
Jennifer Messerly
2016/04/21 00:53:08
it looks like this comment got moved around in a s
Harry Terkelsen
2016/04/21 01:00:11
Done.
|
| +//ignore: DEPRECATED_MEMBER_USE |
| + |
| class CodeGenerator extends GeneralizingAstVisitor |
| with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference { |
| @@ -69,10 +68,6 @@ class CodeGenerator extends GeneralizingAstVisitor |
| /// The global extension type table. |
| final ExtensionTypeSet _extensionTypes; |
| - /// Information that is precomputed for this library, indicates which fields |
| - /// need storage slots. |
| - HashSet<FieldElement> _fieldsNeedingStorage; |
| - |
| /// The variable for the target of the current `..` cascade expression. |
| /// |
| /// Usually a [SimpleIdentifier], but it can also be other expressions |
| @@ -184,9 +179,6 @@ class CodeGenerator extends GeneralizingAstVisitor |
| throw new StateError('Can only call emitModule once.'); |
| } |
| - _fieldsNeedingStorage = findFieldsNeedingStorage( |
| - compilationUnits.map((u) => u.element), _extensionTypes); |
| - |
| // Transform the AST to make coercions explicit. |
| compilationUnits = CoercionReifier.reify(compilationUnits); |
| @@ -554,7 +546,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
| // Emit things that come after the ES6 `class ... { ... }`. |
| _setBaseClass(classElem, className, body); |
| _defineNamedConstructors(ctors, body, className); |
| - _emitVirtualFields(fields, className, body); |
| + _emitVirtualFields(classElem, fields, className, body); |
| _emitClassSignature(methods, classElem, ctors, extensions, className, body); |
| _defineExtensionMembers(extensions, className, body); |
| _emitClassMetadata(node.metadata, className, body); |
| @@ -774,6 +766,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } |
| bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; |
| + var superclasses = getSuperclasses(element); |
| bool hasIterator = false; |
| for (var m in node.members) { |
| @@ -782,6 +775,10 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } else if (m is MethodDeclaration) { |
| jsMethods.add(_emitMethodDeclaration(type, m)); |
| + if (m.element is PropertyAccessorElement) { |
| + jsMethods.add(_emitSuperAccessorWrapper(m, type, superclasses)); |
| + } |
| + |
| if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { |
| hasIterator = true; |
| jsMethods.add(_emitIterable(type)); |
| @@ -806,6 +803,32 @@ class CodeGenerator extends GeneralizingAstVisitor |
| return jsMethods.where((m) => m != null).toList(growable: false); |
| } |
| + JS.Method _emitSuperAccessorWrapper(MethodDeclaration method, |
| + InterfaceType type, List<ClassElement> superclasses) { |
| + var methodElement = method.element as PropertyAccessorElement; |
| + var field = methodElement.variable; |
| + if (!field.isSynthetic) return null; |
| + var propertyOverrideResult = checkForPropertyOverride( |
| + methodElement.variable, superclasses, _extensionTypes); |
| + |
| + // Generate a corresponding virtual getter / setter. |
| + var name = _elementMemberName(methodElement, |
| + allowExtensions: _extensionTypes.contains(type.element)); |
| + if (method.isGetter) { |
| + // Generate a setter |
| + if (field.setter != null || !propertyOverrideResult.foundSetter) |
| + return null; |
| + var fn = js.call('function(value) { super[#] = value; }', [name]); |
| + return new JS.Method(name, fn, isSetter: true); |
| + } else { |
| + // Generate a getter |
| + if (field.getter != null || !propertyOverrideResult.foundGetter) |
| + return null; |
| + var fn = js.call('function() { return super[#]; }', [name]); |
| + return new JS.Method(name, fn, isGetter: true); |
| + } |
| + } |
| + |
| bool _implementsIterable(InterfaceType t) => |
| t.interfaces.any((i) => i.element.type == types.iterableType); |
| @@ -890,11 +913,19 @@ class CodeGenerator extends GeneralizingAstVisitor |
| /// Emits instance fields, if they are virtual |
| /// (in other words, they override a getter/setter pair). |
| - void _emitVirtualFields(List<FieldDeclaration> fields, |
| - JS.Expression className, List<JS.Statement> body) { |
| + void _emitVirtualFields( |
| + ClassElement classElement, |
| + List<FieldDeclaration> fields, |
| + JS.Expression className, |
| + List<JS.Statement> body) { |
| + List<ClassElement> superclasses = getSuperclasses(classElement); |
| for (FieldDeclaration member in fields) { |
| for (VariableDeclaration field in member.fields.variables) { |
| - if (_fieldsNeedingStorage.contains(field.element)) { |
| + var propertyOverrideResult = checkForPropertyOverride( |
| + field.element, superclasses, _extensionTypes); |
| + if (!field.element.isSynthetic && |
|
Jennifer Messerly
2016/04/21 00:53:08
I think these can't be synthetic, because we got t
Harry Terkelsen
2016/04/21 01:00:11
Done.
|
| + (propertyOverrideResult.foundGetter || |
| + propertyOverrideResult.foundSetter)) { |
| body.add(_overrideField(className, field.element)); |
| } |
| } |