{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-} module Language.Java.Syntax ( CompilationUnit(..) , PackageDecl(..) , ImportDecl(..) , TypeDecl(..) , ClassDecl(..) , ClassBody(..) , EnumBody(..) , EnumConstant(..) , InterfaceDecl(..) , InterfaceBody(..) , InterfaceKind(..) , Decl(..) , MemberDecl(..) , VarDecl(..) , VarDeclId(..) , VarInit(..) , FormalParam(..) , MethodBody(..) , ConstructorBody(..) , ExplConstrInv(..) , Modifier(..) , Annotation(..) , desugarAnnotation , desugarAnnotation' , ElementValue(..) , Block(..) , BlockStmt(..) , Stmt(..) , Catch(..) , SwitchBlock(..) , SwitchLabel(..) , ForInit(..) , ExceptionType , Argument , Exp(..) , Lhs(..) , ArrayIndex(..) , FieldAccess(..) , LambdaParams(..) , LambdaExpression(..) , ArrayInit(..) , MethodInvocation(..) , 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) -- | A class declaration specifies a new named reference type. data ClassDecl = ClassDecl [Modifier] Ident [TypeParam] (Maybe RefType) [RefType] ClassBody | EnumDecl [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 InterfaceKind [Modifier] Ident [TypeParam] [RefType] 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 [Modifier] Type [VarDecl] -- | A method declares executable code that can be invoked, passing a fixed number of values as arguments. | MethodDecl [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 [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 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_ 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" -- | 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 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 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) -- | 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) -- | A label within a @switch@ statement. data SwitchLabel -- | The expression contained in the @case@ must be a 'Lit' or an @enum@ constant. = SwitchCase Exp | Default 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 -- | 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 Ident 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)