forked from vincenthz/language-java
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSyntax.hs
More file actions
539 lines (470 loc) · 22.4 KB
/
Syntax.hs
File metadata and controls
539 lines (470 loc) · 22.4 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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
module Language.Java.Syntax
( CompilationUnit(..)
, PackageDecl(..)
, ImportDecl(..)
, TypeDecl(..)
, ClassDecl(..)
, ClassBody(..)
, EnumBody(..)
, EnumConstant(..)
, InterfaceDecl(..)
, InterfaceBody(..)
, InterfaceKind(..)
, Decl(..)
, MemberDecl(..)
, RecordFieldDecl(..)
, VarDecl(..)
, VarDeclId(..)
, VarInit(..)
, FormalParam(..)
, MethodBody(..)
, ConstructorBody(..)
, ExplConstrInv(..)
, Modifier(..)
, Annotation(..)
, desugarAnnotation
, desugarAnnotation'
, ElementValue(..)
, Block(..)
, BlockStmt(..)
, Stmt(..)
, Catch(..)
, TryResource(..)
, ResourceDecl(..)
, SwitchBlock(..)
, SwitchLabel(..)
, SwitchExpBranch(..)
, SwitchExpBranchBody(..)
, SwitchStyle(..)
, ForInit(..)
, ExceptionType
, Argument
, Exp(..)
, Lhs(..)
, ArrayIndex(..)
, FieldAccess(..)
, LambdaParams(..)
, LambdaExpression(..)
, ArrayInit(..)
, MethodInvocation(..)
, MethodRefTarget(..)
, Location(..)
, SourceSpan
, dummyLocation
, dummySourceSpan
, locationEof
, isEof
, module Language.Java.Syntax.Exp
, module Language.Java.Syntax.Types
) where
import Data.Data
import GHC.Generics (Generic)
import Language.Java.Syntax.Types
import Language.Java.Syntax.Exp
-----------------------------------------------------------------------
-- Packages
-- | A compilation unit is the top level syntactic goal symbol of a Java program.
data CompilationUnit = CompilationUnit (Maybe PackageDecl) [ImportDecl] [TypeDecl]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A package declaration appears within a compilation unit to indicate the package to which the compilation unit belongs.
newtype PackageDecl = PackageDecl Name
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An import declaration allows a static member or a named type to be referred to by a single unqualified identifier.
-- The first argument signals whether the declaration only imports static members.
-- The last argument signals whether the declaration brings all names in the named type or package, or only brings
-- a single name into scope.
data ImportDecl
= ImportDecl Bool {- static? -} Name Bool {- .*? -}
deriving (Eq,Show,Read,Typeable,Generic,Data)
-----------------------------------------------------------------------
-- Declarations
-- | A type declaration declares a class type or an interface type.
data TypeDecl
= ClassTypeDecl ClassDecl
| InterfaceTypeDecl InterfaceDecl
deriving (Eq,Show,Read,Typeable,Generic,Data)
type SourceSpan = (Location, Location)
data Location =
Location
{ loc_file :: FilePath
, loc_line :: Int
, loc_column :: Int
}
deriving (Eq,Show,Read,Typeable,Generic,Data)
dummyLocation :: Location
dummyLocation = Location "<input>" 1 1
dummySourceSpan :: SourceSpan
dummySourceSpan = (dummyLocation, dummyLocation)
locationEof :: Location
locationEof = Location "" 0 0
isEof :: Location -> Bool
isEof loc = loc == locationEof
-- | A class declaration specifies a new named reference type.
data ClassDecl
= ClassDecl SourceSpan [Modifier] Ident [TypeParam] (Maybe RefType) [RefType] ClassBody
| RecordDecl SourceSpan [Modifier] Ident [TypeParam] [RecordFieldDecl] [RefType] ClassBody
| EnumDecl SourceSpan [Modifier] Ident [RefType] EnumBody
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A class body may contain declarations of members of the class, that is,
-- fields, classes, interfaces and methods.
-- A class body may also contain instance initializers, static
-- initializers, and declarations of constructors for the class.
newtype ClassBody = ClassBody [Decl]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | The body of an enum type may contain enum constants.
data EnumBody = EnumBody [EnumConstant] [Decl]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An enum constant defines an instance of the enum type.
data EnumConstant = EnumConstant Ident [Argument] (Maybe ClassBody)
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An interface declaration introduces a new reference type whose members
-- are classes, interfaces, constants and abstract methods. This type has
-- no implementation, but otherwise unrelated classes can implement it by
-- providing implementations for its abstract methods.
data InterfaceDecl
= InterfaceDecl SourceSpan InterfaceKind [Modifier] Ident [TypeParam] [RefType] {- extends -} [RefType] {- permits -} InterfaceBody
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | Interface can declare either a normal interface or an annotation
data InterfaceKind = InterfaceNormal | InterfaceAnnotation
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | The body of an interface may declare members of the interface.
newtype InterfaceBody
= InterfaceBody [MemberDecl]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A declaration is either a member declaration, or a declaration of an
-- initializer, which may be static.
data Decl
= MemberDecl MemberDecl
| InitDecl Bool Block
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A class or interface member can be an inner class or interface, a field or
-- constant, or a method or constructor. An interface may only have as members
-- constants (not fields), abstract methods, and no constructors.
data MemberDecl
-- | The variables of a class type are introduced by field declarations.
= FieldDecl SourceSpan [Modifier] Type [VarDecl]
-- | A method declares executable code that can be invoked, passing a fixed number of values as arguments.
| MethodDecl SourceSpan [Modifier] [TypeParam] (Maybe Type) Ident [FormalParam] [ExceptionType] (Maybe Exp) MethodBody
-- | A constructor is used in the creation of an object that is an instance of a class.
| ConstructorDecl SourceSpan [Modifier] [TypeParam] Ident [FormalParam] [ExceptionType] ConstructorBody
-- | A member class is a class whose declaration is directly enclosed in another class or interface declaration.
| MemberClassDecl ClassDecl
-- | A member interface is an interface whose declaration is directly enclosed in another class or interface declaration.
| MemberInterfaceDecl InterfaceDecl
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A field declaration of a record
data RecordFieldDecl
= RecordFieldDecl Type Ident
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A declaration of a variable, which may be explicitly initialized.
data VarDecl
= VarDecl VarDeclId (Maybe VarInit)
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | The name of a variable in a declaration, which may be an array.
data VarDeclId
= VarId Ident
| VarDeclArray VarDeclId
-- ^ Multi-dimensional arrays are represented by nested applications of 'VarDeclArray'.
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | Explicit initializer for a variable declaration.
data VarInit
= InitExp Exp
| InitArray ArrayInit
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A formal parameter in method declaration. The last parameter
-- for a given declaration may be marked as variable arity,
-- indicated by the boolean argument.
data FormalParam = FormalParam [Modifier] Type Bool VarDeclId
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A method body is either a block of code that implements the method or simply a
-- semicolon, indicating the lack of an implementation (modelled by 'Nothing').
newtype MethodBody = MethodBody (Maybe Block)
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | The first statement of a constructor body may be an explicit invocation of
-- another constructor of the same class or of the direct superclass.
data ConstructorBody = ConstructorBody (Maybe ExplConstrInv) [BlockStmt]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An explicit constructor invocation invokes another constructor of the
-- same class, or a constructor of the direct superclass, which may
-- be qualified to explicitly specify the newly created object's immediately
-- enclosing instance.
data ExplConstrInv
= ThisInvoke [RefType] [Argument]
| SuperInvoke [RefType] [Argument]
| PrimarySuperInvoke Exp [RefType] [Argument]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A modifier specifying properties of a given declaration. In general only
-- a few of these modifiers are allowed for each declaration type, for instance
-- a member type declaration may only specify one of public, private or protected.
data Modifier
= Public
| Private
| Protected
| Abstract
| Final
| Static
| StrictFP
| Transient
| Volatile
| Native
| Annotation Annotation
| Synchronized_
| Sealed
deriving (Eq,Read,Typeable,Generic,Data)
instance Show Modifier where
show Public = "public"
show Private = "private"
show Protected = "protected"
show Abstract = "abstract"
show Final = "final"
show Static = "static"
show StrictFP = "strictfp"
show Transient = "transient"
show Volatile = "volatile"
show Native = "native"
show (Annotation a) = show a
show Synchronized_ = "synchronized"
show Sealed = "sealed"
-- | Annotations have three different forms: no-parameter, single-parameter or key-value pairs
data Annotation = NormalAnnotation { annName :: Name -- Not type because not type generics not allowed
, annKV :: [(Ident, ElementValue)] }
| SingleElementAnnotation { annName :: Name
, annValue:: ElementValue }
| MarkerAnnotation { annName :: Name }
deriving (Eq,Show,Read,Typeable,Generic,Data)
desugarAnnotation (MarkerAnnotation n) = (n, [])
desugarAnnotation (SingleElementAnnotation n e) = (n, [(Ident "value", e)])
desugarAnnotation (NormalAnnotation n kv) = (n, kv)
desugarAnnotation' = uncurry NormalAnnotation . desugarAnnotation
-- | Annotations may contain annotations or (loosely) expressions
data ElementValue = EVVal VarInit
| EVAnn Annotation
deriving (Eq,Show,Read,Typeable,Generic,Data)
-----------------------------------------------------------------------
-- Statements
-- | A block is a sequence of statements, local class declarations
-- and local variable declaration statements within braces.
data Block = Block [BlockStmt]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A block statement is either a normal statement, a local
-- class declaration or a local variable declaration.
data BlockStmt
= BlockStmt Stmt
| LocalClass ClassDecl
| LocalVars [Modifier] Type [VarDecl]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A Java statement.
data Stmt
-- | A statement can be a nested block.
= StmtBlock Block
-- | The @if-then@ statement allows conditional execution of a statement.
| IfThen Exp Stmt
-- | The @if-then-else@ statement allows conditional choice of two statements, executing one or the other but not both.
| IfThenElse Exp Stmt Stmt
-- | The @while@ statement executes an expression and a statement repeatedly until the value of the expression is false.
| While Exp Stmt
-- | The basic @for@ statement executes some initialization code, then executes an expression, a statement, and some
-- update code repeatedly until the value of the expression is false.
| BasicFor (Maybe ForInit) (Maybe Exp) (Maybe [Exp]) Stmt
-- | The enhanced @for@ statement iterates over an array or a value of a class that implements the @iterator@ interface.
| EnhancedFor [Modifier] Type Ident Exp Stmt
-- | An empty statement does nothing.
| Empty
-- | Certain kinds of expressions may be used as statements by following them with semicolons:
-- assignments, pre- or post-inc- or decrementation, method invocation or class instance
-- creation expressions.
| ExpStmt Exp
-- | An assertion is a statement containing a boolean expression, where an error is reported if the expression
-- evaluates to false.
| Assert Exp (Maybe Exp)
-- | The switch statement transfers control to one of several statements depending on the value of an expression.
| Switch SwitchStyle Exp [SwitchBlock]
-- | The @do@ statement executes a statement and an expression repeatedly until the value of the expression is false.
| Do Stmt Exp
-- | A @break@ statement transfers control out of an enclosing statement.
| Break (Maybe Ident)
-- | A @continue@ statement may occur only in a while, do, or for statement. Control passes to the loop-continuation
-- point of that statement.
| Continue (Maybe Ident)
-- A @return@ statement returns control to the invoker of a method or constructor.
| Return (Maybe Exp)
-- | A @synchronized@ statement acquires a mutual-exclusion lock on behalf of the executing thread, executes a block,
-- then releases the lock. While the executing thread owns the lock, no other thread may acquire the lock.
| Synchronized Exp Block
-- | A @throw@ statement causes an exception to be thrown.
| Throw Exp
-- | A try statement executes a block. If a value is thrown and the try statement has one or more catch clauses that
-- can catch it, then control will be transferred to the first such catch clause. If the try statement has a finally
-- clause, then another block of code is executed, no matter whether the try block completes normally or abruptly,
-- and no matter whether a catch clause is first given control.
| Try [TryResource] Block [Catch] (Maybe {- finally -} Block)
-- | Statements may have label prefixes.
| Labeled Ident Stmt
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | If a value is thrown and the try statement has one or more catch clauses that can catch it, then control will be
-- transferred to the first such catch clause.
data Catch = Catch FormalParam Block
deriving (Eq,Show,Read,Typeable,Generic,Data)
data TryResource
= TryResourceVarDecl ResourceDecl
| TryResourceVarAccess Ident
| TryResourceQualAccess FieldAccess
deriving (Eq,Show,Read,Typeable,Generic,Data)
data ResourceDecl =
ResourceDecl [Modifier] Type VarDeclId VarInit
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A block of code labelled with a @case@ or @default@ within a @switch@ statement.
data SwitchBlock
= SwitchBlock SwitchLabel [BlockStmt]
deriving (Eq,Show,Read,Typeable,Generic,Data)
data SwitchStyle
= SwitchOldStyle
| SwitchNewStyle -- JEP 361
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A label within a @switch@ statement.
data SwitchLabel
-- | The expressions contained in the @case@ must be a 'Lit' or an @enum@ constant.
-- The list must be non-empty.
= SwitchCase [Exp]
| Default
deriving (Eq,Show,Read,Typeable,Generic,Data)
data SwitchExpBranch
= SwitchExpBranch SwitchLabel SwitchExpBranchBody
deriving (Eq,Show,Read,Typeable,Generic,Data)
data SwitchExpBranchBody
= SwitchExpBranchExp Exp
| SwitchExpBranchBlock [BlockStmt]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | Initialization code for a basic @for@ statement.
data ForInit
= ForLocalVars [Modifier] Type [VarDecl]
| ForInitExps [Exp]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An exception type has to be a class type or a type variable.
type ExceptionType = RefType -- restricted to ClassType or TypeVariable
-- | Arguments to methods and constructors are expressions.
type Argument = Exp
-- | A Java expression.
data Exp
-- | A literal denotes a fixed, unchanging value.
= Lit Literal
-- | A class literal, which is an expression consisting of the name of a class, interface, array,
-- or primitive type, or the pseudo-type void (modelled by 'Nothing'), followed by a `.' and the token class.
| ClassLit (Maybe Type)
-- | The keyword @this@ denotes a value that is a reference to the object for which the instance method
-- was invoked, or to the object being constructed.
| This
-- | Any lexically enclosing instance can be referred to by explicitly qualifying the keyword this.
| ThisClass Name
-- | A class instance creation expression is used to create new objects that are instances of classes.
-- | The first argument is a list of non-wildcard type arguments to a generic constructor.
-- What follows is the type to be instantiated, the list of arguments passed to the constructor, and
-- optionally a class body that makes the constructor result in an object of an /anonymous/ class.
| InstanceCreation [TypeArgument] TypeDeclSpecifier [Argument] (Maybe ClassBody)
-- | A qualified class instance creation expression enables the creation of instances of inner member classes
-- and their anonymous subclasses.
| QualInstanceCreation Exp [TypeArgument] Ident [Argument] (Maybe ClassBody)
-- | An array instance creation expression is used to create new arrays. The last argument denotes the number
-- of dimensions that have no explicit length given. These dimensions must be given last.
| ArrayCreate Type [Exp] Int
-- | An array instance creation expression may come with an explicit initializer. Such expressions may not
-- be given explicit lengths for any of its dimensions.
| ArrayCreateInit Type Int ArrayInit
-- | A field access expression.
| FieldAccess FieldAccess
-- | A method invocation expression.
| MethodInv MethodInvocation
-- | An array access expression refers to a variable that is a component of an array.
| ArrayAccess ArrayIndex
{- | ArrayAccess Exp Exp -- Should this be made into a datatype, for consistency and use with Lhs? -}
-- | An expression name, e.g. a variable.
| ExpName Name
-- | Post-incrementation expression, i.e. an expression followed by @++@.
| PostIncrement Exp
-- | Post-decrementation expression, i.e. an expression followed by @--@.
| PostDecrement Exp
-- | Pre-incrementation expression, i.e. an expression preceded by @++@.
| PreIncrement Exp
-- | Pre-decrementation expression, i.e. an expression preceded by @--@.
| PreDecrement Exp
-- | Unary plus, the promotion of the value of the expression to a primitive numeric type.
| PrePlus Exp
-- | Unary minus, the promotion of the negation of the value of the expression to a primitive numeric type.
| PreMinus Exp
-- | Unary bitwise complementation: note that, in all cases, @~x@ equals @(-x)-1@.
| PreBitCompl Exp
-- | Logical complementation of boolean values.
| PreNot Exp
-- | A cast expression converts, at run time, a value of one numeric type to a similar value of another
-- numeric type; or confirms, at compile time, that the type of an expression is boolean; or checks,
-- at run time, that a reference value refers to an object whose class is compatible with a specified
-- reference type.
| Cast Type Exp
-- | The application of a binary operator to two operand expressions.
| BinOp Exp Op Exp
-- | Testing whether the result of an expression is an instance of some reference type.
| InstanceOf Exp RefType (Maybe Name)
-- | The conditional operator @? :@ uses the boolean value of one expression to decide which of two other
-- expressions should be evaluated.
| Cond Exp Exp Exp
-- | Assignment of the result of an expression to a variable.
| Assign Lhs AssignOp Exp
-- | Lambda expression
| Lambda LambdaParams LambdaExpression
-- | Method reference
| MethodRef Name MethodRefTarget
-- | New-style switch expression (JEP 361)
| SwitchExp Exp [SwitchExpBranch]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | The left-hand side of an assignment expression. This operand may be a named variable, such as a local
-- variable or a field of the current object or class, or it may be a computed variable, as can result from
-- a field access or an array access.
data Lhs
= NameLhs Name -- ^ Assign to a variable
| FieldLhs FieldAccess -- ^ Assign through a field access
| ArrayLhs ArrayIndex -- ^ Assign to an array
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | Array access
data ArrayIndex = ArrayIndex Exp [Exp] -- ^ Index into an array
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A field access expression may access a field of an object or array, a reference to which is the value
-- of either an expression or the special keyword super.
data FieldAccess
= PrimaryFieldAccess Exp Ident -- ^ Accessing a field of an object or array computed from an expression.
| SuperFieldAccess Ident -- ^ Accessing a field of the superclass.
| ClassFieldAccess Name Ident -- ^ Accessing a (static) field of a named class.
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- ¦ A lambda parameter can be a single parameter, or mulitple formal or mulitple inferred parameters
data LambdaParams
= LambdaSingleParam Ident
| LambdaFormalParams [FormalParam]
| LambdaInferredParams [Ident]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | Lambda expression, starting from java 8
data LambdaExpression
= LambdaExpression Exp
| LambdaBlock Block
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | A method invocation expression is used to invoke a class or instance method.
data MethodInvocation
-- | Invoking a specific named method.
= MethodCall Name [Argument]
-- | Invoking a method of a class computed from a primary expression, giving arguments for any generic type parameters.
| PrimaryMethodCall Exp [RefType] Ident [Argument]
-- | Invoking a method of the super class, giving arguments for any generic type parameters.
| SuperMethodCall [RefType] Ident [Argument]
-- | Invoking a method of the superclass of a named class, giving arguments for any generic type parameters.
| ClassMethodCall Name [RefType] Ident [Argument]
-- | Invoking a method of a named type, giving arguments for any generic type parameters.
| TypeMethodCall Name [RefType] Ident [Argument]
deriving (Eq,Show,Read,Typeable,Generic,Data)
-- | An array initializer may be specified in a declaration, or as part of an array creation expression, creating an
-- array and providing some initial values
data ArrayInit
= ArrayInit [VarInit]
deriving (Eq,Show,Read,Typeable,Generic,Data)
data MethodRefTarget
= MethodRefIdent Ident
| MethodRefConstructor
deriving (Eq,Show,Read,Typeable,Generic,Data)