hydra-scala-0.17.3: src/main/haskell/Hydra/Scala/Serde.hs
-- Note: this is an automatically generated file. Do not edit.
-- | Serialization functions for converting Scala AST to abstract expressions
module Hydra.Scala.Serde where
import qualified Hydra.Ast as Ast
import qualified Hydra.Coders as Coders
import qualified Hydra.Core as Core
import qualified Hydra.Docs as Docs
import qualified Hydra.Error.Checking as Checking
import qualified Hydra.Error.Core as ErrorCore
import qualified Hydra.Error.File as ErrorFile
import qualified Hydra.Error.Packaging as ErrorPackaging
import qualified Hydra.Error.System as ErrorSystem
import qualified Hydra.Errors as Errors
import qualified Hydra.File as File
import qualified Hydra.Graph as Graph
import qualified Hydra.Json.Model as Model
import qualified Hydra.Jvm.Serde as Serde
import qualified Hydra.Overlay.Haskell.Lib.Equality as Equality
import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
import qualified Hydra.Overlay.Haskell.Lib.Math as Math
import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Overlay.Haskell.Lib.Ordering as Ordering
import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Parsing as Parsing
import qualified Hydra.Paths as Paths
import qualified Hydra.Query as Query
import qualified Hydra.Relational as Relational
import qualified Hydra.Scala.Syntax as Syntax
import qualified Hydra.Serialization as Serialization
import qualified Hydra.System as System
import qualified Hydra.Tabular as Tabular
import qualified Hydra.Testing as Testing
import qualified Hydra.Time as Time
import qualified Hydra.Topology as Topology
import qualified Hydra.Typed as Typed
import qualified Hydra.Typing as Typing
import qualified Hydra.Util as Util
import qualified Hydra.Validation as Validation
import qualified Hydra.Variants as Variants
import Prelude hiding (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Convert a case clause to an expression
caseToExpr :: Syntax.Case -> Ast.Expr
caseToExpr c =
let pat = Syntax.casePat c
term = Syntax.caseBody c
in (Serialization.spaceSep [
Serialization.cst "case",
(patToExpr pat),
(Serialization.cst "=>"),
(termToExpr term)])
-- | Convert a function-data lambda to an expression
dataFunctionToExpr :: Syntax.FunctionData -> Ast.Expr
dataFunctionToExpr f =
let params = Syntax.functionDataParams f
body = Syntax.functionDataBody f
bodyExpr = termToExpr body
bodyLen = Serialization.expressionLength bodyExpr
in (Logic.ifElse (Ordering.gt bodyLen 60) (Serialization.noSep [
Serialization.parenListAdaptive (Lists.map dataParamToExpr params),
(Serialization.cst " =>\n "),
bodyExpr]) (Serialization.spaceSep [
Serialization.parenListAdaptive (Lists.map dataParamToExpr params),
(Serialization.cst "=>"),
bodyExpr]))
-- | Convert a data name to an expression
dataNameToExpr :: Syntax.NameData -> Ast.Expr
dataNameToExpr dn = Serialization.cst (Syntax.unPredefString (Syntax.nameDataValue dn))
-- | Convert a data parameter to an expression
dataParamToExpr :: Syntax.ParamData -> Ast.Expr
dataParamToExpr dp =
let name = Syntax.paramDataName dp
stype = Syntax.paramDataDecltpe dp
in (Serialization.noSep (Optionals.givens [
Optionals.pure (nameToExpr name),
(Optionals.map (\t -> Serialization.spaceSep [
Serialization.cst ":",
(typeToExpr t)]) stype)]))
-- | Convert a data reference to an expression
dataRefToExpr :: Syntax.RefData -> Ast.Expr
dataRefToExpr ref =
case ref of
Syntax.RefDataName v0 -> dataNameToExpr v0
Syntax.RefDataSelect v0 -> dataSelectToExpr v0
-- | Convert a data select to an expression
dataSelectToExpr :: Syntax.SelectData -> Ast.Expr
dataSelectToExpr sel =
let arg = Syntax.selectDataQual sel
name = Syntax.selectDataName sel
in (Serialization.ifx dotOp (termToExpr arg) (termToExpr (Syntax.DataRef (Syntax.RefDataName name))))
-- | Convert a definition to an expression
defnToExpr :: Syntax.Defn -> Ast.Expr
defnToExpr def =
case def of
Syntax.DefnDef v0 ->
let name = Syntax.defDefnName v0
tparams = Syntax.defDefnTparams v0
paramss = Syntax.defDefnParamss v0
scod = Syntax.defDefnDecltpe v0
body = Syntax.defDefnBody v0
tparamsExpr =
Logic.ifElse (Lists.null tparams) Nothing (Optionals.pure (Serialization.bracketList Serialization.inlineStyle (Lists.map typeParamToExpr tparams)))
scodExpr =
Optionals.map (\t -> Serialization.spaceSep [
Serialization.cst ":",
(typeToExpr t)]) scod
paramssExprs = Lists.map (\ps -> Serialization.parenListAdaptive (Lists.map dataParamToExpr ps)) paramss
nameAndParams =
Serialization.noSep (Optionals.givens (Lists.concat [
[
Optionals.pure (dataNameToExpr name)],
[
tparamsExpr],
(Lists.map (\pe -> Optionals.pure pe) paramssExprs),
[
scodExpr]]))
bodyExpr = termToExpr body
defSig =
Serialization.spaceSep [
Serialization.cst "def",
nameAndParams,
(Serialization.cst "=")]
bodyLen = Serialization.expressionLength bodyExpr
in (Logic.ifElse (Ordering.gt bodyLen 80) (Serialization.noSep [
defSig,
(Serialization.cst "\n "),
bodyExpr]) (Serialization.spaceSep [
defSig,
bodyExpr]))
Syntax.DefnType v0 ->
let name = Syntax.typeDefnName v0
tparams = Syntax.typeDefnTparams v0
body = Syntax.typeDefnBody v0
in (Serialization.spaceSep (Optionals.givens [
Optionals.pure (Serialization.cst "type"),
(Optionals.pure (typeNameToExpr name)),
(Logic.ifElse (Lists.null tparams) Nothing (Optionals.pure (Serialization.bracketList Serialization.inlineStyle (Lists.map typeParamToExpr tparams)))),
(Optionals.pure (Serialization.cst "=")),
(Optionals.pure (typeToExpr body))]))
Syntax.DefnVal v0 ->
let mods = Syntax.valDefnMods v0
pats = Syntax.valDefnPats v0
typ = Syntax.valDefnDecltpe v0
rhs = Syntax.valDefnRhs v0
nameStr =
Optionals.withDefault "" (Optionals.map (\firstPat ->
let patName =
case firstPat of
Syntax.PatVar v1 -> Syntax.varPatName v1
in (Syntax.unPredefString (Syntax.nameDataValue patName))) (Lists.head pats))
nameAndType =
Optionals.cases typ (Serialization.cst nameStr) (\t -> Serialization.spaceSep [
Serialization.cst (Strings.concat2 nameStr ":"),
(typeToExpr t)])
valKeyword = Logic.ifElse (Lists.null mods) "val" "lazy val"
in (Serialization.spaceSep [
Serialization.cst valKeyword,
nameAndType,
(Serialization.cst "="),
(termToExpr rhs)])
Syntax.DefnClass v0 ->
let mods = Syntax.classDefnMods v0
name = Syntax.classDefnName v0
tparams = Syntax.classDefnTparams v0
ctor = Syntax.classDefnCtor v0
paramss = Syntax.primaryCtorParamss ctor
tparamsExpr =
Logic.ifElse (Lists.null tparams) Nothing (Optionals.pure (Serialization.bracketList Serialization.inlineStyle (Lists.map typeParamToExpr tparams)))
paramsExpr =
Logic.ifElse (Lists.null paramss) Nothing (Optionals.pure (Serialization.parenListAdaptive (Lists.map dataParamToExpr (Lists.concat paramss))))
nameAndParams =
Serialization.noSep (Optionals.givens [
Optionals.pure (typeNameToExpr name),
tparamsExpr,
paramsExpr])
in (Serialization.spaceSep (Lists.concat [
Lists.map modToExpr mods,
[
Serialization.cst "class",
nameAndParams]]))
Syntax.DefnEnum v0 ->
let name = Syntax.enumDefnName v0
tparams = Syntax.enumDefnTparams v0
template = Syntax.enumDefnTemplate v0
stats = Syntax.templateStats template
enumHeader =
Serialization.spaceSep [
Serialization.cst "enum",
(Serialization.noSep (Optionals.givens [
Optionals.pure (typeNameToExpr name),
(Logic.ifElse (Lists.null tparams) Nothing (Optionals.pure (Serialization.bracketList Serialization.inlineStyle (Lists.map typeParamToExpr tparams))))])),
(Serialization.cst ":")]
enumCases =
Lists.map (\s -> Serialization.spaceSep [
Serialization.cst " ",
(statToExpr s)]) stats
in (Serialization.newlineSep (Lists.concat [
[
enumHeader],
enumCases]))
Syntax.DefnEnumCase v0 ->
let name = Syntax.enumCaseDefnName v0
ctor = Syntax.enumCaseDefnCtor v0
inits = Syntax.enumCaseDefnInits v0
paramss = Syntax.primaryCtorParamss ctor
allParams = Lists.concat paramss
params =
Logic.ifElse (Lists.null allParams) (Serialization.cst "") (Serialization.parenListAdaptive (Lists.map dataParamToExpr allParams))
extendsClause =
Logic.ifElse (Lists.null inits) (Serialization.cst "") (Serialization.spaceSep [
Serialization.cst "extends",
(Serialization.commaSep Serialization.inlineStyle (Lists.map initToExpr inits))])
in (Serialization.spaceSep [
Serialization.cst "case",
(Serialization.noSep [
dataNameToExpr name,
params]),
extendsClause])
-- | The dot operator for member access
dotOp :: Ast.Op
dotOp =
Ast.Op {
Ast.opSymbol = (Ast.Symbol "."),
Ast.opPadding = Ast.Padding {
Ast.paddingLeft = Ast.WsNone,
Ast.paddingRight = Ast.WsNone},
Ast.opPrecedence = (Ast.Precedence 0),
Ast.opAssociativity = Ast.AssociativityLeft}
-- | The function arrow operator (=>)
functionArrowOp :: Ast.Op
functionArrowOp = Serialization.op "=>" (Math.negate 1) Ast.AssociativityRight
-- | Convert an import/export statement to an expression
importExportStatToExpr :: Syntax.ImportExportStat -> Ast.Expr
importExportStatToExpr ie =
case ie of
Syntax.ImportExportStatImport v0 ->
let importers = Syntax.importImporters v0
in (Serialization.newlineSep (Lists.map importerToExpr importers))
-- | Convert an importer to an expression
importerToExpr :: Syntax.Importer -> Ast.Expr
importerToExpr imp =
let ref = Syntax.importerRef imp
importees = Syntax.importerImportees imp
refName =
case ref of
Syntax.RefDataName v0 -> Syntax.unPredefString (Syntax.nameDataValue v0)
forImportees =
Logic.ifElse (Lists.null importees) (Serialization.cst "") (Logic.ifElse (Equality.equal (Lists.length importees) 1) (Optionals.withDefault (Serialization.cst "") (Optionals.map (\firstImp -> Serialization.noSep [
Serialization.cst ".",
case firstImp of
Syntax.ImporteeWildcard -> Serialization.cst "*"
Syntax.ImporteeName v0 -> Serialization.cst (case (Syntax.nameImporteeName v0) of
Syntax.NameValue v1 -> v1)]) (Lists.head importees))) (Serialization.noSep [
Serialization.cst ".",
(Serialization.curlyBracesList Nothing Serialization.inlineStyle (Lists.map (\it -> case it of
Syntax.ImporteeWildcard -> Serialization.cst "*"
Syntax.ImporteeName v0 -> Serialization.cst (case (Syntax.nameImporteeName v0) of
Syntax.NameValue v1 -> v1)) importees))]))
in (Serialization.spaceSep [
Serialization.cst "import",
(Serialization.noSep [
Serialization.cst refName,
forImportees])])
-- | Convert an init to an expression
initToExpr :: Syntax.Init -> Ast.Expr
initToExpr init = typeToExpr (Syntax.initTpe init)
-- | Convert a literal to an expression
litToExpr :: Syntax.Lit -> Ast.Expr
litToExpr lit =
case lit of
Syntax.LitBoolean v0 -> Serialization.cst (Logic.ifElse v0 "true" "false")
Syntax.LitByte v0 -> Serialization.cst (Strings.concat2 (Literals.showInt8 v0) ".toByte")
Syntax.LitShort v0 -> Serialization.cst (Strings.concat2 (Literals.showInt16 v0) ".toShort")
Syntax.LitInt v0 -> Serialization.cst (Literals.showInt32 v0)
Syntax.LitLong v0 -> Serialization.cst (Strings.concat2 (Literals.showInt64 v0) "L")
Syntax.LitFloat v0 -> Serialization.cst (scalaFloatLiteralText "Float" "f" (Literals.showFloat32 v0))
Syntax.LitDouble v0 -> Serialization.cst (scalaFloatLiteralText "Double" "" (Literals.showFloat64 v0))
Syntax.LitUnit -> Serialization.cst "()"
Syntax.LitString v0 -> Serialization.cst (Strings.concat2 "\"" (Strings.concat2 (Serde.escapeJavaString v0) "\""))
Syntax.LitBytes v0 -> Serialization.cst (Strings.concat2 "Array[Byte](" (Strings.concat2 (Strings.join ", " (Lists.map (\b -> Strings.concat2 (Literals.showInt32 b) ".toByte") v0)) ")"))
_ -> Serialization.cst "TODO:literal"
-- | The match operator
matchOp :: Ast.Op
matchOp =
Ast.Op {
Ast.opSymbol = (Ast.Symbol "match"),
Ast.opPadding = Ast.Padding {
Ast.paddingLeft = Ast.WsSpace,
Ast.paddingRight = (Ast.WsBreakAndIndent " ")},
Ast.opPrecedence = (Ast.Precedence 0),
Ast.opAssociativity = Ast.AssociativityNone}
-- | Convert a modifier to an expression
modToExpr :: Syntax.Mod -> Ast.Expr
modToExpr m =
case m of
Syntax.ModCase -> Serialization.cst "case"
Syntax.ModSealed -> Serialization.cst "sealed"
Syntax.ModAbstract -> Serialization.cst "abstract"
Syntax.ModFinal -> Serialization.cst "final"
Syntax.ModOverride -> Serialization.cst "override"
Syntax.ModImplicit -> Serialization.cst "implicit"
Syntax.ModLazy -> Serialization.cst "lazy"
Syntax.ModPrivate _ -> Serialization.cst "private"
Syntax.ModProtected _ -> Serialization.cst "protected"
-- | Convert a name to an expression
nameToExpr :: Syntax.Name -> Ast.Expr
nameToExpr name =
case name of
Syntax.NameValue v0 -> Serialization.cst v0
-- | Convert a pattern to an expression
patToExpr :: Syntax.Pat -> Ast.Expr
patToExpr pat =
case pat of
Syntax.PatExtract v0 ->
let fun = Syntax.extractPatFun v0
args = Syntax.extractPatArgs v0
in (Logic.ifElse (Lists.null args) (termToExpr fun) (Serialization.noSep [
termToExpr fun,
(Serialization.parenListAdaptive (Lists.map patToExpr args))]))
Syntax.PatVar v0 -> dataNameToExpr (Syntax.varPatName v0)
Syntax.PatWildcard -> Serialization.cst "_"
-- | Convert a package to an expression
pkgToExpr :: Syntax.Pkg -> Ast.Expr
pkgToExpr pkg =
let name = Syntax.pkgName pkg
stats = Syntax.pkgStats pkg
package =
Serialization.spaceSep [
Serialization.cst "package",
(dataNameToExpr name)]
in (Serialization.doubleNewlineSep (Lists.concat [
[
package],
(Lists.map statToExpr stats)]))
scalaFloatLiteralText :: String -> String -> String -> String
scalaFloatLiteralText prefix suffix s =
Logic.ifElse (Equality.equal s "NaN") (Strings.concat2 prefix ".NaN") (Logic.ifElse (Equality.equal s "Infinity") (Strings.concat2 prefix ".PositiveInfinity") (Logic.ifElse (Equality.equal s "-Infinity") (Strings.concat2 prefix ".NegativeInfinity") (Strings.concat2 s suffix)))
-- | Convert a statement to an expression
statToExpr :: Syntax.Stat -> Ast.Expr
statToExpr stat =
case stat of
Syntax.StatTerm v0 -> termToExpr v0
Syntax.StatDefn v0 -> defnToExpr v0
Syntax.StatImportExport v0 -> importExportStatToExpr v0
-- | Convert a term to an expression
termToExpr :: Syntax.Data -> Ast.Expr
termToExpr term =
case term of
Syntax.DataLit v0 -> litToExpr v0
Syntax.DataRef v0 -> dataRefToExpr v0
Syntax.DataApply v0 ->
let fun = Syntax.applyDataFun v0
args = Syntax.applyDataArgs v0
in (Serialization.noSep [
termToExpr fun,
(Serialization.parenListAdaptive (Lists.map termToExpr args))])
Syntax.DataAssign v0 ->
let lhs = Syntax.assignDataLhs v0
rhs = Syntax.assignDataRhs v0
in (Serialization.spaceSep [
termToExpr lhs,
(Serialization.cst "->"),
(termToExpr rhs)])
Syntax.DataTuple v0 -> Serialization.parenListAdaptive (Lists.map termToExpr (Syntax.tupleDataArgs v0))
Syntax.DataMatch v0 ->
let expr = Syntax.matchDataExpr v0
mCases = Syntax.matchDataCases v0
in (Serialization.ifx matchOp (termToExpr expr) (Serialization.newlineSep (Lists.map caseToExpr mCases)))
Syntax.DataFunction v0 -> dataFunctionToExpr v0
Syntax.DataBlock v0 ->
let stats = Syntax.blockDataStats v0
in (Serialization.curlyBlock Serialization.fullBlockStyle (Serialization.newlineSep (Lists.map statToExpr stats)))
-- | Convert a type name to an expression
typeNameToExpr :: Syntax.NameType -> Ast.Expr
typeNameToExpr tn = Serialization.cst (Syntax.nameTypeValue tn)
-- | Convert a type parameter to an expression
typeParamToExpr :: Syntax.ParamType -> Ast.Expr
typeParamToExpr tp = nameToExpr (Syntax.paramTypeName tp)
-- | Convert a type to an expression
typeToExpr :: Syntax.Type -> Ast.Expr
typeToExpr typ =
case typ of
Syntax.TypeRef v0 -> case v0 of
Syntax.RefTypeName v1 -> typeNameToExpr v1
Syntax.TypeApply v0 ->
let fun = Syntax.applyTypeTpe v0
args = Syntax.applyTypeArgs v0
in (Serialization.noSep [
typeToExpr fun,
(Serialization.bracketList Serialization.inlineStyle (Lists.map typeToExpr args))])
Syntax.TypeFunction v0 ->
let cod = Syntax.functionTypeRes v0
dom = Optionals.withDefault cod (Lists.head (Syntax.functionTypeParams v0))
in (Serialization.ifx functionArrowOp (typeToExpr dom) (typeToExpr cod))
Syntax.TypeLambda v0 ->
let params = Syntax.lambdaTypeTparams v0
body = Syntax.lambdaTypeTpe v0
in (Serialization.noSep [
typeToExpr body,
(Serialization.bracketList Serialization.inlineStyle (Lists.map typeParamToExpr params))])
Syntax.TypeVar v0 -> typeNameToExpr (Syntax.varTypeName v0)