Skip to content

Commit

Permalink
Fix java backend to generate valid code for empty structures.
Browse files Browse the repository at this point in the history
Note that the additional test added indicates that neither the haskell
backend nor the C++ backend get this right now. TODO: fix these.
  • Loading branch information
timbod7 committed Jul 20, 2016
1 parent 89b4b42 commit bceecc5
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 12 deletions.
28 changes: 16 additions & 12 deletions haskell/compiler/src/ADL/Compiler/Backends/Java.hs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ generateStruct :: CodeGenProfile -> ModuleName -> JavaPackage -> Decl ResolvedTy
generateStruct codeProfile moduleName javaPackage decl struct = execState gen state0
where
state0 = classFile moduleName javaPackage classDecl
isEmpty = null (s_fields struct)
className = unreserveWord (d_name decl)
classDecl = "public class " <> className <> typeArgs
typeArgs = case s_typeParams struct of
Expand Down Expand Up @@ -389,9 +390,8 @@ generateStruct codeProfile moduleName javaPackage decl struct = execState gen s
)

addMethod ctor1
when (not isGeneric) $ do
addMethod ctor2
addMethod ctor3
when (not isGeneric && not isEmpty) (addMethod ctor2)
when (not isGeneric) (addMethod ctor3)

-- Getters/Setters
when (not (cgp_publicMembers codeProfile)) $ do
Expand All @@ -411,15 +411,19 @@ generateStruct codeProfile moduleName javaPackage decl struct = execState gen s
when (cgp_mutable codeProfile) (addMethod setter)

-- equals
addMethod $ cblock (template "public boolean equals($1 other)"[className]) (
cline "return"
<>
let terminators = replicate (length fieldDetails-1) " &&" <> [";"]
tests = [ctemplate (if unboxedField fd then "$1 == other.$1$2" else "$1.equals(other.$1)$2")
[fd_fieldName fd,term]
| (fd,term) <- zip fieldDetails terminators]
in indent (mconcat tests)
)
let equals = cblock (template "public boolean equals($1 other)"[className]) (
cline "return"
<>
let terminators = replicate (length fieldDetails-1) " &&" <> [";"]
tests = [ctemplate (if unboxedField fd then "$1 == other.$1$2" else "$1.equals(other.$1)$2")
[fd_fieldName fd,term]
| (fd,term) <- zip fieldDetails terminators]
in indent (mconcat tests)
)
equalsEmpty = cblock (template "public boolean equals($1 other)"[className]) (
cline "return true;"
)
addMethod (if isEmpty then equalsEmpty else equals)

-- hashcode
addMethod $ cblock "public int hashCode()" (
Expand Down
52 changes: 52 additions & 0 deletions haskell/compiler/tests/test2/cpp-output/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@
namespace ADL {
namespace test {

S0::S0()
{
}

S0::S0(
)
{
}

bool
operator<( const S0 &a, const S0 &b )
{
return false;
}

bool
operator==( const S0 &a, const S0 &b )
{
return
}

S1::S1()
: x(0)
{
Expand Down Expand Up @@ -76,6 +97,37 @@ operator==( const S2 &a, const S2 &b )

namespace ADL {

typename Serialiser<ADL::test::S0>::Ptr
Serialisable<ADL::test::S0>::serialiser( const SerialiserFlags &sf )
{
typedef ADL::test::S0 _T;

struct S_ : public Serialiser<_T>
{
S_( const SerialiserFlags & sf )
{}



void toJson( JsonWriter &json, const _T & v ) const
{
json.startObject();
json.endObject();
}

void fromJson( _T &v, JsonReader &json ) const
{
match( json, JsonReader::START_OBJECT );
while( !match0( json, JsonReader::END_OBJECT ) )
{
ignoreField( json );
}
}
};

return typename Serialiser<_T>::Ptr( new S_(sf) );
};

typename Serialiser<ADL::test::S1>::Ptr
Serialisable<ADL::test::S1>::serialiser( const SerialiserFlags &sf )
{
Expand Down
18 changes: 18 additions & 0 deletions haskell/compiler/tests/test2/cpp-output/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@
namespace ADL {
namespace test {

struct S0
{
S0();

S0(
);

};

bool operator<( const S0 &a, const S0 &b );
bool operator==( const S0 &a, const S0 &b );

struct S1
{
S1();
Expand Down Expand Up @@ -225,6 +237,12 @@ operator==( const S4<T> &a, const S4<T> &b )

namespace ADL {

template <>
struct Serialisable<ADL::test::S0>
{
static Serialiser<ADL::test::S0>::Ptr serialiser(const SerialiserFlags &);
};

template <>
struct Serialisable<ADL::test::S1>
{
Expand Down
19 changes: 19 additions & 0 deletions haskell/compiler/tests/test2/hs-output/ADL/Test.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module ADL.Test(
IntTree,
S0(..),
S1(..),
S2(..),
S3(..),
Expand All @@ -19,6 +20,24 @@ import qualified Prelude

type IntTree = (Tree Data.Int.Int32)

data S0 = S0
}
deriving (Prelude.Eq,Prelude.Ord,Prelude.Show)

instance ADLValue S0 where
atype _ = "test.S0"

defaultv = S0

jsonSerialiser jf = JSONSerialiser to from
where

to v = JSON.Object ( HM.fromList
] )

from (JSON.Object hm) = S0
from _ = Prelude.Nothing

data S1 = S1
{ s1_x :: Data.Int.Int32
, s1_y :: T.Text
Expand Down
4 changes: 4 additions & 0 deletions haskell/compiler/tests/test2/input/test.adl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ module test

// Simple structures

struct S0
{
};

struct S1
{
Int32 x;
Expand Down
31 changes: 31 additions & 0 deletions haskell/compiler/tests/test2/java-output/adl/test/S0.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package adl.test;

import org.adl.runtime.Factory;

public class S0 {


public S0() {
}

public S0(S0 other) {
}

public boolean equals(S0 other) {
return true;
}

public int hashCode() {
int result = 1;
return result;
}

public static Factory<S0> factory = new Factory<S0>() {
public S0 create() {
return new S0();
}
public S0 create(S0 other) {
return new S0(other);
}
};
}

0 comments on commit bceecc5

Please sign in to comment.