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

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

Issue 2797443007: fix #29182, generate top level const fields lazily (Closed)
Patch Set: fix Created 3 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 | « pkg/dev_compiler/lib/sdk/ddc_sdk.sum ('k') | pkg/dev_compiler/lib/src/compiler/element_loader.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/dev_compiler/lib/src/compiler/code_generator.dart
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index cbbdd0b837ff2a6a55650f49afb68bae25883973..ef155dc3dde28936b1c3272ad905348299908445 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -41,7 +41,6 @@ import '../js_ast/js_ast.dart' show js;
import 'ast_builder.dart' show AstBuilder;
import 'compiler.dart' show BuildUnit, CompilerOptions, JSModuleFile;
import 'element_helpers.dart';
-import 'element_loader.dart' show ElementLoader;
import 'extension_types.dart' show ExtensionTypeSet;
import 'js_interop.dart';
import 'js_metalet.dart' as JS;
@@ -72,6 +71,10 @@ class CodeGenerator extends GeneralizingAstVisitor
/// Imported libraries, and the temporaries used to refer to them.
final _imports = new Map<LibraryElement, JS.TemporaryId>();
+ /// The list of dart:_runtime SDK functions; these are assumed by other code
+ /// in the SDK to be generated before anything else.
+ final _internalSdkFunctions = <JS.ModuleItem>[];
+
/// The list of output module items, in the order they need to be emitted in.
final _moduleItems = <JS.ModuleItem>[];
@@ -105,8 +108,6 @@ class CodeGenerator extends GeneralizingAstVisitor
final _hasDeferredSupertype = new HashSet<ClassElement>();
- final _eagerTopLevelFields = new HashSet<Element>.identity();
-
/// The type provider from the current Analysis [context].
final TypeProvider types;
@@ -134,9 +135,24 @@ class CodeGenerator extends GeneralizingAstVisitor
/// The current function body being compiled.
FunctionBody _currentFunction;
- /// Helper class for emitting elements in the proper order to allow
- /// JS to load the module.
- ElementLoader _loader;
+ HashMap<TypeDefiningElement, AstNode> _declarationNodes;
+
+ /// The stack of currently emitting elements, if generating top-level code
+ /// for them. This is not used when inside method bodies, because order does
+ /// not matter for those.
+ final _topLevelElements = <TypeDefiningElement>[];
+
+ /// The current element being loaded.
+ /// We can use this to determine if we're loading top-level code or not:
+ ///
+ /// _currentElements.last == _topLevelElements.last
+ //
+ // TODO(jmesserly): ideally we'd only track types here, in other words,
+ // TypeDefiningElement. However we still rely on this for [currentLibrary] so
+ // we need something to be pushed always.
+ final _currentElements = <Element>[];
+
+ final _deferredProperties = new HashMap<PropertyAccessorElement, JS.Method>();
BuildUnit _buildUnit;
@@ -182,7 +198,9 @@ class CodeGenerator extends GeneralizingAstVisitor
_getLibrary(c, 'dart:_internal').getType('PrivateSymbol'),
dartJSLibrary = _getLibrary(c, 'dart:js');
- LibraryElement get currentLibrary => _loader.currentElement.library;
+ Element get currentElement => _currentElements.last;
+
+ LibraryElement get currentLibrary => currentElement.library;
/// The main entry point to JavaScript code generation.
///
@@ -285,19 +303,17 @@ class CodeGenerator extends GeneralizingAstVisitor
}
}
- // Collect all Element -> Node mappings, in case we need to forward declare
- // any nodes.
- var nodes = new HashMap<Element, AstNode>.identity();
- var sdkBootstrappingFns = new List<FunctionElement>();
+ // Collect all class/type Element -> Node mappings
+ // in case we need to forward declare any classes.
+ _declarationNodes = new HashMap<TypeDefiningElement, AstNode>.identity();
for (var unit in compilationUnits) {
- if (isSdkInternalRuntime(
- resolutionMap.elementDeclaredByCompilationUnit(unit).library)) {
- sdkBootstrappingFns.addAll(
- resolutionMap.elementDeclaredByCompilationUnit(unit).functions);
+ for (var declaration in unit.declarations) {
+ var element = declaration.element;
+ if (element is TypeDefiningElement) {
+ _declarationNodes[element] = declaration;
+ }
}
- _collectElements(unit, nodes);
}
- _loader = new ElementLoader(nodes);
if (compilationUnits.isNotEmpty) {
_constants = new ConstFieldVisitor(context,
dummySource: resolutionMap
@@ -308,15 +324,16 @@ class CodeGenerator extends GeneralizingAstVisitor
// Add implicit dart:core dependency so it is first.
emitLibraryName(dartCoreLibrary);
- // Emit SDK bootstrapping functions first, if any.
- sdkBootstrappingFns.forEach(_emitDeclaration);
-
// Visit each compilation unit and emit its code.
//
// NOTE: declarations are not necessarily emitted in this order.
// Order will be changed as needed so the resulting code can execute.
// This is done by forward declaring items.
- compilationUnits.forEach(_finishDeclarationsInUnit);
+ compilationUnits.forEach(_emitCompilationUnit);
+ assert(_deferredProperties.isEmpty);
+
+ // Visit directives (for exports)
+ compilationUnits.forEach(_emitExportDirectives);
// Declare imports
_finishImports(items);
@@ -324,6 +341,7 @@ class CodeGenerator extends GeneralizingAstVisitor
// Discharge the type table cache variables and
// hoisted definitions.
items.addAll(_typeTable.discharge());
+ items.addAll(_internalSdkFunctions);
// Track the module name for each library in the module.
// This data is only required for debugging.
@@ -432,7 +450,7 @@ class CodeGenerator extends GeneralizingAstVisitor
for (var item in items) {
if (item is JS.Block && !item.isScope) {
_copyAndFlattenBlocks(result, item.statements);
- } else {
+ } else if (item != null) {
result.add(item);
}
}
@@ -485,21 +503,6 @@ class CodeGenerator extends GeneralizingAstVisitor
});
}
- /// Collect toplevel elements and nodes we need to emit, and returns
- /// an ordered map of these.
- static void _collectElements(
- CompilationUnit unit, Map<Element, AstNode> map) {
- for (var declaration in unit.declarations) {
- if (declaration is TopLevelVariableDeclaration) {
- for (var field in declaration.variables.variables) {
- map[field.element] = field;
- }
- } else {
- map[declaration.element] = declaration;
- }
- }
- }
-
/// Called to emit all top-level declarations.
///
/// During the course of emitting one item, we may emit another. For example
@@ -508,40 +511,112 @@ class CodeGenerator extends GeneralizingAstVisitor
///
/// Because D depends on B, we'll emit B first if needed. However C is not
/// used by top-level JavaScript code, so we can ignore that dependency.
- void _emitDeclaration(Element e) {
- var item = _loader.emitDeclaration(e, (AstNode node) {
- // TODO(jmesserly): this is not really the right place for this.
- // Ideally we do this per function body.
- //
- // We'll need to be consistent about when we're generating functions, and
- // only run this on the outermost function, and not any closures.
- inferNullableTypes(node);
- return _visit(node) as JS.Node;
- });
+ void _emitTypeDeclaration(TypeDefiningElement e) {
+ var node = _declarationNodes.remove(e);
+ if (node == null) return null; // not from this module or already loaded.
+
+ _currentElements.add(e);
+
+ // TODO(jmesserly): this is not really the right place for this.
+ // Ideally we do this per function body.
+ //
+ // We'll need to be consistent about when we're generating functions, and
+ // only run this on the outermost function, and not any closures.
+ inferNullableTypes(node);
+
+ _moduleItems.add(_visit(node));
- if (item != null) _moduleItems.add(item);
+ var last = _currentElements.removeLast();
+ assert(identical(e, last));
}
- void _declareBeforeUse(Element e) {
- _loader.declareBeforeUse(e, _emitDeclaration);
+ /// Start generating top-level code for the element [e].
+ ///
+ /// Subsequent [emitDeclaration] calls will cause those elements to be
+ /// generated before this one, until [finishTopLevel] is called.
+ void _startTopLevelCodeForClass(TypeDefiningElement e) {
+ assert(identical(e, currentElement));
+ _topLevelElements.add(e);
vsm 2017/04/04 22:58:43 Is it worth asserting that it's not there already?
Jennifer Messerly 2017/04/04 23:18:34 I think it's ~probably okay if we skip that assert
+ }
+
+ /// Finishes the top-level code for the element [e].
+ void _finishTopLevelCodeForClass(TypeDefiningElement e) {
+ var last = _topLevelElements.removeLast();
+ assert(identical(e, last));
}
- void _finishDeclarationsInUnit(CompilationUnit unit) {
+ /// To emit top-level module items, we sometimes need to reorder them.
+ ///
+ /// This function takes care of that, and also detects cases where reordering
+ /// failed, and we need to resort to lazy loading, by marking the element as
+ /// lazy. All elements need to be aware of this possibility and generate code
+ /// accordingly.
+ ///
+ /// If we are not emitting top-level code, this does nothing, because all
+ /// declarations are assumed to be available before we start execution.
+ /// See [startTopLevel].
+ void _declareBeforeUse(TypeDefiningElement e) {
+ if (e == null) return;
+
+ var topLevel = _topLevelElements;
+ if (topLevel.isNotEmpty && identical(currentElement, topLevel.last)) {
+ // If the item is from our library, try to emit it now.
+ _emitTypeDeclaration(e);
+ }
+ }
+
+ void _emitCompilationUnit(CompilationUnit unit) {
// NOTE: this method isn't the right place to initialize
// per-compilation-unit state. Declarations can be visited out of order,
// this is only to catch things that haven't been emitted yet.
//
- // See _emitDeclaration.
+ // See _emitTypeDeclaration.
+ var library = unit.element.library;
+ bool internalSdk = isSdkInternalRuntime(library);
+ _currentElements.add(library);
+
+ List<VariableDeclaration> fields;
for (var declaration in unit.declarations) {
+ if (declaration is TopLevelVariableDeclaration) {
+ inferNullableTypes(declaration);
+ if (internalSdk && declaration.variables.isFinal) {
+ _emitInternalSdkFields(declaration.variables.variables);
+ } else {
+ (fields ??= []).addAll(declaration.variables.variables);
+ }
+ continue;
+ }
+
+ if (fields != null) {
+ _emitTopLevelFields(fields);
+ fields = null;
+ }
+
var element = declaration.element;
- if (element != null) {
- _emitDeclaration(element);
+ if (element is TypeDefiningElement) {
+ _emitTypeDeclaration(element);
+ continue;
+ }
+
+ inferNullableTypes(declaration);
+ var item = _visit(declaration);
+ if (internalSdk && element is FunctionElement) {
+ _internalSdkFunctions.add(item);
} else {
- declaration.accept(this);
+ _moduleItems.add(item);
}
}
+
+ if (fields != null) _emitTopLevelFields(fields);
+
+ _currentElements.removeLast();
+ }
+
+ void _emitExportDirectives(CompilationUnit unit) {
for (var directive in unit.directives) {
+ _currentElements.add(directive.element);
directive.accept(this);
+ _currentElements.removeLast();
}
}
@@ -575,48 +650,21 @@ class CodeGenerator extends GeneralizingAstVisitor
var exportedNames =
new NamespaceBuilder().createExportNamespaceForDirective(element);
- var libraryName = emitLibraryName(currentLibrary);
-
- // TODO(jmesserly): we could collect all of the names for bulk re-export,
- // but this is easier to implement for now.
- void emitExport(Element export, {String suffix: ''}) {
- var name = _emitTopLevelName(export, suffix: suffix);
-
- if (export is TypeDefiningElement ||
- export is FunctionElement ||
- _eagerTopLevelFields.contains(export)) {
- // classes, typedefs, functions, and eager init fields can be assigned
- // directly.
- // TODO(jmesserly): we don't know about eager init fields from other
- // modules we import, so we will never go down this code path for them.
- _moduleItems
- .add(js.statement('#.# = #;', [libraryName, name.selector, name]));
- }
- }
-
- // We only need to export main as it is the only method party of the
+ // We only need to export main as it is the only method part of the
// publicly exposed JS API for a library.
// TODO(jacobr): add a library level annotation indicating that all
// contents of a library need to be exposed to JS.
// https://github.com/dart-lang/sdk/issues/26368
-
var export = exportedNames.get('main');
- if (export == null) return;
- if (export is PropertyAccessorElement) {
- export = (export as PropertyAccessorElement).variable;
- }
-
- // Don't allow redefining names from this library.
- if (currentNames.containsKey(export.name)) return;
+ if (export is FunctionElement) {
+ // Don't allow redefining names from this library.
+ if (currentNames.containsKey(export.name)) return;
- if (export.isSynthetic && export is PropertyInducingElement) {
- _emitDeclaration(export.getter);
- _emitDeclaration(export.setter);
- } else {
- _emitDeclaration(export);
+ var name = _emitTopLevelName(export);
+ _moduleItems.add(js.statement(
+ '#.# = #;', [emitLibraryName(currentLibrary), name.selector, name]));
}
- emitExport(export);
}
@override
@@ -1313,7 +1361,7 @@ class CodeGenerator extends GeneralizingAstVisitor
var type = element.type;
if (type.isObject) return null;
- _loader.startTopLevel(element);
+ _startTopLevelCodeForClass(element);
// List of "direct" supertypes (supertype + mixins)
var basetypes = [type.superclass]..addAll(type.mixins);
@@ -1336,7 +1384,7 @@ class CodeGenerator extends GeneralizingAstVisitor
? baseclasses.first
: _callHelper('mixin(#)', [baseclasses]);
- _loader.finishTopLevel(element);
+ _finishTopLevelCodeForClass(element);
return heritage;
}
@@ -1792,17 +1840,7 @@ class CodeGenerator extends GeneralizingAstVisitor
/// otherwise define them as lazy properties.
void _emitStaticFields(List<FieldDeclaration> staticFields,
ClassElement classElem, List<JS.Statement> body) {
- var lazyStatics = <VariableDeclaration>[];
- for (FieldDeclaration member in staticFields) {
- for (VariableDeclaration field in member.fields.variables) {
- JS.Statement eagerField = _emitConstantStaticField(classElem, field);
- if (eagerField != null) {
- body.add(eagerField);
- } else {
- lazyStatics.add(field);
- }
- }
- }
+ var lazyStatics = staticFields.expand((f) => f.fields.variables).toList();
if (lazyStatics.isNotEmpty) {
body.add(_emitLazyFields(classElem, lazyStatics));
}
@@ -2133,12 +2171,7 @@ class CodeGenerator extends GeneralizingAstVisitor
new JS.Method(name, fun, isStatic: true), node, node.element);
}
- // For const constructors we need to ensure default values are
- // available for use by top-level constant initializers.
- ClassDeclaration cls = node.parent;
- if (node.constKeyword != null) _loader.startTopLevel(cls.element);
var params = visitFormalParameterList(node.parameters);
- if (node.constKeyword != null) _loader.finishTopLevel(cls.element);
// Factory constructors are essentially static methods.
if (node.factoryKeyword != null) {
@@ -2187,9 +2220,7 @@ class CodeGenerator extends GeneralizingAstVisitor
// nice to do them first.
// Also for const constructors we need to ensure default values are
// available for use by top-level constant initializers.
- if (node.constKeyword != null) _loader.startTopLevel(cls.element);
var init = _emitArgumentInitializers(node, constructor: true);
- if (node.constKeyword != null) _loader.finishTopLevel(cls.element);
if (init != null) body.add(init);
// Redirecting constructors: these are not allowed to have initializers,
@@ -2297,9 +2328,6 @@ class CodeGenerator extends GeneralizingAstVisitor
List<FieldDeclaration> fieldDecls,
Map<FieldElement, JS.TemporaryId> virtualFields,
[ConstructorDeclaration ctor]) {
- bool isConst = ctor != null && ctor.constKeyword != null;
- if (isConst) _loader.startTopLevel(cls.element);
-
// Run field initializers if they can have side-effects.
var fields = new Map<FieldElement, JS.Expression>();
var unsetFields = new Map<FieldElement, VariableDeclaration>();
@@ -2351,7 +2379,6 @@ class CodeGenerator extends GeneralizingAstVisitor
body.add(js.statement('this.# = #;', [access, initialValue]));
});
- if (isConst) _loader.finishTopLevel(cls.element);
return _statement(body);
}
@@ -2520,25 +2547,24 @@ class CodeGenerator extends GeneralizingAstVisitor
if (_externalOrNative(node)) return null;
- // If we have a getter/setter pair, they need to be defined together.
- if (node.isGetter) {
- PropertyAccessorElement element = node.element;
- var props = <JS.Method>[_emitTopLevelProperty(node)];
- var setter = element.correspondingSetter;
- if (setter != null) {
- props.add(_loader.emitDeclaration(
- setter, (node) => _emitTopLevelProperty(node)));
- }
- return _callHelperStatement('copyProperties(#, { # });',
- [emitLibraryName(currentLibrary), props]);
- }
- if (node.isSetter) {
+ if (node.isGetter || node.isSetter) {
PropertyAccessorElement element = node.element;
- var props = <JS.Method>[_emitTopLevelProperty(node)];
- var getter = element.correspondingGetter;
- if (getter != null) {
- props.add(_loader.emitDeclaration(
- getter, (node) => _emitTopLevelProperty(node)));
+ var pairAccessor = node.isGetter
+ ? element.correspondingSetter
+ : element.correspondingGetter;
+
+ var jsCode = _emitTopLevelProperty(node);
+ var props = <JS.Method>[jsCode];
+ if (pairAccessor != null) {
+ // If we have a getter/setter pair, they need to be defined together.
+ // If this is the first one, save the generated code for later.
+ // If this is the second one, get the saved code and emit both.
+ var pairCode = _deferredProperties.remove(pairAccessor);
+ if (pairCode == null) {
+ _deferredProperties[element] = jsCode;
+ return null;
+ }
+ props.add(pairCode);
}
return _callHelperStatement('copyProperties(#, { # });',
[emitLibraryName(currentLibrary), props]);
@@ -2631,7 +2657,7 @@ class CodeGenerator extends GeneralizingAstVisitor
if (type is ParameterizedType && !type.typeArguments.every(_typeIsLoaded)) {
return false;
}
- return _loader.isLoaded(type.element);
+ return !_declarationNodes.containsKey(type.element);
}
JS.Expression _emitFunctionTagged(JS.Expression fn, DartType type,
@@ -2852,10 +2878,10 @@ class CodeGenerator extends GeneralizingAstVisitor
var element = accessor;
if (accessor is PropertyAccessorElement) element = accessor.variable;
- _declareBeforeUse(element);
-
// type literal
if (element is TypeDefiningElement) {
+ _declareBeforeUse(element);
+
var typeName = _emitType(fillDynamicTypeArgs(element.type));
// If the type is a type literal expression in Dart code, wrap the raw
@@ -3157,7 +3183,9 @@ class CodeGenerator extends GeneralizingAstVisitor
}
var element = type.element;
- _declareBeforeUse(element);
+ if (element is TypeDefiningElement) {
+ _declareBeforeUse(element);
+ }
var interop = _emitJSInterop(element);
// Type parameters don't matter as JS interop types cannot be reified.
@@ -3391,7 +3419,9 @@ class CodeGenerator extends GeneralizingAstVisitor
var element = accessor;
if (accessor is PropertyAccessorElement) element = accessor.variable;
- _declareBeforeUse(element);
+ if (element is TypeDefiningElement) {
+ _declareBeforeUse(element);
+ }
if (element is LocalVariableElement || element is ParameterElement) {
return _emitSetLocal(node, element, rhs);
@@ -4010,11 +4040,11 @@ class CodeGenerator extends GeneralizingAstVisitor
return new JS.Yield(_visit(node.expression));
}
+ /// This is not used--we emit top-level fields as we are emitting the
+ /// compilation unit, see [_emitCompilationUnit].
@override
visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- for (var variable in node.variables.variables) {
- _emitDeclaration(variable.element);
- }
+ assert(false);
}
/// This is not used--we emit fields as we are emitting the class,
@@ -4050,9 +4080,9 @@ class CodeGenerator extends GeneralizingAstVisitor
@override
visitVariableDeclaration(VariableDeclaration node) {
if (node.element is PropertyInducingElement) {
- // Static and instance fields are handled elsewhere.
- assert(node.element is TopLevelVariableElement);
- return _emitTopLevelField(node);
+ // All fields are handled elsewhere.
+ assert(false);
+ return null;
}
var name = new JS.Identifier(node.name.name,
@@ -4061,87 +4091,21 @@ class CodeGenerator extends GeneralizingAstVisitor
return new JS.VariableInitialization(name, _visitInitializer(node));
}
- /// Try to emit a constant static field.
- ///
- /// If the field's initializer does not cause side effects, and if all of
- /// dependencies are safe to refer to while we are initializing the class,
- /// then we can initialize it eagerly:
- ///
- /// // Baz must be const constructor, and the name "Baz" must be defined
- /// // by this point.
- /// Foo.bar = dart.const(new Baz(42));
- ///
- /// Otherwise, we'll need to generate a lazy-static field. That ensures
- /// correct visible behavior, as well as avoiding referencing something that
- /// isn't defined yet (because it is defined later in the module).
- JS.Statement _emitConstantStaticField(
- ClassElement classElem, VariableDeclaration field) {
vsm 2017/04/04 22:58:43 We could consider keeping this/below only for case
Jennifer Messerly 2017/04/04 23:05:17 yeah... thought about that. It'd certainly be a lo
- PropertyInducingElement element = field.element;
- assert(element.isStatic);
-
- _loader.startCheckingReferences();
- JS.Expression jsInit = _visitInitializer(field);
- bool isLoaded = _loader.finishCheckingReferences();
-
- bool eagerInit =
- isLoaded && (field.isConst || _constants.isFieldInitConstant(field));
-
- var fieldName = field.name.name;
- if (eagerInit &&
- !JS.invalidStaticFieldName(fieldName) &&
- !_classProperties.staticFieldOverrides.contains(element)) {
- return annotate(
- js.statement('#.# = #;', [
- _emitTopLevelName(classElem),
- _emitMemberName(fieldName, isStatic: true),
- jsInit
- ]),
- field,
- field.element);
- }
-
- // This means it should be treated as a lazy field.
- // TODO(jmesserly): we're throwing away the initializer expression,
- // which will force us to regenerate it.
- return null;
+ /// Emits a list of top-level field.
+ void _emitTopLevelFields(List<VariableDeclaration> fields) {
+ _moduleItems.add(_emitLazyFields(currentLibrary, fields));
}
- /// Emits a top-level field.
- JS.ModuleItem _emitTopLevelField(VariableDeclaration field) {
- TopLevelVariableElement element = field.element;
- assert(element.isStatic);
-
- bool eagerInit;
- JS.Expression jsInit;
- if (field.isConst || _constants.isFieldInitConstant(field)) {
- // If the field is constant, try and generate it at the top level.
- _loader.startTopLevel(element);
- jsInit = _visitInitializer(field);
- _loader.finishTopLevel(element);
- eagerInit = _loader.isLoaded(element);
- } else {
- // TODO(jmesserly): we're visiting the initializer here, and again
- // later on when we emit lazy fields. That seems busted.
- jsInit = _visitInitializer(field);
- eagerInit = false;
- }
-
- // Treat dart:runtime stuff as safe to eagerly evaluate.
- // TODO(jmesserly): it'd be nice to avoid this special case.
- var isJSTopLevel = field.isFinal && isSdkInternalRuntime(element.library);
- if (eagerInit || isJSTopLevel) {
- // Remember that we emitted it this way, so re-export can take advantage
- // of this fact.
- _eagerTopLevelFields.add(element);
-
- return annotate(
- js.statement('# = #;', [_emitTopLevelName(element), jsInit]),
+ /// Treat dart:_runtime fields as safe to eagerly evaluate.
+ // TODO(jmesserly): it'd be nice to avoid this special case.
+ void _emitInternalSdkFields(List<VariableDeclaration> fields) {
+ for (var field in fields) {
+ _moduleItems.add(annotate(
+ js.statement('# = #;',
+ [_emitTopLevelName(field.element), _visitInitializer(field)]),
field,
- element);
+ field.element));
}
-
- assert(element.library == currentLibrary);
- return _emitLazyFields(element.library, [field]);
}
JS.Expression _visitInitializer(VariableDeclaration node) {
@@ -4157,6 +4121,8 @@ class CodeGenerator extends GeneralizingAstVisitor
for (var node in fields) {
var name = node.name.name;
var element = node.element;
+ assert(element.getAncestor((e) => identical(e, target)) != null,
+ "target is $target but enclosing element is ${element.enclosingElement}");
var access = _emitMemberName(name, isStatic: true);
methods.add(annotate(
new JS.Method(
@@ -5934,7 +5900,7 @@ class CodeGenerator extends GeneralizingAstVisitor
bool _inWhitelistCode(AstNode node, {isCall: false}) {
if (!options.useAngular2Whitelist) return false;
- var path = _loader.currentElement.source.fullName;
+ var path = currentElement.source.fullName;
var filename = path.split("/").last;
if (_uncheckedWhitelist.containsKey(filename)) {
var whitelisted = _uncheckedWhitelist[filename];
« no previous file with comments | « pkg/dev_compiler/lib/sdk/ddc_sdk.sum ('k') | pkg/dev_compiler/lib/src/compiler/element_loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698