-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAstDecl.java
More file actions
278 lines (217 loc) · 8.79 KB
/
Copy pathAstDecl.java
File metadata and controls
278 lines (217 loc) · 8.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
package processing.mode.cpp;
import java.util.List;
/*
* Consolidated declaration AST node types -- formerly 10 separate files
* under tools/cpp-parser's ast/decl/ package. Merged for the same reason
* as AstExpr.java; see its header comment.
*/
/**
* Marker for anything that can appear directly inside a CompilationUnit:
* a VariableDecl, FunctionDecl, TypeDef, EnumDecl, NamespaceDecl, or
* UsingNamespaceDecl. Also reused as the "member of a class/struct body"
* marker (TypeDef.members), since the corpus confirms the same shapes
* (field VariableDecl, method/constructor/destructor FunctionDecl, nested
* TypeDef) appear in both top-level and class-body positions identically.
*/
sealed interface TopLevelItem extends Node
permits VariableDecl, FunctionDecl, TypeDef, EnumDecl, NamespaceDecl,
UsingNamespaceDecl, PreprocessorLine, TopLevelStatement {
}
/** The root AST node: an entire parsed source file as a list of top-level items. */
record CompilationUnit(List<TopLevelItem> items) {
}
/**
* A top-level or class-field variable declaration, e.g. "int steps = 0;",
* "std::string axiom;", "PenroseSnowflakeLSystem ps;", "static int count;".
*
* Per the multi-declarator desugaring decision (see DeclStatement's notes,
* which apply identically here): "int rectX, rectY;" and "color rectColor,
* circleColor, baseColor;" both desugar into multiple single-name
* VariableDecl nodes at parse time, sharing one TypeRef each, confirmed
* necessary at both top-level scope (Button fixture) and inside a class
* body (Handles fixture's Handle class fields).
*
* isConst/isStatic confirmed needed by the type_system kitchen-sink batch
* ("const int LIMIT = 100;", "static int count;").
*/
record VariableDecl(
TypeRef type,
String name,
List<Expr> arrayDims,
Expr initializer,
boolean isConst,
boolean isStatic,
List<String> templateParams,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
VariableDecl(TypeRef type, String name, List<Expr> arrayDims,
Expr initializer, boolean isConst, boolean isStatic,
int line, int col, List<CppLexerToken> leadingComments) {
this(type, name, arrayDims, initializer, isConst, isStatic,
List.of(), line, col, leadingComments);
}
}
/**
* A function declaration/definition. This single node shape covers every
* function-like form confirmed in the corpus:
*
* - free functions ("void setup() { ... }", "static int staticFreeFunction(int n)")
* - methods, including one-liner setters ("void useRule(std::string r_) { rule = r_; }")
* - virtual methods and virtual destructors ("virtual std::string iterate(...)",
* "virtual ~LSystem() {}")
* - override methods ("std::string iterate(...) override { ... }")
* - const methods ("float getX() const { return x; }")
* - constructors, including with an initializer list
* ("Handle(int x) : x_(x), y_(0) { }") -- isConstructor is true and
* returnType is null in this case
* - destructors ("virtual ~LSystem() {}") -- isDestructor is true,
* returnType is null
* - operator overloads ("bool operator==(const Handle& other) const { ... }")
* -- name is the literal text "operator==", no separate node needed
* - template functions ("template<typename T> T myMax(T a, T b) { ... }")
* -- templateParams is non-empty
*
* Note on isConstructor/isDestructor vs returnType: constructors and
* destructors have no return type in C++ syntax at all (not even "void") --
* returnType is null for both, and the parser distinguishes "this is a
* constructor" by the function name matching the enclosing class name with
* no return type present, and "this is a destructor" by a leading "~".
* These flags exist so later passes don't need to re-derive that from name
* matching every time.
*/
record FunctionDecl(
TypeRef returnType, // null for constructors/destructors
String name, // includes "operator==" style names verbatim
List<String> templateParams,
List<Param> params,
List<ConstructorInit> initializerList, // empty unless isConstructor
Block body, // null for a declaration with no definition (rare in corpus, supported regardless)
boolean isConstructor,
boolean isDestructor,
boolean isVirtual,
boolean isOverride,
boolean isConst,
boolean isConstexpr,
boolean isStatic,
boolean isPureVirtual, // "= 0" specifier
boolean isDefault, // "= default"
boolean isDelete, // "= delete"
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
/** One "member(args...)" entry in a constructor's initializer list. */
public record ConstructorInit(String memberName, List<Expr> args) {
}
}
/**
* A class or struct declaration: "class Name [: public Base1, public Base2] { members }"
* or "struct Name { members }".
*
* kind distinguishes "class" vs "struct" textually -- confirmed by the corpus
* that both forms are used (LSystem/Handle as class, Point/Counter as struct)
* but behave identically in every other respect for parsing purposes, so one
* node with a kind field is sufficient (no separate ClassDecl/StructDecl).
*
* baseClasses is a List, not a nullable single name -- confirmed necessary by
* the multiple-inheritance fixture ("class Sprite : public Movable, public
* Drawable"). Empty list for no inheritance.
*
* templateParams is empty for non-template types; confirmed necessary by
* "template<typename T> class Box" and the two-parameter
* "template<typename K, typename V> class Pair" form.
*/
record TypeDef(
String kind, // "class" or "struct"
String name,
List<String> templateParams,
List<String> baseClasses,
List<TopLevelItem> members,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}
/**
* "enum Name { VALUE1, VALUE2, ... };" (isScoped=false) or
* "enum class Name { VALUE1, VALUE2 };" (isScoped=true).
*
* isScoped is a real semantic difference, not just cosmetic -- confirmed by
* the corpus that unscoped enum values are usable bare ("Color c = RED;")
* while scoped enum values require qualification ("Direction d =
* Direction::UP;"). A later name-resolution pass needs this flag to know
* whether an enum's values pollute the enclosing scope or not; the parser
* itself doesn't enforce the distinction, it just records which form was
* written.
*/
record EnumDecl(
String name,
boolean isScoped,
List<String> values,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}
/**
* "namespace Name { items }".
*
* NOTE (carried over from the synthetic test-fixture brief): real .pde-style
* CppMode sketches have not been confirmed to ever use namespaces. This node
* exists so the parser doesn't choke if one appears, but semantic-pass
* support for namespace-aware name resolution is deliberately deprioritized
* until real sketch input demonstrates the need. Parse-only support for now.
*/
record NamespaceDecl(
String name,
boolean isInline,
List<TopLevelItem> items,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}
/** "using namespace Name;". Same low-priority/parse-only status as NamespaceDecl. */
record UsingNamespaceDecl(
String name,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}
/**
* An opaque preprocessor directive line ("#include ...", "#define ...", etc.),
* passed through verbatim per the original grammar-scope decision: the parser
* never deeply parses preprocessor directives, only preserves their raw text
* and position so codegen can re-emit them unchanged in the right place.
*/
record PreprocessorLine(
String rawText,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}
/**
* Wraps a bare statement appearing directly at file (top) scope -- confirmed
* necessary by real Processing "static mode" sketches in the example corpus
* (e.g. Coordinates.pde), which have no setup()/draw() at all and consist of
* a flat sequence of statements executed once, top to bottom. A call like
* "size(640, 360);" at true top level doesn't fit any other TopLevelItem
* shape (it's not a declaration), so it's wrapped here instead, carrying
* the underlying Statement unchanged.
*
* This was NOT anticipated by the original corpus walk -- all four
* hand-picked example sketches happened to use active mode with explicit
* setup()/draw(). Found only by running the parser against the full real
* example corpus.
*/
record TopLevelStatement(
Statement statement,
int line,
int col,
List<CppLexerToken> leadingComments
) implements TopLevelItem {
}