1use crate::{ident::Ident, span::Span};
4
5use super::{
6 attribute::Annotation,
7 lit::Lit,
8 op::{AssignOpToken, BinOpToken, UnaryOp},
9 pat::Pattern,
10 path::{Path, TypeArguments},
11 stmt::Block,
12 ty::Type,
13};
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub enum Expr {
21 Literal(Lit),
23 Ident(Ident),
25 This(Span),
27 Super(Span),
29 Paren {
31 paren_span: (Span, Span),
32 expr: Box<Expr>,
33 },
34 ClassLit {
36 type_expr: Box<Type>,
37 dot_span: Span,
38 class_span: Span,
39 },
40 FieldAccess(FieldAccessExpr),
42 MethodCall(MethodCallExpr),
44 ArrayAccess(ArrayAccessExpr),
46 MethodRef(MethodRefExpr),
48 ArrayNew(ArrayNewExpr),
50 Cast(CastExpr),
52 Binary(BinaryExpr),
54 Unary(UnaryExpr),
56 Instanceof(InstanceofExpr),
58 Assign(AssignExpr),
60 Conditional(ConditionalExpr),
62 Lambda(LambdaExpr),
64 Switch(SwitchExpr),
66 NewClass(NewClassExpr),
68 ArrayInit(ArrayInitExpr),
70}
71
72impl Expr {
73 pub fn span(&self) -> Span {
74 match self {
75 Self::Literal(lit) => lit.span(),
76 Self::Ident(ident) => ident.span(),
77 Self::This(s) => *s,
78 Self::Super(s) => *s,
79 Self::Paren { paren_span, .. } => paren_span.0.join(paren_span.1),
80 Self::ClassLit {
81 type_expr,
82 class_span,
83 ..
84 } => type_expr.span().join(*class_span),
85 Self::FieldAccess(e) => e.span(),
86 Self::MethodCall(e) => e.span(),
87 Self::ArrayAccess(e) => e.span(),
88 Self::MethodRef(e) => e.span(),
89 Self::ArrayNew(e) => e.span(),
90 Self::Cast(e) => e.span(),
91 Self::Binary(e) => e.span(),
92 Self::Unary(e) => e.span(),
93 Self::Instanceof(e) => e.span(),
94 Self::Assign(e) => e.span(),
95 Self::Conditional(e) => e.span(),
96 Self::Lambda(e) => e.span,
97 Self::Switch(e) => e.span(),
98 Self::NewClass(e) => e.span(),
99 Self::ArrayInit(e) => e.brace_span.0.join(e.brace_span.1),
100 }
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
106pub struct FieldAccessExpr {
107 pub target: Box<Expr>,
108 pub dot_span: Span,
109 pub field: Ident,
110}
111
112impl FieldAccessExpr {
113 pub fn span(&self) -> Span {
114 self.target.span().join(self.field.span())
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
120pub struct MethodCallExpr {
121 pub receiver: Option<Box<Expr>>,
123 pub type_args: Option<TypeArguments>,
125 pub method: Ident,
127 pub paren_span: (Span, Span),
129 pub args: Vec<Expr>,
131}
132
133impl MethodCallExpr {
134 pub fn span(&self) -> Span {
135 let start = match &self.receiver {
136 Some(r) => r.span(),
137 None => self.method.span(),
138 };
139 start.join(self.paren_span.1)
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct ArrayAccessExpr {
146 pub array: Box<Expr>,
147 pub index: Box<Expr>,
148 pub bracket_span: (Span, Span),
149}
150
151impl ArrayAccessExpr {
152 pub fn span(&self) -> Span {
153 self.array.span().join(self.bracket_span.1)
154 }
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Hash)]
159pub struct MethodRefExpr {
160 pub target: MethodRefTarget,
161 pub colon_colon_span: Span,
162 pub type_args: Option<TypeArguments>,
163 pub method_name: Ident,
164}
165
166impl MethodRefExpr {
167 pub fn span(&self) -> Span {
168 let start = self.target.span();
169 start.join(self.method_name.span())
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Hash)]
175pub enum MethodRefTarget {
176 Type(Path),
178 Expr(Box<Expr>),
180 Super(Span),
182 SuperFromType {
184 type_name: Path,
185 dot_span: Span,
186 super_span: Span,
187 },
188}
189
190impl MethodRefTarget {
191 pub fn span(&self) -> Span {
192 match self {
193 Self::Type(p) => p.span,
194 Self::Expr(e) => e.span(),
195 Self::Super(s) => *s,
196 Self::SuperFromType {
197 type_name,
198 super_span,
199 ..
200 } => type_name.span.join(*super_span),
201 }
202 }
203}
204
205#[derive(Debug, Clone, PartialEq, Eq, Hash)]
207pub struct NewClassExpr {
208 pub new_span: Span,
209 pub type_args: Option<TypeArguments>,
210 pub class_type: Path,
211 pub paren_span: (Span, Span),
212 pub args: Vec<Expr>,
213 pub body: Option<super::item::ClassBodyDeclList>,
214}
215
216impl NewClassExpr {
217 pub fn span(&self) -> Span {
218 let end = match &self.body {
219 Some(b) => b.brace_span.1,
220 None => self.paren_span.1,
221 };
222 self.new_span.join(end)
223 }
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228pub struct ArrayNewExpr {
229 pub new_span: Span,
230 pub elem_type: Type,
231 pub dim_exprs: Vec<ArrayDimExpr>,
232 pub dims: Vec<super::ty::ArrayDim>,
233 pub initializer: Option<ArrayInitExpr>,
234}
235
236impl ArrayNewExpr {
237 pub fn span(&self) -> Span {
238 let end = match &self.initializer {
239 Some(init) => init.brace_span.1,
240 None => {
241 if let Some(dim) = self.dims.last() {
242 dim.bracket_span.1
243 } else if let Some(dim_expr) = self.dim_exprs.last() {
244 dim_expr.bracket_span.1
245 } else {
246 self.elem_type.span()
247 }
248 }
249 };
250 self.new_span.join(end)
251 }
252}
253
254#[derive(Debug, Clone, PartialEq, Eq, Hash)]
256pub struct ArrayDimExpr {
257 pub annotations: Vec<Annotation>,
258 pub bracket_span: (Span, Span),
259 pub expr: Box<Expr>,
260}
261
262#[derive(Debug, Clone, PartialEq, Eq, Hash)]
264pub struct ArrayInitExpr {
265 pub brace_span: (Span, Span),
266 pub elements: Vec<Expr>,
267 pub trailing_comma: bool,
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Hash)]
272pub struct CastExpr {
273 pub paren_span: (Span, Span),
274 pub target_type: Type,
275 pub expr: Box<Expr>,
276}
277
278impl CastExpr {
279 pub fn span(&self) -> Span {
280 self.paren_span.0.join(self.expr.span())
281 }
282}
283
284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
286pub struct BinaryExpr {
287 pub left: Box<Expr>,
288 pub op: BinOpToken,
289 pub right: Box<Expr>,
290}
291
292impl BinaryExpr {
293 pub fn span(&self) -> Span {
294 self.left.span().join(self.right.span())
295 }
296}
297
298#[derive(Debug, Clone, PartialEq, Eq, Hash)]
300pub struct UnaryExpr {
301 pub op: UnaryOp,
302 pub op_span: Span,
303 pub expr: Box<Expr>,
304 pub is_postfix: bool,
306}
307
308impl UnaryExpr {
309 pub fn span(&self) -> Span {
310 if self.is_postfix {
311 self.expr.span().join(self.op_span)
312 } else {
313 self.op_span.join(self.expr.span())
314 }
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Hash)]
320pub struct InstanceofExpr {
321 pub expr: Box<Expr>,
322 pub instanceof_span: Span,
323 pub pattern: InstanceofPattern,
324}
325
326impl InstanceofExpr {
327 pub fn span(&self) -> Span {
328 match &self.pattern {
329 InstanceofPattern::Type(t) => self.expr.span().join(t.span()),
330 InstanceofPattern::Pattern(p) => self.expr.span().join(p.span()),
331 }
332 }
333}
334
335#[derive(Debug, Clone, PartialEq, Eq, Hash)]
337pub enum InstanceofPattern {
338 Type(Type),
340 Pattern(Pattern),
342}
343
344#[derive(Debug, Clone, PartialEq, Eq, Hash)]
346pub struct AssignExpr {
347 pub target: AssignTarget,
348 pub op: AssignOpToken,
349 pub value: Box<Expr>,
350}
351
352impl AssignExpr {
353 pub fn span(&self) -> Span {
354 self.target.span().join(self.value.span())
355 }
356}
357
358#[derive(Debug, Clone, PartialEq, Eq, Hash)]
360pub enum AssignTarget {
361 Ident(Ident),
363 FieldAccess(FieldAccessExpr),
365 ArrayAccess(ArrayAccessExpr),
367}
368
369impl AssignTarget {
370 pub fn span(&self) -> Span {
371 match self {
372 Self::Ident(i) => i.span(),
373 Self::FieldAccess(f) => f.span(),
374 Self::ArrayAccess(a) => a.span(),
375 }
376 }
377}
378
379#[derive(Debug, Clone, PartialEq, Eq, Hash)]
381pub struct ConditionalExpr {
382 pub cond: Box<Expr>,
383 pub question_span: Span,
384 pub then_expr: Box<Expr>,
385 pub colon_span: Span,
386 pub else_expr: Box<Expr>,
387}
388
389impl ConditionalExpr {
390 pub fn span(&self) -> Span {
391 self.cond.span().join(self.else_expr.span())
392 }
393}
394
395#[derive(Debug, Clone, PartialEq, Eq, Hash)]
397pub struct LambdaExpr {
398 pub params: LambdaParams,
399 pub arrow_span: Span,
400 pub body: LambdaBody,
401 pub span: Span,
402}
403
404#[derive(Debug, Clone, PartialEq, Eq, Hash)]
406pub enum LambdaParams {
407 List {
409 paren_span: (Span, Span),
410 params: Vec<LambdaParam>,
411 },
412 IdentList {
414 paren_span: (Span, Span),
415 idents: Vec<Ident>,
416 },
417 Single(Ident),
419}
420
421#[derive(Debug, Clone, PartialEq, Eq, Hash)]
423pub struct LambdaParam {
424 pub modifiers: Vec<super::item::Modifier>,
425 pub ty: Type,
426 pub name: Ident,
427}
428
429#[derive(Debug, Clone, PartialEq, Eq, Hash)]
431pub enum LambdaBody {
432 Expr(Box<Expr>),
433 Block(Block),
434}
435
436impl LambdaBody {
437 pub fn span(&self) -> Span {
438 match self {
439 Self::Expr(e) => e.span(),
440 Self::Block(b) => b.span(),
441 }
442 }
443}
444
445#[derive(Debug, Clone, PartialEq, Eq, Hash)]
447pub struct SwitchExpr {
448 pub switch_span: Span,
449 pub paren_span: (Span, Span),
450 pub selector: Box<Expr>,
451 pub brace_span: (Span, Span),
452 pub cases: Vec<SwitchArm>,
453}
454
455impl SwitchExpr {
456 pub fn span(&self) -> Span {
457 self.switch_span.join(self.brace_span.1)
458 }
459}
460
461#[derive(Debug, Clone, PartialEq, Eq, Hash)]
463pub enum SwitchArm {
464 Expr(SwitchCase, Span, Expr),
466 Block(SwitchCase, Span, Block),
468 Throw(SwitchCase, Span, Expr),
470 Colon(SwitchCase, Vec<super::stmt::Stmt>),
472}
473
474impl SwitchArm {
475 pub fn span(&self) -> Span {
476 match self {
477 Self::Expr(case, _arrow, expr) => case.span().join(expr.span()),
478 Self::Block(case, _arrow, block) => case.span().join(block.brace_span.1),
479 Self::Throw(case, _arrow, expr) => case.span().join(expr.span()),
480 Self::Colon(case, stmts) => {
481 let end = stmts.last().map(|s| s.span()).unwrap_or(case.span());
482 case.span().join(end)
483 }
484 }
485 }
486}
487
488#[derive(Debug, Clone, PartialEq, Eq, Hash)]
490pub enum SwitchCase {
491 CaseValues { case_span: Span, values: Vec<Expr> },
493 CaseNull { case_span: Span, null_span: Span },
495 CaseNullDefault {
497 case_span: Span,
498 null_span: Span,
499 default_span: Span,
500 },
501 CasePattern {
503 case_span: Span,
504 pattern: Pattern,
505 guard: Box<Option<super::pat::Guard>>,
506 },
507 Default { default_span: Span },
509}
510
511impl SwitchCase {
512 pub fn span(&self) -> Span {
513 match self {
514 Self::CaseValues { case_span, values } => {
515 let end = values.last().map(|v| v.span()).unwrap_or(*case_span);
516 case_span.join(end)
517 }
518 Self::CaseNull {
519 case_span,
520 null_span,
521 } => case_span.join(*null_span),
522 Self::CaseNullDefault {
523 case_span,
524 default_span,
525 ..
526 } => case_span.join(*default_span),
527 Self::CasePattern {
528 case_span,
529 pattern,
530 guard,
531 } => {
532 let end = match guard.as_ref() {
533 Some(g) => g.expr.span(),
534 None => pattern.span(),
535 };
536 case_span.join(end)
537 }
538 Self::Default { default_span } => *default_span,
539 }
540 }
541}