Skip to content

Commit

Permalink
Merge pull request #346 from TiesNetwork/master
Browse files Browse the repository at this point in the history
Contract wrapper generator should convert array items to native types
  • Loading branch information
conor10 authored Feb 27, 2018
2 parents b54a29e + fd277ad commit 8a84214
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void generateJavaFiles(
classBuilder.addMethod(buildLoad(className, Credentials.class, CREDENTIALS));
classBuilder.addMethod(buildLoad(className, TransactionManager.class,
TRANSACTION_MANAGER));

addAddressesSupport(classBuilder, addresses);

write(basePackageName, classBuilder.build(), destinationDir);
Expand Down Expand Up @@ -345,7 +345,7 @@ private static MethodSpec buildLoad(
CONTRACT_ADDRESS, WEB3J, authName, GAS_PRICE, GAS_LIMIT)
.build();
}

String addParameters(
MethodSpec.Builder methodBuilder, List<AbiDefinition.NamedType> namedTypes) {

Expand Down Expand Up @@ -562,9 +562,37 @@ private void buildConstantFunction(
TypeReference.class, typeName);

if (useNativeJavaTypes) {
methodBuilder.addStatement(
"return executeRemoteCallSingleValueReturn(function, $T.class)",
nativeReturnTypeName);
if (nativeReturnTypeName.equals(ClassName.get(List.class))) {
// We return list. So all the list elements should
// also be converted to native types
TypeName listType = ParameterizedTypeName.get(List.class, Type.class);

CodeBlock.Builder callCode = CodeBlock.builder();
callCode.addStatement(
"$T result = "
+ "($T) executeCallSingleValueReturn(function, $T.class)",
listType, listType, nativeReturnTypeName);
callCode.addStatement("return convertToNative(result)");

TypeSpec callableType = TypeSpec.anonymousClassBuilder("")
.addSuperinterface(ParameterizedTypeName.get(
ClassName.get(Callable.class), nativeReturnTypeName))
.addMethod(MethodSpec.methodBuilder("call")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addException(Exception.class)
.returns(nativeReturnTypeName)
.addCode(callCode.build())
.build())
.build();

methodBuilder.addStatement("return new $T(\n$L)",
buildRemoteCall(nativeReturnTypeName), callableType);
} else {
methodBuilder.addStatement(
"return executeRemoteCallSingleValueReturn(function, $T.class)",
nativeReturnTypeName);
}
} else {
methodBuilder.addStatement("return executeRemoteCallSingleValueReturn(function)");
}
Expand All @@ -583,7 +611,7 @@ private void buildConstantFunction(
buildVariableLengthReturnFunctionConstructor(
methodBuilder, functionName, inputParams, outputParameterTypes);

buildTupleResultContainer(methodBuilder, parameterizedTupleType);
buildTupleResultContainer(methodBuilder, parameterizedTupleType, outputParameterTypes);
}
}

Expand Down Expand Up @@ -889,30 +917,53 @@ private static void buildVariableLengthReturnFunctionConstructor(
}

private void buildTupleResultContainer(
MethodSpec.Builder methodBuilder, ParameterizedTypeName tupleType)
MethodSpec.Builder methodBuilder, ParameterizedTypeName tupleType,
List<TypeName> outputParameterTypes)
throws ClassNotFoundException {

List<TypeName> typeArguments = tupleType.typeArguments;

CodeBlock.Builder tupleConstructor = CodeBlock.builder();
tupleConstructor.addStatement(
"$T results = executeCallMultipleValueReturn(function);",
"$T results = executeCallMultipleValueReturn(function)",
ParameterizedTypeName.get(List.class, Type.class))
.add("return new $T(", tupleType)
.add("$>$>");

String resultString = "\n($T) results.get($L)";
String resultStringSimple = "\n($T) results.get($L)";
if (useNativeJavaTypes) {
resultString += ".getValue()";
resultStringSimple += ".getValue()";
}

String resultStringNativeList =
"\nconvertToNative(($T) results.get($L).getValue())";

int size = typeArguments.size();
for (int i = 0; i < size - 1; i++) {
ClassName classList = ClassName.get(List.class);

for (int i = 0; i < size; i++) {
TypeName param = outputParameterTypes.get(i);
TypeName convertTo = typeArguments.get(i);

String resultString = resultStringSimple;

// If we use native java types we need to convert
// elements of arrays to native java types too
if (useNativeJavaTypes && param instanceof ParameterizedTypeName) {
ParameterizedTypeName oldContainer = (ParameterizedTypeName)param;
ParameterizedTypeName newContainer = (ParameterizedTypeName)convertTo;
if (newContainer.rawType.compareTo(classList) == 0
&& newContainer.typeArguments.size() == 1) {
convertTo = ParameterizedTypeName.get(classList,
oldContainer.typeArguments.get(0));
resultString = resultStringNativeList;
}
}

tupleConstructor
.add(resultString + ", ", typeArguments.get(i), i);
.add(resultString, convertTo, i);
tupleConstructor.add(i < size - 1 ? ", " : ");\n");
}
tupleConstructor
.add(resultString + ");\n", typeArguments.get(size - 1), size - 1);
tupleConstructor.add("$<$<");

TypeSpec callableType = TypeSpec.anonymousClassBuilder("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,18 @@ public void testBuildFunctionConstantSingleValueRawListReturn() throws Exception
//CHECKSTYLE:OFF
String expected =
"public org.web3j.protocol.core.RemoteCall<java.util.List> functionName(java.math.BigInteger param) {\n"
+ " org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(\"functionName\", \n"
+ " java.util.Arrays.<org.web3j.abi.datatypes.Type>asList(new org.web3j.abi.datatypes.generated.Uint8(param)), \n"
+ " java.util.Arrays.<org.web3j.abi.TypeReference<?>>asList(new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.DynamicArray<org.web3j.abi.datatypes.Address>>() {}));\n"
+ " return executeRemoteCallSingleValueReturn(function, java.util.List.class);\n"
+ "}\n";
+ " org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(\"functionName\", \n"
+ " java.util.Arrays.<org.web3j.abi.datatypes.Type>asList(new org.web3j.abi.datatypes.generated.Uint8(param)), \n"
+ " java.util.Arrays.<org.web3j.abi.TypeReference<?>>asList(new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.DynamicArray<org.web3j.abi.datatypes.Address>>() {}));\n"
+ " return new org.web3j.protocol.core.RemoteCall<java.util.List>(\n"
+ " new java.util.concurrent.Callable<java.util.List>() {\n"
+ " @java.lang.Override\n"
+ " public java.util.List call() throws java.lang.Exception {\n"
+ " java.util.List<org.web3j.abi.datatypes.Type> result = (java.util.List<org.web3j.abi.datatypes.Type>) executeCallSingleValueReturn(function, java.util.List.class);\n"
+ " return convertToNative(result);\n"
+ " }\n"
+ " });\n"
+ "}\n";
//CHECKSTYLE:ON

assertThat(methodSpec.toString(), is(expected));
Expand Down Expand Up @@ -272,7 +279,7 @@ public void testBuildFunctionConstantMultipleValueReturn() throws Exception {
+ " new java.util.concurrent.Callable<org.web3j.tuples.generated.Tuple2<java.math.BigInteger, java.math.BigInteger>>() {\n"
+ " @java.lang.Override\n"
+ " public org.web3j.tuples.generated.Tuple2<java.math.BigInteger, java.math.BigInteger> call() throws java.lang.Exception {\n"
+ " java.util.List<org.web3j.abi.datatypes.Type> results = executeCallMultipleValueReturn(function);;\n"
+ " java.util.List<org.web3j.abi.datatypes.Type> results = executeCallMultipleValueReturn(function);\n"
+ " return new org.web3j.tuples.generated.Tuple2<java.math.BigInteger, java.math.BigInteger>(\n"
+ " (java.math.BigInteger) results.get(0).getValue(), \n"
+ " (java.math.BigInteger) results.get(1).getValue());\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6060604052341561000f57600080fd5b6101db8061001e6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d51cd4ac811461003c57600080fd5b341561004757600080fd5b61006873ffffffffffffffffffffffffffffffffffffffff60043516610150565b60405173ffffffffffffffffffffffffffffffffffffffff808a168252881660208201526040810187905260608101869052608081018560008111156100aa57fe5b60ff168152602081018590526060810183905260808282038101604083019081528554600260001960018316156101000201909116049183018290529160a001908590801561013a5780601f1061010f5761010080835404028352916020019161013a565b820191906000526020600020905b81548152906001019060200180831161011d57829003601f168201915b5050995050505050505050505060405180910390f35b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600787015473ffffffffffffffffffffffffffffffffffffffff9687169796909516959394929360ff90921692909160060190885600a165627a7a72305820a724ff6f47df5f7b0a835a873d40089b7ace6a56076e71c1f6941f892fedf1780029
6060604052341561000f57600080fd5b6101e48061001e6000396000f3006060604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d51cd4ac8114610045575b600080fd5b341561005057600080fd5b61007173ffffffffffffffffffffffffffffffffffffffff60043516610159565b60405173ffffffffffffffffffffffffffffffffffffffff808a168252881660208201526040810187905260608101869052608081018560008111156100b357fe5b60ff168152602081018590526060810183905260808282038101604083019081528554600260001960018316156101000201909116049183018290529160a00190859080156101435780601f1061011857610100808354040283529160200191610143565b820191906000526020600020905b81548152906001019060200180831161012657829003601f168201915b5050995050505050505050505060405180910390f35b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600787015473ffffffffffffffffffffffffffffffffffffffff9687169796909516959394929360ff90921692909160060190885600a165627a7a72305820b9eddd870fcbf5f71addbcec8bab66cb21d6e74b3a6f559009dc6810af0407230029
10 changes: 10 additions & 0 deletions core/src/main/java/org/web3j/tx/Contract.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -463,4 +464,13 @@ public Log getLog() {
}
}

@SuppressWarnings("unchecked")
protected static <S extends Type, T>
List<T> convertToNative(List<S> arr) {
List<T> out = new ArrayList<T>();
for (Iterator<S> it = arr.iterator(); it.hasNext(); ) {
out.add((T)it.next().getValue());
}
return out;
}
}

0 comments on commit 8a84214

Please sign in to comment.