Remove AST-hack for multi-field declarations.

R=sigmund@google.com

Review URL: https://codereview.chromium.org/2244333003 .
This commit is contained in:
Johnni Winther 2016-08-17 10:05:13 +02:00
parent 910b2ba016
commit 502b6d55ff
4 changed files with 58 additions and 23 deletions

View file

@ -1473,6 +1473,7 @@ abstract class VariableElementX extends ElementX
final Token token;
final VariableList variables;
VariableDefinitions definitionsCache;
Expression definitionCache;
Expression initializerCache;
Modifiers get modifiers => variables.modifiers;
@ -1505,6 +1506,16 @@ abstract class VariableElementX extends ElementX
return definitionsCache;
}
/// Returns the node that defines this field.
///
/// For instance in `var a, b = true`, the definitions nodes for fields 'a'
/// and 'b' are the nodes for `a` and `b = true`, respectively.
Expression get definition {
assert(invariant(this, definitionCache != null,
message: "Definition node has not been computed for $this."));
return definitionCache;
}
Expression get initializer {
assert(invariant(this, definitionsCache != null,
message: "Initializer has not been computed for $this."));
@ -1522,8 +1533,6 @@ abstract class VariableElementX extends ElementX
void createDefinitions(VariableDefinitions definitions) {
assert(invariant(this, definitionsCache == null,
message: "VariableDefinitions has already been computed for $this."));
Expression node;
int count = 0;
for (Link<Node> link = definitions.definitions.nodes;
!link.isEmpty;
link = link.tail) {
@ -1533,28 +1542,16 @@ abstract class VariableElementX extends ElementX
SendSet sendSet = initializedIdentifier.asSendSet();
identifier = sendSet.selector.asIdentifier();
if (identical(name, identifier.source)) {
node = initializedIdentifier;
definitionCache = initializedIdentifier;
initializerCache = sendSet.arguments.first;
}
} else if (identical(name, identifier.source)) {
node = initializedIdentifier;
definitionCache = initializedIdentifier;
}
count++;
}
invariant(definitions, node != null, message: "Could not find '$name'.");
if (count == 1) {
definitionsCache = definitions;
} else {
// Create a [VariableDefinitions] node for the single definition of
// [node].
definitionsCache = new VariableDefinitions(
definitions.type,
definitions.modifiers,
new NodeList(
definitions.definitions.beginToken,
const Link<Node>().prepend(node),
definitions.definitions.endToken));
}
invariant(definitions, definitionCache != null,
message: "Could not find '$name'.");
definitionsCache = definitions;
}
DartType computeType(Resolution resolution) {
@ -1659,6 +1656,14 @@ class ErroneousFieldElementX extends ElementX
Token get token => node.getBeginToken();
get definitionCache {
throw new UnsupportedError("definitionCache");
}
set definitionCache(_) {
throw new UnsupportedError("definitionCache=");
}
get initializerCache {
throw new UnsupportedError("initializerCache");
}
@ -1673,6 +1678,8 @@ class ErroneousFieldElementX extends ElementX
get initializer => null;
get definition => null;
bool get isMalformed => true;
get nestedClosures {
@ -3016,6 +3023,7 @@ class EnumFieldElementX extends FieldElementX {
definitionsCache = new VariableDefinitions(
null, variableList.modifiers, new NodeList.singleton(definition));
initializerCache = initializer;
definitionCache = definition;
}
@override

View file

@ -361,7 +361,7 @@ class ResolverTask extends CompilerTask {
ResolutionRegistry registry = visitor.registry;
// TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
// to the backend ast.
registry.defineElement(tree.definitions.nodes.head, element);
registry.defineElement(element.definition, element);
// TODO(johnniwinther): Share the resolved type between all variables
// declared in the same declaration.
if (tree.type != null) {

View file

@ -661,6 +661,8 @@ const Map<String, List<Test>> DECL_TESTS = const {
const [
const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
element: 'field(C#m)'),
const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
element: 'field(C#n)'),
]),
const Test.clazz(
'''
@ -787,7 +789,9 @@ const Map<String, List<Test>> DECL_TESTS = const {
''',
const [
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#m)'),
element: 'field(C#m)'),
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#n)'),
]),
const Test.clazz(
'''
@ -797,7 +801,13 @@ const Map<String, List<Test>> DECL_TESTS = const {
''',
const [
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#m)'),
element: 'field(C#k)'),
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#l)'),
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#m)'),
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#n)'),
]),
const Test.clazz(
'''
@ -820,6 +830,9 @@ const Map<String, List<Test>> DECL_TESTS = const {
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#m)',
rhs: 42),
const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
element: 'field(C#n)',
rhs: true),
]),
const Test.clazz(
'''
@ -846,7 +859,9 @@ const Map<String, List<Test>> DECL_TESTS = const {
''',
const [
const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
element: 'field(m)'),
element: 'field(m)'),
const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
element: 'field(n)'),
]),
const Test(
'''

View file

@ -671,6 +671,18 @@ class ConstClass {
final x;
const ConstClass(this.x);
}
''',
}),
const Test('Multi variable declaration', const {
'main.dart': '''
import 'a.dart';
main() => y;
''',
}, preserializedSourceFiles: const {
'a.dart': '''
var x, y = 2;
''',
}),
];