Skip to content

Commit 35db90a

Browse files
johnniwintherCommit Queue
authored andcommitted
[cfe][analyzer] Add metadata parser
This adds a shared metadata parser to be used for macros. The parser create a new AST which supports unresolved ASTs and delayed AST resolution. An id-test is added for the generated AST from both CFE and analyzer. Change-Id: Ie51817493fa6e668727a7af3a55cd22e2be722b3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391100 Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Jens Johansen <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent d75fe77 commit 35db90a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+8133
-11
lines changed

pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ analyzer:
2020
- test/inference/inferred_type_arguments/data/**
2121
- test/inference/inferred_variable_types/data/**
2222
- test/inheritance/data/**
23+
- test/metadata/data/**
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'expressions.dart';
6+
import 'proto.dart';
7+
8+
/// Superclass for named and position arguments.
9+
// TODO(johnniwinther): Merge subclasses into one class?
10+
sealed class Argument {
11+
/// Returns the [Argument] corresponding to this [Argument] in
12+
/// which all [UnresolvedIdentifier]s have been resolved within their scope.
13+
///
14+
/// If this didn't create a new [Argument], `null` is returned.
15+
Argument? resolve();
16+
}
17+
18+
class PositionalArgument extends Argument {
19+
final Expression expression;
20+
21+
PositionalArgument(this.expression);
22+
23+
@override
24+
String toString() => 'PositionalArgument($expression)';
25+
26+
@override
27+
Argument? resolve() {
28+
Expression? newExpression = expression.resolve();
29+
return newExpression == null ? null : new PositionalArgument(newExpression);
30+
}
31+
}
32+
33+
class NamedArgument extends Argument {
34+
final String name;
35+
final Expression expression;
36+
37+
NamedArgument(this.name, this.expression);
38+
39+
@override
40+
String toString() => 'NamedArgument($name,$expression)';
41+
42+
@override
43+
Argument? resolve() {
44+
Expression? newExpression = expression.resolve();
45+
return newExpression == null
46+
? null
47+
: new NamedArgument(name, newExpression);
48+
}
49+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
export 'arguments.dart';
6+
export 'elements.dart';
7+
export 'expressions.dart';
8+
export 'formal_parameters.dart';
9+
export 'proto.dart';
10+
export 'record_fields.dart';
11+
export 'references.dart';
12+
export 'string_literal_parts.dart';
13+
export 'type_annotations.dart';
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'expressions.dart';
6+
import 'proto.dart';
7+
8+
/// Superclass for collection elements.
9+
sealed class Element {
10+
/// Returns the [Element] corresponding to this [Element] in
11+
/// which all [UnresolvedIdentifier]s have been resolved within their scope.
12+
///
13+
/// If this didn't create a new [Element], `null` is returned.
14+
Element? resolve();
15+
}
16+
17+
class ExpressionElement extends Element {
18+
final Expression expression;
19+
final bool isNullAware;
20+
21+
ExpressionElement(this.expression, {required this.isNullAware});
22+
23+
@override
24+
String toString() =>
25+
'ExpressionElement($expression,isNullAware=$isNullAware)';
26+
27+
@override
28+
Element? resolve() {
29+
Expression? newExpression = expression.resolve();
30+
return newExpression == null
31+
? null
32+
: new ExpressionElement(newExpression, isNullAware: isNullAware);
33+
}
34+
}
35+
36+
class MapEntryElement extends Element {
37+
final Expression key;
38+
final Expression value;
39+
final bool isNullAwareKey;
40+
final bool isNullAwareValue;
41+
42+
MapEntryElement(this.key, this.value,
43+
{required this.isNullAwareKey, required this.isNullAwareValue});
44+
45+
@override
46+
String toString() => 'MapEntryElement($key,$value,'
47+
'isNullAwareKey=$isNullAwareValue,isNullAwareValue=$isNullAwareValue)';
48+
49+
@override
50+
Element? resolve() {
51+
Expression? newKey = key.resolve();
52+
Expression? newValue = value.resolve();
53+
return newKey == null && newValue == null
54+
? null
55+
: new MapEntryElement(newKey ?? key, newValue ?? value,
56+
isNullAwareKey: isNullAwareKey, isNullAwareValue: isNullAwareValue);
57+
}
58+
}
59+
60+
class SpreadElement extends Element {
61+
final Expression expression;
62+
final bool isNullAware;
63+
64+
SpreadElement(this.expression, {required this.isNullAware});
65+
66+
@override
67+
String toString() => 'SpreadElement($expression,isNullAware=$isNullAware)';
68+
69+
@override
70+
Element? resolve() {
71+
Expression? newExpression = expression.resolve();
72+
return newExpression == null
73+
? null
74+
: new SpreadElement(newExpression, isNullAware: isNullAware);
75+
}
76+
}
77+
78+
class IfElement extends Element {
79+
final Expression condition;
80+
final Element then;
81+
final Element? otherwise;
82+
83+
IfElement(this.condition, this.then, [this.otherwise]);
84+
85+
@override
86+
String toString() => 'IfElement($condition,$then,$otherwise)';
87+
88+
@override
89+
Element? resolve() {
90+
Expression? newCondition = condition.resolve();
91+
Element? newThen = then.resolve();
92+
Element? newOtherwise = otherwise?.resolve();
93+
if (otherwise != null) {
94+
return newCondition == null && newThen == null && newOtherwise == null
95+
? null
96+
: new IfElement(newCondition ?? condition, newThen ?? then,
97+
newOtherwise ?? otherwise);
98+
} else {
99+
return newCondition == null && newThen == null
100+
? null
101+
: new IfElement(newCondition ?? condition, newThen ?? then);
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)