diff --git a/adl/stdlib/sys/adlast.adl b/adl/stdlib/sys/adlast.adl index 9988fdda..8088af19 100644 --- a/adl/stdlib/sys/adlast.adl +++ b/adl/stdlib/sys/adlast.adl @@ -90,7 +90,7 @@ type DeclVersions = Vector; union Import { ModuleName moduleName; - ScopedName scopedName; + ScopedName scopedNameImport; }; struct Module diff --git a/haskell/compiler/adl-compiler.cabal b/haskell/compiler/adl-compiler.cabal index 99019a00..75e3aa5a 100644 --- a/haskell/compiler/adl-compiler.cabal +++ b/haskell/compiler/adl-compiler.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: adl-compiler -version: 1.1.6 +version: 1.2.0 synopsis: A compiler for the Algebraic Data Language (ADL) license: BSD-3-Clause license-file: ../../LICENSE diff --git a/haskell/compiler/adlc-lib0/ADL/Utils/IndentedCode.hs b/haskell/compiler/adlc-lib0/ADL/Utils/IndentedCode.hs index 5aad8c16..5c29f9a5 100644 --- a/haskell/compiler/adlc-lib0/ADL/Utils/IndentedCode.hs +++ b/haskell/compiler/adlc-lib0/ADL/Utils/IndentedCode.hs @@ -26,6 +26,9 @@ instance Monoid Code where mempty = CEmpty mappend = (S.<>) -- redundant from ghc 8.4 +cempty :: Code +cempty = CEmpty + cline :: T.Text -> Code cline t = CLine t diff --git a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java.hs b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java.hs index d3631e6d..2a0f8067 100644 --- a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java.hs +++ b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java.hs @@ -423,7 +423,12 @@ generateCoreStruct codeProfile moduleName javaPackageFn decl struct = gen data UnionType = AllVoids | NoVoids | Mixed generateUnion :: CodeGenProfile -> ModuleName -> JavaPackageFn -> CDecl -> Union CResolvedType -> ClassFile -generateUnion codeProfile moduleName javaPackageFn decl union = execState gen state0 +generateUnion codeProfile moduleName javaPackageFn decl union = case codeProfile of + CodeGenProfile { cgp_sealedUnions = True } -> generateSealedUnion codeProfile moduleName javaPackageFn decl union + _ -> generateLegacyUnion codeProfile moduleName javaPackageFn decl union + +generateLegacyUnion :: CodeGenProfile -> ModuleName -> JavaPackageFn -> CDecl -> Union CResolvedType -> ClassFile +generateLegacyUnion codeProfile moduleName javaPackageFn decl union = execState gen state0 where className = unreserveWord (d_name decl) state0 = classFile codeProfile moduleName javaPackageFn classDecl @@ -692,6 +697,143 @@ generateUnion codeProfile moduleName javaPackageFn decl union = execState gen s when (cgp_parcelable codeProfile) $ do generateUnionParcelable codeProfile decl union fieldDetails +generateSealedUnion :: CodeGenProfile -> ModuleName -> JavaPackageFn -> CDecl -> Union CResolvedType -> ClassFile +generateSealedUnion codeProfile moduleName javaPackageFn decl union = execState gen state0 + where + className = unreserveWord (d_name decl) + state0 = classFile codeProfile moduleName javaPackageFn classDecl + classDecl = "public sealed interface " <> className <> typeArgs + isGeneric = length (u_typeParams union) > 0 + typeArgs = case u_typeParams union of + [] -> "" + args -> "<" <> commaSep (map unreserveWord args) <> ">" + typecast fd from = + if needsSuppressedCheckInCast (f_type (fd_field fd)) + then template "$1.<$2>cast($3)" [className,fd_boxedTypeExprStr fd,from] + else template "($1) $2" [fd_boxedTypeExprStr fd,from] + + unionType + | and voidTypes = AllVoids + | or voidTypes = Mixed + | otherwise = NoVoids + where + voidTypes = [isVoidType (f_type f) | f <- u_fields union] + + gen = do + addImport (javaClass (javaPackageFn moduleName) className) + + setDocString (generateDocString (d_annotations decl)) + fieldDetails <- mapM genFieldDetails (u_fields union) + fieldDetail0 <- case fieldDetails of + [] -> error "BUG: unions with no fields are illegal" + (fd:_) -> return fd + + for_ fieldDetails (preventImport . fd_memberVarName) + for_ fieldDetails (preventImport . fd_varName) + + objectsClass <- addImport "java.util.Objects" + + -- constructors + addMethod (cline "/* Constructors */") + + for_ fieldDetails $ \fd -> do + let constructor = cblock (template "public record $1$2($3) implements $4$2" [recordName fd, typeArgs, arg fd, className]) cempty + addMethod constructor + addPermits (className <> "." <> recordName fd) + + -- cast helper + -- let needCastHelper = (or [needsSuppressedCheckInCast (f_type (fd_field fd))| fd <- fieldDetails]) + -- when needCastHelper $ addMethod ( + -- cline "@SuppressWarnings(\"unchecked\")" + -- <> + -- cblock "private static T cast(final Object o)" ( + -- cline "return (T) o;" + -- ) + -- ) + + -- factory + factoryInterface <- addImport (javaClass (cgp_runtimePackage codeProfile) "Factory") + typeExprMethodCode <- genTypeExprMethod codeProfile moduleName decl + + let factory = + cblock1 (template "public static final $2<$1> FACTORY = new $2<$1>()" [className,factoryInterface]) ( + coverride (template "public $1 create($1 other)" [className]) ( + cblock1 "return switch (other)" ( + mconcat [ + ctemplate "case $1($2) ->" [recordName fd, arg fd] + <> + indent ( + ctemplate "new $1($2);" + [recordName fd, val fd] + ) + | fd <- fieldDetails] + ) + ) + <> + cline "" + <> + typeExprMethodCode + <> + cline "" + <> + coverride (template "public JsonBinding<$1> jsonBinding()" [className]) ( + ctemplate "return $1.jsonBinding();" [className] + ) + ) + + let factoryg lazyC = + cblock (template "public static$2 $3<$1$2> factory($4)" [className,leadSpace typeArgs,factoryInterface,factoryArgs]) ( + cblock1 (template "return new Factory<$1$2>()" [className,typeArgs]) ( + mconcat [ctemplate "final $1> $3 = new $1<>(() -> $4);" + [lazyC,fd_boxedTypeExprStr fd,fd_varName fd,fd_factoryExprStr fd] | fd <- fieldDetails] + <> + cline "" + <> + cline "" + <> + coverride (template "public $1$2 create($1$2 other)" [className,typeArgs]) ( + cblock1 "return switch (other)" ( + mconcat [ + ctemplate "case $1($2) ->" [recordName fd, arg fd] + <> + indent ( + ctemplate "new $1($2);" + [recordName fd, val fd] + ) + | fd <- fieldDetails] + ) + ) + <> + cline "" + <> + typeExprMethodCode + <> + cline "" + <> + coverride (template "public JsonBinding<$1$2> jsonBinding()" [className,typeArgs]) ( + ctemplate "return $1.jsonBinding($2);" [className,jsonBindingArgs] + ) + ) + ) + + factoryArgs = commaSep [template "Factory<$1> $2" [arg,factoryTypeArg arg] | arg <- u_typeParams union] + jsonBindingArgs = commaSep [template "$1.jsonBinding()" [factoryTypeArg arg] | arg <- u_typeParams union] + + addMethod (cline "/* Factory for construction of generic values */") + if isGeneric + then do + lazyC <- addImport (javaClass (cgp_runtimePackage codeProfile) "Lazy") + addMethod (factoryg lazyC) + else do + addMethod factory + + -- Json + generateSealedUnionJson codeProfile decl union fieldDetails + + -- Parcelable + -- when (cgp_parcelable codeProfile) $ do + -- generateUnionParcelable codeProfile decl union fieldDetails + generateEnum :: CodeGenProfile -> ModuleName -> JavaPackageFn -> CDecl -> Union CResolvedType -> ClassFile generateEnum codeProfile moduleName javaPackageFn decl union = execState gen state0 where @@ -806,11 +948,12 @@ genTypeExprMethod cgp moduleName decl = do typeRefI <- addImport (javaClass adlastPackage "TypeRef") scopedNameI <- addImport (javaClass adlastPackage "ScopedName") arrayListI <- addImport "java.util.ArrayList" + let constructor = if cgp_sealedUnions cgp then "new " <> typeRefI <> ".Reference" else typeRefI <> ".reference" return $ coverride (template "public $1 typeExpr()" [typeExprI]) ( ctemplate "$1 scopedName = new $1(\"$2\", \"$3\");" [scopedNameI,formatText moduleName,className] <> ctemplate "$1<$2> params = new $1<>();" [arrayListI,typeExprI] <> (mconcat [ ctemplate "params.add(factory$1.typeExpr());" [tparam] | tparam <- getTypeParams (d_type decl)]) - <> ctemplate "return new $1($2.reference(scopedName), params);" [typeExprI,typeRefI] + <> ctemplate "return new $1($2(scopedName), params);" [typeExprI, constructor] ) isTypeToken :: FieldDetails -> Bool diff --git a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java/Internal.hs b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java/Internal.hs index 9c8616cc..c91fa126 100644 --- a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java/Internal.hs +++ b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Java/Internal.hs @@ -34,6 +34,7 @@ import ADL.Compiler.Primitive import ADL.Utils.IndentedCode import ADL.Core.Value import ADL.Utils.Format +import qualified Data.Text as T data JavaFlags = JavaFlags { jf_libDir :: FilePath, @@ -138,6 +139,7 @@ data CodeGenProfile = CodeGenProfile { cgp_hungarianNaming :: Bool, cgp_publicMembers :: Bool, cgp_genericFactories :: Bool, + cgp_sealedUnions :: Bool, cgp_builder :: Bool, cgp_parcelable :: Bool, cgp_runtimePackage :: JavaPackage, @@ -151,6 +153,7 @@ defaultCodeGenProfile = CodeGenProfile { cgp_hungarianNaming = False, cgp_publicMembers = False, cgp_genericFactories = False, + cgp_sealedUnions = False, cgp_builder = True, cgp_parcelable = False, cgp_runtimePackage = defaultRuntimePackage, @@ -166,6 +169,7 @@ data ClassFile = ClassFile { cf_javaPackageFn :: ModuleName -> JavaPackage, cf_imports :: Map.Map Ident (Maybe JavaPackage), cf_implements :: Set.Set T.Text, + cf_permits :: Set.Set T.Text, cf_docString :: Code, cf_decl :: T.Text, cf_fields :: [Code], @@ -173,7 +177,7 @@ data ClassFile = ClassFile { } classFile :: CodeGenProfile -> ModuleName -> (ModuleName -> JavaPackage) -> T.Text -> ClassFile -classFile codeProfile mname javaPackageFn decl = ClassFile codeProfile mname javaPackageFn Map.empty Set.empty mempty decl [] [] +classFile codeProfile mname javaPackageFn decl = ClassFile codeProfile mname javaPackageFn Map.empty Set.empty Set.empty mempty decl [] [] cf_package :: ClassFile -> JavaPackage cf_package cf = cf_javaPackageFn cf (cf_module cf) @@ -219,8 +223,10 @@ classFileCode content = javaPackage = cf_package content imports = [javaClass package name | (name,Just package) <- Map.toList (cf_imports content), package /= javaPackage] header = cgp_header (cf_codeProfile content) - decl | Set.null (cf_implements content) = (template "$1" [cf_decl content]) - | otherwise = (template "$1 implements $2" [cf_decl content,commaSep (Set.toList (cf_implements content))]) + decl | Set.null (cf_implements content) && Set.null (cf_permits content) = (template "$1" [cf_decl content]) + | Set.null (cf_implements content) = (template "$1 permits $2" [cf_decl content, commaSep (Set.toList (cf_permits content))]) + | Set.null (cf_permits content) = (template "$1 implements $2" [cf_decl content, commaSep (Set.toList (cf_implements content))]) + | otherwise = (template "$1 implements $2 permits $3" [cf_decl content, commaSep (Set.toList (cf_implements content)), commaSep (Set.toList (cf_permits content))]) type CState a = State ClassFile a @@ -251,6 +257,9 @@ preventImport name = do addImplements :: T.Text -> CState () addImplements imp = modify (\cf->cf{cf_implements=Set.insert imp (cf_implements cf)}) +addPermits :: T.Text -> CState () +addPermits imp = modify (\cf->cf{cf_permits=Set.insert imp (cf_permits cf)}) + setDocString :: Code -> CState () setDocString code = modify (\cf->cf{cf_docString=code}) @@ -337,11 +346,13 @@ getTypeDetails rt@(RT_Named (scopedName,Decl{d_customType=Nothing})) = TypeDetai genLiteralText' (Literal te (LUnion ctor l)) = do sn <- genScopedName scopedName lit <- genLiteralText l - let ctorfn = unreserveWord ctor + cgp <- cf_codeProfile <$> get + let constructor_function = (if cgp_sealedUnions cgp then discriminatorNameSealed else unreserveWord) ctor + let prefix = (if cgp_sealedUnions cgp then "new " else "") case te of te | refEnumeration te -> return (template "$1.$2" [sn, discriminatorName0 ctor]) - | isVoidLiteral l -> return (template "$1.$2()" [sn, ctorfn]) - | otherwise -> return (template "$1.$2($3)" [sn, ctorfn, lit ]) + | isVoidLiteral l -> return (template "$1$2.$3($4)" [prefix, sn, constructor_function, ""]) + | otherwise -> return (template "$1$2.$3($4)" [prefix, sn, constructor_function, lit]) genLiteralText' lit = error ("BUG: getTypeDetails1: unexpected literal:" ++ show lit) -- a custom type @@ -371,7 +382,11 @@ getTypeDetails rt@(RT_Named (_,Decl{d_customType=Just customType})) = TypeDetail genLiteralText' (Literal te (LUnion ctor l)) = do idHelpers <- getHelpers customType lit <- genLiteralText l - return (template "$1.$2($3)" [idHelpers, ctor, lit ]) + cgp <- cf_codeProfile <$> get + let constructor = if cgp_sealedUnions cgp + then template "new $1.$2($3)" [idHelpers, capitalise ctor, lit] + else template "$1.$2($3)" [idHelpers, ctor, lit] + return constructor genLiteralText' lit = error ("BUG: getTypeDetails2: unexpected literal:" ++ show lit) -- a type variable @@ -902,6 +917,9 @@ discriminatorName0 = T.toUpper . unreserveWord discriminatorName :: FieldDetails -> Ident discriminatorName = discriminatorName0 . f_name . fd_field +discriminatorNameSealed :: T.Text -> Ident +discriminatorNameSealed = capitalise + leadSpace :: T.Text -> T.Text leadSpace "" = "" leadSpace t = " " <> t @@ -1160,6 +1178,118 @@ generateUnionJson cgp decl union fieldDetails = do addMethod (cline "/* Json serialization */") addMethod factory +recordName :: FieldDetails -> Ident +recordName = capitalise . f_name .fd_field + +arg :: FieldDetails -> T.Text +arg fd = if (isVoidType . f_type . fd_field) fd then "" else fd_typeExprStr fd <> " val" + +val :: FieldDetails -> T.Text +val fd = if (isVoidType . f_type . fd_field) fd then "" else "val" + +generateSealedUnionJson :: CodeGenProfile -> CDecl -> Union CResolvedType -> [FieldDetails] -> CState () +generateSealedUnionJson cgp decl union fieldDetails = do + let typeArgs = case u_typeParams union of + [] -> "" + args -> "<" <> commaSep (map unreserveWord args) <> ">" + className0 = unreserveWord (d_name decl) + className = className0 <> typeArgs + + factoryI <- addImport (javaClass (cgp_runtimePackage cgp) "Factory") + lazyC <- addImport (javaClass (cgp_runtimePackage cgp) "Lazy") + jsonBindingI <- addImport (javaClass (cgp_runtimePackage cgp) "JsonBinding") + jsonBindingsI <- addImport (javaClass (cgp_runtimePackage cgp) "JsonBindings") + jsonElementI <- addImport "com.google.gson.JsonElement" + jsonParseExceptionI <- addImport (javaClass (cgp_runtimePackage cgp) "JsonParseException") + jsonBindings <- mapM (genJsonBindingExpr cgp . f_type . fd_field) fieldDetails + let isInternallyTagged = getSerializedWithInternalTag (d_annotations decl) + let bindingArgs = commaSep [template "$1<$2> $3" [jsonBindingI,arg,"binding" <> arg] | arg <- u_typeParams union] + + let factory = + cblock (template "public static$1 $2<$3> jsonBinding($4)" [typeArgs,jsonBindingI,className,bindingArgs]) ( + clineN + [ template "final $1<$2<$3>> $4 = new $1<>(() -> $5);" [lazyC,jsonBindingI,fd_boxedTypeExprStr fd,fd_varName fd,binding] + | (fd,binding) <- zip fieldDetails jsonBindings] + <> + clineN + [ template "final $1<$2> factory$2 = binding$2.factory();" [factoryI,typeParam] + | typeParam <- u_typeParams union] + <> + case u_typeParams union of + [] -> ctemplate "final $1<$2> _factory = FACTORY;" [factoryI,className] + tparams -> ctemplate "final $1<$2> _factory = factory($3);" [factoryI,className,commaSep [template "binding$1.factory()" [i] | i <-tparams ]] + <> + cline "" + <> + cblock1 (template "return new $1<$2>()" [jsonBindingI,className]) ( + coverride (template "public $1<$2> factory()" [factoryI,className]) ( + cline "return _factory;" + ) + <> + cline "" + <> + coverride (template "public $1 toJson($2 _val)" [jsonElementI,className]) ( + cblock1 "return switch (_val)" ( + mconcat [ + ctemplate "case $1($2) ->" [recordName fd, arg fd] + <> + indent ( + if isVoidType (f_type (fd_field fd)) + then ctemplate "$1.unionToJson(\"$2\", null, null);" + [jsonBindingsI, fd_serializedName fd] + else case isInternallyTagged of + (Just tag) -> + ctemplate "$1.unionToItJson(\"$2\", \"$3\", val.$4, $5.get());" + [jsonBindingsI, tag, fd_serializedName fd, fd_accessExpr fd, fd_varName fd] + _ -> + ctemplate "$1.unionToJson(\"$2\", val, $4.get());" + [jsonBindingsI, fd_serializedName fd, fd_accessExpr fd, fd_varName fd] + ) + | fd <- fieldDetails ] + + ) + ) + <> + cline "" + <> + coverride (template "public $1 fromJson($2 _json)" [className,jsonElementI]) ( + case isInternallyTagged of + (Just tag) -> + ctemplate "String _key = $1.unionNameFromItJson(\"$2\", _json);" [jsonBindingsI, tag] + _ -> + ctemplate "String _key = $1.unionNameFromJson(_json);" [jsonBindingsI] + <> + let returnStatements = [ + if isVoidType (f_type (fd_field fd)) + then ctemplate "return new $3();" [className0,typeArgs,recordName fd] + else case isInternallyTagged of + (Just tag) -> + ctemplate "return new $3($4.unionValueFromItJson(\"$5\", _json, $6.get()));" [className0,typeArgs,recordName fd, jsonBindingsI, tag, fd_varName fd] + _ -> + ctemplate "return new $3($4.unionValueFromJson(_json, $5.get()));" [className0,typeArgs,recordName fd, jsonBindingsI, fd_varName fd] + | fd <- fieldDetails] + in ctemplate "if (_key.equals(\"$1\")) {" [fd_serializedName (head fieldDetails)] + <> + indent (head returnStatements) + <> + mconcat [ + cline "}" + <> + ctemplate "else if (_key.equals(\"$1\")) {" [fd_serializedName fd] + <> + indent returnCase + | (fd,returnCase) <- zip (tail fieldDetails) (tail returnStatements)] + <> + cline "}" + <> + ctemplate "throw new $1(\"Invalid discriminator \" + _key + \" for union $2\");" [jsonParseExceptionI,className] + ) + ) + ) + + addMethod (cline "/* Json serialization */") + addMethod factory + generateEnumJson :: CodeGenProfile -> CDecl -> Union CResolvedType -> [FieldDetails] -> CState () generateEnumJson cgp decl union fieldDetails = do factoryI <- addImport (javaClass (cgp_runtimePackage cgp) "Factory") diff --git a/haskell/compiler/adlc/Main.hs b/haskell/compiler/adlc/Main.hs index a047771a..43406889 100644 --- a/haskell/compiler/adlc/Main.hs +++ b/haskell/compiler/adlc/Main.hs @@ -172,6 +172,7 @@ runJava args = do , runtimePackageOption (\s -> updateCodeGenProfile (\cgp -> cgp{J.cgp_runtimePackage=fromString s})) , javaGenerateParcelable (updateCodeGenProfile (\cgp->cgp{J.cgp_parcelable=True})) , javaHungarianNaming (updateCodeGenProfile (\cgp->cgp{J.cgp_hungarianNaming=True})) + , javaSealedUnions (updateCodeGenProfile (\cgp->cgp{J.cgp_sealedUnions=True})) , javaMaxLineLength (\s -> (updateCodeGenProfile (\cgp -> cgp{J.cgp_maxLineLength=read s}))) , javaHeaderComment (\s -> (updateCodeGenProfile (\cgp -> cgp{J.cgp_header=T.pack s}))) , javaSuppressWarningsAnnotation (\s -> (updateCodeGenProfile (\cgp -> cgp{J.cgp_supressWarnings=T.splitOn "," (T.pack s)}))) @@ -192,6 +193,11 @@ runJava args = do (NoArg ufn) "Use hungarian naming conventions" + javaSealedUnions ufn = + Option "" ["sealed-unions"] + (NoArg ufn) + "Use sealed interfaces with permits (Java 17+) for unions" + javaMaxLineLength ufn = Option "" ["max-line-length"] (ReqArg ufn "PACKAGE") diff --git a/java/runtime/src/main/java/org/adl/runtime/Factories.java b/java/runtime/src/main/java/org/adl/runtime/Factories.java index 174a105e..2f1c6bc9 100644 --- a/java/runtime/src/main/java/org/adl/runtime/Factories.java +++ b/java/runtime/src/main/java/org/adl/runtime/Factories.java @@ -256,13 +256,13 @@ public static HashMap stringMap(String k1, T v1, Object... kvs) { } private static TypeExpr primTypeExpr(String primitive) { - return new TypeExpr(TypeRef.primitive(primitive), new ArrayList<>()); + return new TypeExpr(new TypeRef.Primitive(primitive), new ArrayList<>()); } private static TypeExpr primTypeExpr(String primitive, TypeExpr param1) { ArrayList params = new ArrayList<>(); params.add(param1); - return new TypeExpr(TypeRef.primitive(primitive), params); + return new TypeExpr(new TypeRef.Primitive(primitive), params); } }; diff --git a/java/runtime/src/main/java/org/adl/runtime/HashMapHelpers.java b/java/runtime/src/main/java/org/adl/runtime/HashMapHelpers.java index b4014340..99b04673 100644 --- a/java/runtime/src/main/java/org/adl/runtime/HashMapHelpers.java +++ b/java/runtime/src/main/java/org/adl/runtime/HashMapHelpers.java @@ -33,7 +33,7 @@ public TypeExpr typeExpr() { ArrayList params = new ArrayList<>(); params.add(keyFactory.typeExpr()); params.add(valueFactory.typeExpr()); - return new TypeExpr(TypeRef.reference(scopedName), params); + return new TypeExpr(new TypeRef.Reference(scopedName), params); } @Override diff --git a/java/runtime/src/main/java/org/adl/runtime/HashSetHelpers.java b/java/runtime/src/main/java/org/adl/runtime/HashSetHelpers.java index 05e98521..3dc62e97 100644 --- a/java/runtime/src/main/java/org/adl/runtime/HashSetHelpers.java +++ b/java/runtime/src/main/java/org/adl/runtime/HashSetHelpers.java @@ -30,7 +30,7 @@ public TypeExpr typeExpr() { ScopedName scopedName = new ScopedName("sys.types", "Set"); ArrayList params = new ArrayList<>(); params.add(valueFactory.typeExpr()); - return new TypeExpr(TypeRef.reference(scopedName), params); + return new TypeExpr(new TypeRef.Reference(scopedName), params); } @Override diff --git a/java/runtime/src/main/java/org/adl/runtime/JsonBindings.java b/java/runtime/src/main/java/org/adl/runtime/JsonBindings.java index 0c5e53a0..ea43283c 100644 --- a/java/runtime/src/main/java/org/adl/runtime/JsonBindings.java +++ b/java/runtime/src/main/java/org/adl/runtime/JsonBindings.java @@ -317,7 +317,7 @@ public String fromJson(JsonElement json) { @Override public JsonElement create(JsonElement other) { return other; } @Override - public TypeExpr typeExpr() { return new TypeExpr(TypeRef.primitive("Json"), new ArrayList<>()); } + public TypeExpr typeExpr() { return new TypeExpr(new TypeRef.Primitive("Json"), new ArrayList<>()); } @Override public JsonBinding jsonBinding() { return JSON; } }; diff --git a/java/runtime/src/main/java/org/adl/runtime/MaybeHelpers.java b/java/runtime/src/main/java/org/adl/runtime/MaybeHelpers.java index 681083a3..26ac44ca 100644 --- a/java/runtime/src/main/java/org/adl/runtime/MaybeHelpers.java +++ b/java/runtime/src/main/java/org/adl/runtime/MaybeHelpers.java @@ -26,7 +26,7 @@ public TypeExpr typeExpr() { ScopedName scopedName = new ScopedName("sys.types", "Maybe"); ArrayList params = new ArrayList<>(); params.add(tFactory.typeExpr()); - return new TypeExpr(TypeRef.reference(scopedName), params); + return new TypeExpr(new TypeRef.Reference(scopedName), params); } @Override