Ensure we're looking at the correct resolved AST when initializing fields in constructors.
Step 30 of bagilliondy. BUG=https://github.com/dart-lang/sdk/issues/27394 R=sigmund@google.com Review-Url: https://codereview.chromium.org/2616933003 .
This commit is contained in:
@@ -115,6 +115,9 @@ class _ResolvedUriTranslator implements ResolvedUriTranslator {
|
||||
bool allowInternalLibraryAccess = importingLibrary != null &&
|
||||
(importingLibrary.isPlatformLibrary ||
|
||||
importingLibrary.isPatch ||
|
||||
// The memory scheme is specifically for unit tests that use the
|
||||
// in-memory compiler.
|
||||
importingLibrary.canonicalUri.scheme == 'memory' ||
|
||||
importingLibrary.canonicalUri.path
|
||||
.contains('sdk/tests/compiler/dart2js_native'));
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import '../js/js.dart' as js;
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../kernel/kernel.dart';
|
||||
import '../native/native.dart' as native;
|
||||
import '../resolution/tree_elements.dart';
|
||||
import '../tree/dartstring.dart';
|
||||
import '../tree/nodes.dart' show Node, BreakStatement;
|
||||
import '../types/masks.dart';
|
||||
@@ -115,9 +114,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||
@override
|
||||
JavaScriptBackend get backend => compiler.backend;
|
||||
|
||||
@override
|
||||
TreeElements get elements => resolvedAst.elements;
|
||||
|
||||
SourceInformationBuilder sourceInformationBuilder;
|
||||
KernelAstAdapter astAdapter;
|
||||
LoopHandler<ir.Node> loopHandler;
|
||||
@@ -298,8 +294,12 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||
if (field.initializer == null) {
|
||||
fieldValues[field] = graph.addConstantNull(closedWorld);
|
||||
} else {
|
||||
// Gotta update the resolvedAst when we're looking at field values
|
||||
// outside the constructor.
|
||||
astAdapter.pushResolvedAst(field);
|
||||
field.initializer.accept(this);
|
||||
fieldValues[field] = pop();
|
||||
astAdapter.popResolvedAstStack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||
return builtArguments;
|
||||
}
|
||||
|
||||
/// Inlines the given super [constructor]'s initializers by collecting it's
|
||||
/// Inlines the given super [constructor]'s initializers by collecting its
|
||||
/// field values and building its constructor initializers. We visit super
|
||||
/// constructors all the way up to the [Object] constructor.
|
||||
void _buildInlinedInitializers(ir.Constructor constructor,
|
||||
@@ -793,8 +793,8 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||
HLoopInformation loopInfo = current.loopInformation;
|
||||
HBasicBlock loopEntryBlock = current;
|
||||
HBasicBlock bodyEntryBlock = current;
|
||||
JumpTarget target =
|
||||
elements.getTargetDefinition(astAdapter.getNode(doStatement));
|
||||
JumpTarget target = astAdapter.elements
|
||||
.getTargetDefinition(astAdapter.getNode(doStatement));
|
||||
bool hasContinues = target != null && target.isContinueTarget;
|
||||
if (hasContinues) {
|
||||
// Add extra block to hang labels on.
|
||||
@@ -906,8 +906,8 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||
// Since the body of the loop has a break, we attach a synthesized label
|
||||
// to the body.
|
||||
SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
|
||||
JumpTarget target =
|
||||
elements.getTargetDefinition(astAdapter.getNode(doStatement));
|
||||
JumpTarget target = astAdapter.elements
|
||||
.getTargetDefinition(astAdapter.getNode(doStatement));
|
||||
LabelDefinition label = target.addLabel(null, 'loop');
|
||||
label.setBreakTarget();
|
||||
HLabeledBlockInformation info = new HLabeledBlockInformation(
|
||||
|
||||
@@ -11,7 +11,6 @@ import '../elements/resolution_types.dart';
|
||||
import '../elements/elements.dart';
|
||||
import '../io/source_information.dart';
|
||||
import '../js_backend/js_backend.dart';
|
||||
import '../resolution/tree_elements.dart';
|
||||
import '../tree/tree.dart' as ast;
|
||||
import '../types/types.dart';
|
||||
import '../universe/call_structure.dart' show CallStructure;
|
||||
@@ -38,9 +37,6 @@ abstract class GraphBuilder {
|
||||
/// The JavaScript backend we are targeting in this compilation.
|
||||
JavaScriptBackend get backend;
|
||||
|
||||
/// The tree elements for the element being built into an SSA graph.
|
||||
TreeElements get elements;
|
||||
|
||||
CodegenRegistry get registry;
|
||||
|
||||
ClosedWorld get closedWorld;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import 'package:js_runtime/shared/embedded_names.dart';
|
||||
import 'package:kernel/ast.dart' as ir;
|
||||
|
||||
import 'dart:collection' show Queue;
|
||||
|
||||
import '../common.dart';
|
||||
import '../common/names.dart';
|
||||
import '../compiler.dart';
|
||||
@@ -36,7 +38,6 @@ import 'types.dart';
|
||||
class KernelAstAdapter {
|
||||
final Kernel kernel;
|
||||
final JavaScriptBackend _backend;
|
||||
final ResolvedAst _resolvedAst;
|
||||
final Map<ir.Node, ast.Node> _nodeToAst;
|
||||
final Map<ir.Node, Element> _nodeToElement;
|
||||
final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals =
|
||||
@@ -44,6 +45,12 @@ class KernelAstAdapter {
|
||||
final Map<ir.LabeledStatement, KernelJumpTarget> _jumpTargets =
|
||||
<ir.LabeledStatement, KernelJumpTarget>{};
|
||||
DartTypeConverter _typeConverter;
|
||||
ResolvedAst _resolvedAst;
|
||||
|
||||
/// Sometimes for resolution the resolved AST element needs to change (for
|
||||
/// example, if we're inlining, or if we're in a constructor, but then also
|
||||
/// constructing the field values). We keep track of this with a stack.
|
||||
Queue<ResolvedAst> _resolvedAstStack;
|
||||
|
||||
KernelAstAdapter(this.kernel, this._backend, this._resolvedAst,
|
||||
this._nodeToAst, this._nodeToElement) {
|
||||
@@ -67,6 +74,20 @@ class KernelAstAdapter {
|
||||
_nodeToElement[kernel.typeParameters[typeVariable]] = typeVariable;
|
||||
}
|
||||
_typeConverter = new DartTypeConverter(this);
|
||||
_resolvedAstStack = new Queue<ResolvedAst>();
|
||||
}
|
||||
|
||||
/// Push the existing resolved AST on the stack and shift the current resolved
|
||||
/// AST to the AST that this kernel node points to.
|
||||
void pushResolvedAst(ir.Node node) {
|
||||
_resolvedAstStack.addLast(_resolvedAst);
|
||||
_resolvedAst = getElement(node).resolvedAst;
|
||||
}
|
||||
|
||||
/// Pop the resolved AST stack to reset it to the previous resolved AST node.
|
||||
void popResolvedAstStack() {
|
||||
assert(_resolvedAstStack.isNotEmpty);
|
||||
_resolvedAst = _resolvedAstStack.removeLast();
|
||||
}
|
||||
|
||||
Compiler get _compiler => _backend.compiler;
|
||||
|
||||
@@ -46,6 +46,27 @@ main() => new Foo(number: 3);
|
||||
''';
|
||||
return check(code, lookup: defaultConstructorFor('Foo'));
|
||||
});
|
||||
|
||||
// TODO(efortuna): Kernel needs to have some additional constructor
|
||||
// implementaion work before this is legitimately equivalent code to the
|
||||
// original AST.
|
||||
/* test('initialized field and constructor', () {
|
||||
String code = '''
|
||||
import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL;
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
|
||||
class Foo {
|
||||
final value = JS('bool', '#()', JS_EMBEDDED_GLOBAL('', 'foo'));
|
||||
Foo() {
|
||||
print('hello world');
|
||||
}
|
||||
}
|
||||
|
||||
main() => new Foo();
|
||||
''';
|
||||
return check(code, lookup: defaultConstructorFor('Foo'));
|
||||
});*/
|
||||
}
|
||||
|
||||
defaultConstructorFor(String className) => (Compiler compiler) {
|
||||
|
||||
Reference in New Issue
Block a user