hydra-0.1.0: src/main/haskell/Hydra/Ext/Java/Utils.hs
module Hydra.Ext.Java.Utils where
import Hydra.All
import qualified Hydra.Ext.Java.Syntax as Java
import qualified Hydra.Lib.Strings as Strings
import Hydra.Adapters.Coders
import Hydra.Ext.Java.Language
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y
addExpressions :: [Java.MultiplicativeExpression] -> Java.AdditiveExpression
addExpressions exprs = L.foldl add (Java.AdditiveExpressionUnary $ L.head exprs) $ L.tail exprs
where
add ae me = Java.AdditiveExpressionPlus $ Java.AdditiveExpression_Binary ae me
addJavaTypeParameter :: Java.ReferenceType -> Java.Type -> GraphFlow m Java.Type
addJavaTypeParameter rt t = case t of
Java.TypeReference (Java.ReferenceTypeClassOrInterface cit) -> case cit of
Java.ClassOrInterfaceTypeClass (Java.ClassType anns qual id args) -> pure $
Java.TypeReference $ Java.ReferenceTypeClassOrInterface $
Java.ClassOrInterfaceTypeClass $ Java.ClassType anns qual id (args ++ [Java.TypeArgumentReference rt])
_ -> fail $ "expected a Java class type. Found: " ++ show cit
_ -> fail $ "expected a Java class or interface type. Found: " ++ show t
fieldExpression :: Java.Identifier -> Java.Identifier -> Java.ExpressionName
fieldExpression varId fieldId = Java.ExpressionName (Just $ Java.AmbiguousName [varId]) fieldId
fieldNameToJavaExpression :: FieldName -> Java.Expression
fieldNameToJavaExpression fname = javaPostfixExpressionToJavaExpression $
Java.PostfixExpressionName $ Java.ExpressionName Nothing (fieldNameToJavaIdentifier fname)
fieldNameToJavaIdentifier :: FieldName -> Java.Identifier
fieldNameToJavaIdentifier (FieldName name) = javaIdentifier name
fieldNameToJavaVariableDeclarator :: FieldName -> Java.VariableDeclarator
fieldNameToJavaVariableDeclarator (FieldName n) = javaVariableDeclarator (javaIdentifier n) Nothing
fieldNameToJavaVariableDeclaratorId :: FieldName -> Java.VariableDeclaratorId
fieldNameToJavaVariableDeclaratorId (FieldName n) = javaVariableDeclaratorId $ javaIdentifier n
importAliasesForModule :: Module m -> M.Map Namespace Java.PackageName
importAliasesForModule mod = addName (L.foldl addName M.empty $ S.toList deps) $ moduleNamespace mod
where
deps = moduleDependencyNamespaces True True True mod
addName m name = M.insert name (moduleNamespaceToPackageName name) m
moduleNamespaceToPackageName (Namespace n) = javaPackageName $ Strings.splitOn "/" n
interfaceMethodDeclaration :: [Java.InterfaceMethodModifier] -> [Java.TypeParameter] -> String -> [Java.FormalParameter]
-> Java.Result -> Maybe [Java.BlockStatement] -> Java.InterfaceMemberDeclaration
interfaceMethodDeclaration mods tparams methodName params result stmts = Java.InterfaceMemberDeclarationInterfaceMethod $
Java.InterfaceMethodDeclaration mods header body
where
header = javaMethodHeader tparams methodName params result
body = javaMethodBody stmts
javaAssignmentStatement :: Java.LeftHandSide -> Java.Expression -> Java.Statement
javaAssignmentStatement lhs rhs = Java.StatementWithoutTrailing $ Java.StatementWithoutTrailingSubstatementExpression $
Java.ExpressionStatement $ Java.StatementExpressionAssignment ass
where
ass = Java.Assignment lhs Java.AssignmentOperatorSimple rhs
javaBoolean :: Bool -> Java.Literal
javaBoolean = Java.LiteralBoolean
javaBooleanExpression :: Bool -> Java.Expression
javaBooleanExpression = javaPrimaryToJavaExpression . javaLiteralToPrimary . javaBoolean
javaBooleanType :: Java.Type
javaBooleanType = javaPrimitiveTypeToJavaType Java.PrimitiveTypeBoolean
javaCastExpression :: M.Map Namespace Java.PackageName -> Java.ReferenceType -> Java.UnaryExpression -> Java.CastExpression
javaCastExpression aliases rt expr = Java.CastExpressionNotPlusMinus $ Java.CastExpression_NotPlusMinus rb expr
where
rb = Java.CastExpression_RefAndBounds rt []
javaCastExpressionToJavaExpression :: Java.CastExpression -> Java.Expression
javaCastExpressionToJavaExpression = javaUnaryExpressionToJavaExpression . Java.UnaryExpressionOther .
Java.UnaryExpressionNotPlusMinusCast
javaClassDeclaration :: M.Map Namespace Java.PackageName -> [Java.TypeParameter] -> Name -> [Java.ClassModifier]
-> Maybe Name -> [Java.ClassBodyDeclarationWithComments] -> Java.ClassDeclaration
javaClassDeclaration aliases tparams elName mods supname bodyDecls = Java.ClassDeclarationNormal $ Java.NormalClassDeclaration {
Java.normalClassDeclarationModifiers = mods,
Java.normalClassDeclarationIdentifier = javaDeclName elName,
Java.normalClassDeclarationParameters = tparams,
Java.normalClassDeclarationExtends = fmap (\n -> nameToJavaClassType aliases True [] n Nothing) supname,
Java.normalClassDeclarationImplements = [],
Java.normalClassDeclarationBody = Java.ClassBody bodyDecls}
javaClassType :: [Java.ReferenceType] -> Maybe Java.PackageName -> String -> Java.ClassType
javaClassType args pkg id = Java.ClassType [] qual (javaTypeIdentifier id) targs
where
qual = maybe Java.ClassTypeQualifierNone Java.ClassTypeQualifierPackage pkg
targs = Java.TypeArgumentReference <$> args
javaClassTypeToJavaType :: Java.ClassType -> Java.Type
javaClassTypeToJavaType = Java.TypeReference . Java.ReferenceTypeClassOrInterface . Java.ClassOrInterfaceTypeClass
javaConditionalAndExpressionToJavaExpression :: Java.ConditionalAndExpression -> Java.Expression
javaConditionalAndExpressionToJavaExpression condAndEx = Java.ExpressionAssignment $
Java.AssignmentExpressionConditional $ Java.ConditionalExpressionSimple $ Java.ConditionalOrExpression [condAndEx]
javaConstructorCall :: Java.ClassOrInterfaceTypeToInstantiate -> [Java.Expression] -> Maybe Java.ClassBody -> Java.Expression
javaConstructorCall ci args mbody = javaPrimaryToJavaExpression $
Java.PrimaryNoNewArray $
Java.PrimaryNoNewArrayClassInstance $
Java.ClassInstanceCreationExpression Nothing $
Java.UnqualifiedClassInstanceCreationExpression [] ci args mbody
javaConstructorName :: Java.Identifier -> Maybe Java.TypeArgumentsOrDiamond -> Java.ClassOrInterfaceTypeToInstantiate
javaConstructorName id targs = Java.ClassOrInterfaceTypeToInstantiate [Java.AnnotatedIdentifier [] id] targs
javaDeclName :: Name -> Java.TypeIdentifier
javaDeclName = Java.TypeIdentifier . javaVariableName
javaEmptyStatement :: Java.Statement
javaEmptyStatement = Java.StatementWithoutTrailing $ Java.StatementWithoutTrailingSubstatementEmpty Java.EmptyStatement
javaEqualityExpressionToJavaInclusiveOrExpression :: Java.EqualityExpression -> Java.InclusiveOrExpression
javaEqualityExpressionToJavaInclusiveOrExpression eq = Java.InclusiveOrExpression [
Java.ExclusiveOrExpression [Java.AndExpression [eq]]]
javaExpressionNameToJavaExpression :: Java.ExpressionName -> Java.Expression
javaExpressionNameToJavaExpression = javaPostfixExpressionToJavaExpression . Java.PostfixExpressionName
javaExpressionToJavaPrimary :: Java.Expression -> Java.Primary
javaExpressionToJavaPrimary = Java.PrimaryNoNewArray . Java.PrimaryNoNewArrayParens
javaExpressionToJavaUnaryExpression :: Java.Expression -> Java.UnaryExpression
javaExpressionToJavaUnaryExpression = javaPrimaryToJavaUnaryExpression . javaExpressionToJavaPrimary
javaFieldAccessToJavaExpression :: Java.FieldAccess -> Java.Expression
javaFieldAccessToJavaExpression = javaPrimaryToJavaExpression . Java.PrimaryNoNewArray . Java.PrimaryNoNewArrayFieldAccess
javaIdentifier :: String -> Java.Identifier
javaIdentifier = Java.Identifier . sanitizeJavaName
javaIdentifierToJavaExpression :: Java.Identifier -> Java.Expression
javaIdentifierToJavaExpression = javaUnaryExpressionToJavaExpression . javaIdentifierToJavaUnaryExpression
javaIdentifierToJavaRelationalExpression :: Java.Identifier -> Java.RelationalExpression
javaIdentifierToJavaRelationalExpression id = javaPostfixExpressionToJavaRelationalExpression $
Java.PostfixExpressionName $ Java.ExpressionName Nothing id
javaIdentifierToJavaUnaryExpression :: Java.Identifier -> Java.UnaryExpression
javaIdentifierToJavaUnaryExpression = javaRelationalExpressionToJavaUnaryExpression . javaIdentifierToJavaRelationalExpression
javaInstanceOf :: Java.RelationalExpression -> Java.ReferenceType -> Java.RelationalExpression
javaInstanceOf lhs rhs = Java.RelationalExpressionInstanceof $ Java.RelationalExpression_InstanceOf lhs rhs
javaInt :: Integral a => a -> Java.Literal
javaInt i = Java.LiteralInteger $ Java.IntegerLiteral $ fromIntegral i
javaIntExpression :: Integer -> Java.Expression
javaIntExpression = javaPrimaryToJavaExpression . javaLiteralToPrimary . javaInt
javaIntType :: Java.Type
javaIntType = javaPrimitiveTypeToJavaType $ Java.PrimitiveTypeNumeric $ Java.NumericTypeIntegral Java.IntegralTypeInt
javaInterfaceDeclarationToJavaClassBodyDeclaration :: Java.NormalInterfaceDeclaration -> Java.ClassBodyDeclaration
javaInterfaceDeclarationToJavaClassBodyDeclaration = Java.ClassBodyDeclarationClassMember .
Java.ClassMemberDeclarationInterface . Java.InterfaceDeclarationNormalInterface
javaLambda :: Variable -> Java.Expression -> Java.Expression
javaLambda var jbody = Java.ExpressionLambda $ Java.LambdaExpression params (Java.LambdaBodyExpression jbody)
where
params = Java.LambdaParametersSingle $ variableToJavaIdentifier var
javaLangPackageName :: Maybe Java.PackageName
javaLangPackageName = Just $ javaPackageName ["java", "lang"]
javaLiteralToJavaExpression = javaRelationalExpressionToJavaExpression .
javaMultiplicativeExpressionToJavaRelationalExpression .
javaLiteralToJavaMultiplicativeExpression
javaLiteralToJavaMultiplicativeExpression = Java.MultiplicativeExpressionUnary . javaPrimaryToJavaUnaryExpression .
javaLiteralToPrimary
javaLiteralToPrimary :: Java.Literal -> Java.Primary
javaLiteralToPrimary = Java.PrimaryNoNewArray . Java.PrimaryNoNewArrayLiteral
javaMemberField :: [Java.FieldModifier] -> Java.Type -> Java.VariableDeclarator -> Java.ClassBodyDeclaration
javaMemberField mods jt var = Java.ClassBodyDeclarationClassMember $ Java.ClassMemberDeclarationField $
Java.FieldDeclaration mods (Java.UnannType jt) [var]
javaMethodBody :: Maybe [Java.BlockStatement] -> Java.MethodBody
javaMethodBody stmts = Y.maybe Java.MethodBodyNone (Java.MethodBodyBlock . Java.Block) stmts
javaMethodDeclarationToJavaClassBodyDeclaration :: Java.MethodDeclaration -> Java.ClassBodyDeclaration
javaMethodDeclarationToJavaClassBodyDeclaration = Java.ClassBodyDeclarationClassMember . Java.ClassMemberDeclarationMethod
javaMethodHeader :: [Java.TypeParameter] -> String -> [Java.FormalParameter] -> Java.Result -> Java.MethodHeader
javaMethodHeader tparams methodName params result = Java.MethodHeader tparams result decl mthrows
where
decl = Java.MethodDeclarator (Java.Identifier methodName) Nothing params
mthrows = Nothing
javaMethodInvocationToJavaExpression :: Java.MethodInvocation -> Java.Expression
javaMethodInvocationToJavaExpression = javaPrimaryToJavaExpression . javaMethodInvocationToJavaPrimary
javaMethodInvocationToJavaPostfixExpression :: Java.MethodInvocation -> Java.PostfixExpression
javaMethodInvocationToJavaPostfixExpression = Java.PostfixExpressionPrimary . Java.PrimaryNoNewArray .
Java.PrimaryNoNewArrayMethodInvocation
javaMethodInvocationToJavaPrimary :: Java.MethodInvocation -> Java.Primary
javaMethodInvocationToJavaPrimary = Java.PrimaryNoNewArray .
Java.PrimaryNoNewArrayMethodInvocation
javaMultiplicativeExpressionToJavaRelationalExpression :: Java.MultiplicativeExpression -> Java.RelationalExpression
javaMultiplicativeExpressionToJavaRelationalExpression = Java.RelationalExpressionSimple .
Java.ShiftExpressionUnary . Java.AdditiveExpressionUnary
javaPackageDeclaration :: Namespace -> Java.PackageDeclaration
javaPackageDeclaration (Namespace name) = Java.PackageDeclaration [] (Java.Identifier <$> Strings.splitOn "/" name)
javaPackageName :: [String] -> Java.PackageName
javaPackageName parts = Java.PackageName (Java.Identifier <$> parts)
javaPostfixExpressionToJavaEqualityExpression :: Java.PostfixExpression -> Java.EqualityExpression
javaPostfixExpressionToJavaEqualityExpression = Java.EqualityExpressionUnary .
javaUnaryExpressionToJavaRelationalExpression . Java.UnaryExpressionOther . Java.UnaryExpressionNotPlusMinusPostfix
javaPostfixExpressionToJavaExpression :: Java.PostfixExpression -> Java.Expression
javaPostfixExpressionToJavaExpression = javaRelationalExpressionToJavaExpression .
javaPostfixExpressionToJavaRelationalExpression
javaPostfixExpressionToJavaInclusiveOrExpression :: Java.PostfixExpression -> Java.InclusiveOrExpression
javaPostfixExpressionToJavaInclusiveOrExpression = javaEqualityExpressionToJavaInclusiveOrExpression .
javaPostfixExpressionToJavaEqualityExpression
javaPostfixExpressionToJavaRelationalExpression :: Java.PostfixExpression -> Java.RelationalExpression
javaPostfixExpressionToJavaRelationalExpression =
javaUnaryExpressionToJavaRelationalExpression . javaPostfixExpressionToJavaUnaryExpression
javaPostfixExpressionToJavaUnaryExpression :: Java.PostfixExpression -> Java.UnaryExpression
javaPostfixExpressionToJavaUnaryExpression = Java.UnaryExpressionOther . Java.UnaryExpressionNotPlusMinusPostfix
javaPrimaryToJavaExpression :: Java.Primary -> Java.Expression
javaPrimaryToJavaExpression = javaPostfixExpressionToJavaExpression . Java.PostfixExpressionPrimary
javaPrimaryToJavaUnaryExpression :: Java.Primary -> Java.UnaryExpression
javaPrimaryToJavaUnaryExpression = Java.UnaryExpressionOther .
Java.UnaryExpressionNotPlusMinusPostfix .
Java.PostfixExpressionPrimary
javaPrimitiveTypeToJavaType :: Java.PrimitiveType -> Java.Type
javaPrimitiveTypeToJavaType pt = Java.TypePrimitive $ Java.PrimitiveTypeWithAnnotations pt []
javaRefType :: [Java.ReferenceType] -> Maybe Java.PackageName -> String -> Java.Type
javaRefType args pkg id = Java.TypeReference $ Java.ReferenceTypeClassOrInterface $ Java.ClassOrInterfaceTypeClass $
javaClassType args pkg id
javaRelationalExpressionToJavaExpression :: Java.RelationalExpression -> Java.Expression
javaRelationalExpressionToJavaExpression relEx = javaConditionalAndExpressionToJavaExpression $
Java.ConditionalAndExpression [javaEqualityExpressionToJavaInclusiveOrExpression $ Java.EqualityExpressionUnary relEx]
javaRelationalExpressionToJavaUnaryExpression :: Java.RelationalExpression -> Java.UnaryExpression
javaRelationalExpressionToJavaUnaryExpression = javaPrimaryToJavaUnaryExpression .
Java.PrimaryNoNewArray .
Java.PrimaryNoNewArrayParens .
javaRelationalExpressionToJavaExpression
javaReturnStatement :: Y.Maybe Java.Expression -> Java.Statement
javaReturnStatement mex = Java.StatementWithoutTrailing $ Java.StatementWithoutTrailingSubstatementReturn $
Java.ReturnStatement mex
javaStatementsToBlock :: [Java.Statement] -> Java.Block
javaStatementsToBlock stmts = Java.Block (Java.BlockStatementStatement <$> stmts)
javaString :: String -> Java.Literal
javaString = Java.LiteralString . Java.StringLiteral
javaStringMultiplicativeExpression :: String -> Java.MultiplicativeExpression
javaStringMultiplicativeExpression = javaLiteralToJavaMultiplicativeExpression . javaString
javaThis :: Java.Expression
javaThis = javaPrimaryToJavaExpression $ Java.PrimaryNoNewArray Java.PrimaryNoNewArrayThis
javaTypeIdentifier :: String -> Java.TypeIdentifier
javaTypeIdentifier = Java.TypeIdentifier . Java.Identifier
javaTypeName :: Java.Identifier -> Java.TypeName
javaTypeName id = Java.TypeName (Java.TypeIdentifier id) Nothing
javaTypeParameter :: String -> Java.TypeParameter
javaTypeParameter v = Java.TypeParameter [] (javaTypeIdentifier v) Nothing
javaTypeVariable :: String -> Java.ReferenceType
javaTypeVariable v = Java.ReferenceTypeVariable $ Java.TypeVariable [] $ javaTypeIdentifier $ capitalize v
javaTypeVariableToType :: Java.TypeVariable -> Java.Type
javaTypeVariableToType = Java.TypeReference . Java.ReferenceTypeVariable
javaUtilFunctionPackageName :: Maybe Java.PackageName
javaUtilFunctionPackageName = Just $ javaPackageName ["java", "util", "function"]
javaUtilPackageName :: Maybe Java.PackageName
javaUtilPackageName = Just $ javaPackageName ["java", "util"]
javaTypeToJavaFormalParameter :: Java.Type -> FieldName -> Java.FormalParameter
javaTypeToJavaFormalParameter jt fname = Java.FormalParameterSimple $ Java.FormalParameter_Simple [] argType argId
where
argType = Java.UnannType jt
argId = fieldNameToJavaVariableDeclaratorId fname
javaTypeToJavaReferenceType :: Java.Type -> GraphFlow m Java.ReferenceType
javaTypeToJavaReferenceType t = case t of
Java.TypeReference rt -> pure rt
_ -> fail $ "expected a Java reference type. Found: " ++ show t
javaTypeToJavaResult :: Java.Type -> Java.Result
javaTypeToJavaResult = Java.ResultType . Java.UnannType
javaTypeToJavaTypeArgument :: Java.Type -> Java.TypeArgument
javaTypeToJavaTypeArgument t = case t of
Java.TypeReference rt -> Java.TypeArgumentReference rt
_ -> Java.TypeArgumentWildcard $ Java.Wildcard [] Nothing -- TODO
javaUnaryExpressionToJavaExpression :: Java.UnaryExpression -> Java.Expression
javaUnaryExpressionToJavaExpression = javaRelationalExpressionToJavaExpression .
javaUnaryExpressionToJavaRelationalExpression
javaUnaryExpressionToJavaRelationalExpression :: Java.UnaryExpression -> Java.RelationalExpression
javaUnaryExpressionToJavaRelationalExpression = javaMultiplicativeExpressionToJavaRelationalExpression .
Java.MultiplicativeExpressionUnary
javaVariableDeclarator :: Java.Identifier -> Y.Maybe Java.VariableInitializer -> Java.VariableDeclarator
javaVariableDeclarator id = Java.VariableDeclarator (javaVariableDeclaratorId id)
javaAdditiveExpressionToJavaExpression :: Java.AdditiveExpression -> Java.Expression
javaAdditiveExpressionToJavaExpression = javaRelationalExpressionToJavaExpression .
Java.RelationalExpressionSimple . Java.ShiftExpressionUnary
javaVariableDeclaratorId :: Java.Identifier -> Java.VariableDeclaratorId
javaVariableDeclaratorId id = Java.VariableDeclaratorId id Nothing
javaVariableName :: Name -> Java.Identifier
javaVariableName = javaIdentifier . localNameOfEager
makeConstructor :: M.Map Namespace Java.PackageName -> Name -> Bool -> [Java.FormalParameter]
-> [Java.BlockStatement] -> Java.ClassBodyDeclaration
makeConstructor aliases elName private params stmts = Java.ClassBodyDeclarationConstructorDeclaration $
Java.ConstructorDeclaration mods cons Nothing body
where
nm = Java.SimpleTypeName $ nameToJavaTypeIdentifier aliases False elName
cons = Java.ConstructorDeclarator [] nm Nothing params
mods = [if private then Java.ConstructorModifierPrivate else Java.ConstructorModifierPublic]
body = Java.ConstructorBody Nothing stmts
methodDeclaration :: [Java.MethodModifier] -> [Java.TypeParameter] -> [Java.Annotation] -> String
-> [Java.FormalParameter] -> Java.Result -> Maybe [Java.BlockStatement] -> Java.ClassBodyDeclaration
methodDeclaration mods tparams anns methodName params result stmts =
javaMethodDeclarationToJavaClassBodyDeclaration $
Java.MethodDeclaration anns mods header body
where
header = javaMethodHeader tparams methodName params result
body = javaMethodBody stmts
methodInvocation :: Y.Maybe (Either Java.ExpressionName Java.Primary) -> Java.Identifier -> [Java.Expression] -> Java.MethodInvocation
methodInvocation lhs methodName = Java.MethodInvocation header
where
header = case lhs of
Nothing -> Java.MethodInvocation_HeaderSimple $ Java.MethodName methodName
Just either -> Java.MethodInvocation_HeaderComplex $ Java.MethodInvocation_Complex variant targs methodName
where
targs = []
variant = case either of
Left name -> Java.MethodInvocation_VariantExpression name
Right prim -> Java.MethodInvocation_VariantPrimary prim
methodInvocationStatic :: Java.Identifier -> Java.Identifier -> [Java.Expression] -> Java.MethodInvocation
methodInvocationStatic self methodName = methodInvocation (Just $ Left name) methodName
where
name = Java.ExpressionName Nothing self
nameToJavaClassType :: M.Map Namespace Java.PackageName -> Bool -> [Java.TypeArgument] -> Name -> Maybe String -> Java.ClassType
nameToJavaClassType aliases qualify args name mlocal = Java.ClassType [] pkg id args
where
(id, pkg) = nameToQualifiedJavaName aliases qualify name mlocal
nameToQualifiedJavaName :: M.Map Namespace Java.PackageName -> Bool -> Name -> Maybe String
-> (Java.TypeIdentifier, Java.ClassTypeQualifier)
nameToQualifiedJavaName aliases qualify name mlocal = (jid, pkg)
where
(gname, local) = toQnameEager name
pkg = if qualify
then Y.maybe none Java.ClassTypeQualifierPackage $ M.lookup gname aliases
else none
none = Java.ClassTypeQualifierNone
jid = javaTypeIdentifier $ case mlocal of
Nothing -> sanitizeJavaName local
Just l -> sanitizeJavaName local ++ "." ++ sanitizeJavaName l
nameToJavaName :: M.Map Namespace Java.PackageName -> Name -> Java.Identifier
nameToJavaName aliases name = Java.Identifier $ case M.lookup gname aliases of
Nothing -> local
Just (Java.PackageName parts) -> L.intercalate "." $ (Java.unIdentifier <$> parts) ++ [sanitizeJavaName local]
where
(gname, local) = toQnameEager name
nameToJavaReferenceType :: M.Map Namespace Java.PackageName -> Bool -> Name -> Maybe String -> Java.ReferenceType
nameToJavaReferenceType aliases qualify name mlocal = Java.ReferenceTypeClassOrInterface $ Java.ClassOrInterfaceTypeClass $
nameToJavaClassType aliases qualify [] name mlocal
nameToJavaTypeIdentifier :: M.Map Namespace Java.PackageName -> Bool -> Name -> Java.TypeIdentifier
nameToJavaTypeIdentifier aliases qualify name = fst $ nameToQualifiedJavaName aliases qualify name Nothing
overrideAnnotation :: Java.Annotation
overrideAnnotation = Java.AnnotationMarker $ Java.MarkerAnnotation $ javaTypeName $ Java.Identifier "Override"
referenceTypeToResult :: Java.ReferenceType -> Java.Result
referenceTypeToResult = javaTypeToJavaResult . Java.TypeReference
sanitizeJavaName :: String -> String
sanitizeJavaName name = if L.head name == '$'
-- The '$' prefix allows names to be excluded from sanitization
then L.tail name
else sanitizeWithUnderscores reservedWords name
toAcceptMethod :: Bool -> Java.ClassBodyDeclaration
toAcceptMethod abstract = methodDeclaration mods tparams anns "accept" [param] result body
where
mods = [Java.MethodModifierPublic] ++ if abstract then [Java.MethodModifierAbstract] else []
tparams = [javaTypeParameter "R"]
anns = if abstract
then []
else [overrideAnnotation]
param = javaTypeToJavaFormalParameter ref (FieldName varName)
where
ref = javaClassTypeToJavaType $
Java.ClassType
[]
Java.ClassTypeQualifierNone
(javaTypeIdentifier "Visitor")
[Java.TypeArgumentReference visitorTypeVariable]
result = javaTypeToJavaResult $ Java.TypeReference visitorTypeVariable
varName = "visitor"
visitMethodName = Java.Identifier "visit"
body = if abstract
then Nothing
else Just [Java.BlockStatementStatement $ javaReturnStatement $ Just returnExpr]
returnExpr = javaMethodInvocationToJavaExpression $
methodInvocationStatic (Java.Identifier varName) visitMethodName [javaThis]
toAssignStmt :: FieldName -> Java.Statement
toAssignStmt fname = javaAssignmentStatement lhs rhs
where
lhs = Java.LeftHandSideFieldAccess $ thisField id
where
id = fieldNameToJavaIdentifier fname
rhs = fieldNameToJavaExpression fname
thisField = Java.FieldAccess $ Java.FieldAccess_QualifierPrimary $ Java.PrimaryNoNewArray Java.PrimaryNoNewArrayThis
toJavaArrayType :: Java.Type -> GraphFlow m Java.Type
toJavaArrayType t = Java.TypeReference . Java.ReferenceTypeArray <$> case t of
Java.TypeReference rt -> case rt of
Java.ReferenceTypeClassOrInterface cit -> pure $
Java.ArrayType (Java.Dims [[]]) $ Java.ArrayType_VariantClassOrInterface cit
Java.ReferenceTypeArray (Java.ArrayType (Java.Dims d) v) -> pure $
Java.ArrayType (Java.Dims $ d ++ [[]]) v
_ -> fail $ "don't know how to make Java reference type into array type: " ++ show rt
_ -> fail $ "don't know how to make Java type into array type: " ++ show t
typeParameterToTypeArgument (Java.TypeParameter _ id _) = Java.TypeArgumentReference $
Java.ReferenceTypeVariable $ Java.TypeVariable [] id
variableDeclarationStatement :: M.Map Namespace Java.PackageName -> Name -> Java.Identifier -> Java.Expression -> Java.BlockStatement
variableDeclarationStatement aliases elName id rhs = Java.BlockStatementLocalVariableDeclaration $
Java.LocalVariableDeclarationStatement $
Java.LocalVariableDeclaration [] t [vdec]
where
t = Java.LocalVariableTypeType $ Java.UnannType $ javaTypeVariableToType $ Java.TypeVariable [] $
nameToJavaTypeIdentifier aliases False elName
vdec = javaVariableDeclarator id (Just init)
where
init = Java.VariableInitializerExpression rhs
variableToJavaIdentifier :: Variable -> Java.Identifier
variableToJavaIdentifier (Variable var) = Java.Identifier var -- TODO: escape
variantClassName :: Bool -> Name -> FieldName -> Name
variantClassName qualify elName (FieldName fname) = fromQname gname local1
where
(gname, local) = toQnameEager elName
flocal = capitalize fname
local1 = if qualify
then local ++ "." ++ flocal
else if flocal == local then flocal ++ "_" else flocal
visitorTypeVariable :: Java.ReferenceType
visitorTypeVariable = javaTypeVariable "r"