diff --git a/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractWrapper.java b/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractWrapper.java index 41c2907..5de004a 100644 --- a/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractWrapper.java +++ b/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractWrapper.java @@ -926,7 +926,12 @@ private void buildConstantFunction( nativeReturnTypeName = structClassNameMap.get(outputType.structIdentifier()); } else if (outputType.getType().startsWith("tuple") && outputType.getType().contains("[")) { - nativeReturnTypeName = typeName; + TypeName argument = + ((ParameterizedTypeName) buildStructArrayTypeName(outputType)) + .typeArguments.get(0); + nativeReturnTypeName = + ParameterizedTypeName.get( + ClassName.get(List.class), ClassName.get("", argument.toString())); } else { nativeReturnTypeName = this.getWrapperRawType(typeName); } @@ -972,14 +977,25 @@ private void buildConstantFunction( nativeReturnTypeName); } } else { - List returnTypes = buildReturnTypes(outputParameterTypes); + List returnTypes = new ArrayList<>(); + for (int i = 0; i < functionDefinition.getOutputs().size(); ++i) { + ABIDefinition.NamedType outputType = functionDefinition.getOutputs().get(i); + if (outputType.getType().equals("tuple")) { + returnTypes.add(structClassNameMap.get(outputType.structIdentifier())); + } else if (outputType.getType().startsWith("tuple") + && outputType.getType().contains("[")) { + returnTypes.add(buildStructArrayTypeName(outputType)); + } else { + returnTypes.add(getNativeType(outputParameterTypes.get(i))); + } + } ParameterizedTypeName parameterizedTupleType = ParameterizedTypeName.get( ClassName.get( "org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated", "Tuple" + returnTypes.size()), - returnTypes.toArray(new TypeName[returnTypes.size()])); + returnTypes.toArray(new TypeName[0])); methodBuilder.returns(parameterizedTupleType); @@ -1067,12 +1083,28 @@ private TypeSpec buildEventResponseObject( builder.addField(TransactionReceipt.Logs.class, "log", Modifier.PUBLIC); for (NamedTypeName namedType : indexedParameters) { - TypeName typeName = getEventNativeType(namedType.typeName); + final TypeName typeName; + if (namedType.getType().equals("tuple")) { + typeName = structClassNameMap.get(namedType.structIdentifier()); + } else if (namedType.getType().startsWith("tuple") + && namedType.getType().contains("[")) { + typeName = buildStructArrayTypeName(namedType.namedType); + } else { + typeName = getEventNativeType(namedType.typeName); + } builder.addField(typeName, namedType.getName(), Modifier.PUBLIC); } for (NamedTypeName namedType : nonIndexedParameters) { - TypeName typeName = getNativeType(namedType.typeName); + final TypeName typeName; + if (namedType.getType().equals("tuple")) { + typeName = structClassNameMap.get(namedType.structIdentifier()); + } else if (namedType.getType().startsWith("tuple") + && namedType.getType().contains("[")) { + typeName = buildStructArrayTypeName(namedType.namedType); + } else { + typeName = getNativeType(namedType.typeName); + } builder.addField(typeName, namedType.getName(), Modifier.PUBLIC); } @@ -1196,6 +1228,15 @@ private List buildEventFunctions( } } for (ABIDefinition.NamedType namedType : inputs) { + final TypeName typeName; + if (namedType.getType().equals("tuple")) { + typeName = structClassNameMap.get(namedType.structIdentifier()); + } else if (namedType.getType().startsWith("tuple") + && namedType.getType().contains("[")) { + typeName = buildStructArrayTypeName(namedType); + } else { + typeName = buildTypeName(namedType.getType()); + } if (namedType.getName() == null || namedType.getName().equals("")) { String paramName = functionName + "Param" + index; while (eventParamNameFilter.contains(paramName)) { @@ -1205,11 +1246,7 @@ private List buildEventFunctions( eventParamNameFilter.add(paramName); namedType.setName(paramName); } - NamedTypeName parameter = - new NamedTypeName( - namedType.getName(), - buildTypeName(namedType.getType()), - namedType.isIndexed()); + NamedTypeName parameter = new NamedTypeName(namedType, typeName, namedType.isIndexed()); if (namedType.isIndexed()) { indexedParameters.add(parameter); } else { @@ -1240,9 +1277,6 @@ private CodeBlock buildTypedResponse( List indexedParameters, List nonIndexedParameters, boolean flowable) { - String nativeConversion; - - nativeConversion = ".getValue()"; CodeBlock.Builder builder = CodeBlock.builder(); if (flowable) { @@ -1251,21 +1285,51 @@ private CodeBlock buildTypedResponse( builder.addStatement("$L.log = eventValues.getLog()", objectName); } for (int i = 0; i < indexedParameters.size(); i++) { + final NamedTypeName namedTypeName = indexedParameters.get(i); + String nativeConversion; + if (structClassNameMap.values().stream() + .noneMatch(name -> name.equals(namedTypeName.getTypeName())) + && !namedTypeName.getType().startsWith("tuple[")) { + nativeConversion = ".getValue()"; + } else { + nativeConversion = ""; + } + final TypeName typeName; + if (namedTypeName.getType().equals("tuple")) { + typeName = structClassNameMap.get(namedTypeName.structIdentifier()); + } else if (namedTypeName.getType().startsWith("tuple") + && namedTypeName.getType().contains("[")) { + typeName = buildStructArrayTypeName(namedTypeName.namedType); + } else { + typeName = getEventNativeType(namedTypeName.getTypeName()); + } builder.addStatement( "$L.$L = ($T) eventValues.getIndexedValues().get($L)" + nativeConversion, objectName, indexedParameters.get(i).getName(), - getEventNativeType(indexedParameters.get(i).getTypeName()), + typeName, i); } for (int i = 0; i < nonIndexedParameters.size(); i++) { + final NamedTypeName namedTypeName = nonIndexedParameters.get(i); + String result = "$L.$L = ($T) eventValues.getNonIndexedValues().get($L)"; + final TypeName typeName; + if (nonIndexedParameters.get(i).getType().equals("tuple")) { + typeName = structClassNameMap.get(namedTypeName.structIdentifier()); + } else if (nonIndexedParameters.get(i).getType().startsWith("tuple") + && nonIndexedParameters.get(i).getType().contains("[")) { + typeName = buildStructArrayTypeName(namedTypeName.namedType); + } else { + typeName = getNativeType(nonIndexedParameters.get(i).getTypeName()); + } + if (structClassNameMap.values().stream() + .noneMatch(name -> name.equals(namedTypeName.getTypeName())) + && !namedTypeName.getType().startsWith("tuple[")) { + result += ".getValue()"; + } builder.addStatement( - "$L.$L = ($T) eventValues.getNonIndexedValues().get($L)" + nativeConversion, - objectName, - nonIndexedParameters.get(i).getName(), - getNativeType(nonIndexedParameters.get(i).getTypeName()), - i); + result, objectName, nonIndexedParameters.get(i).getName(), typeName, i); } return builder.build(); } @@ -1493,17 +1557,21 @@ private static String funcNameToConst(String funcName) { private static class NamedTypeName { private final TypeName typeName; - private final String name; + private final ABIDefinition.NamedType namedType; private final boolean indexed; - NamedTypeName(String name, TypeName typeName, boolean indexed) { - this.name = name; + NamedTypeName(ABIDefinition.NamedType namedType, TypeName typeName, boolean indexed) { + this.namedType = namedType; this.typeName = typeName; this.indexed = indexed; } public String getName() { - return name; + return namedType.getName(); + } + + public String getType() { + return namedType.getType(); } public TypeName getTypeName() { @@ -1513,6 +1581,10 @@ public TypeName getTypeName() { public boolean isIndexed() { return indexed; } + + public int structIdentifier() { + return namedType.structIdentifier(); + } } private static String getBinaryFuncDefinition() { diff --git a/src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java b/src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java index c6e0eb1..1bf167f 100644 --- a/src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java +++ b/src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java @@ -58,6 +58,13 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept } } + @Test + public void helloCodeGen() throws IOException { + final String COMPLEX_ABI_FILE = "HelloWorld.abi"; + final String COMPLEX_NAME = "HelloWorld"; + codeGenTest(COMPLEX_ABI_FILE, COMPLEX_NAME); + } + @Test public void complexABICodeGen() throws IOException { final String COMPLEX_ABI_FILE = "ComplexCodecTest.abi"; @@ -72,6 +79,13 @@ public void tableABICodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void voteABICodeGen() throws IOException { + final String ABI_FILE = "AnonymousVoting.abi"; + final String CONTRACT_NAME = "AnonymousVoting"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + @Test public void codecTestABICodeGen() throws IOException { final String ABI_FILE = "CodecTest.abi"; @@ -86,6 +100,14 @@ public void weidABICodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + // FIXME: v2 event override bug + // @Test + public void eventTestCodeGen() throws IOException { + final String ABI_FILE = "EventSubDemo.abi"; + final String CONTRACT_NAME = "EventSubDemo"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + private void codeGenTest(String abiFileName, String contractName) throws IOException { String abiFile = CodeGenV2Test.class.getClassLoader().getResource(abiFileName).getPath(); String binFile = CodeGenV2Test.class.getClassLoader().getResource(abiFileName).getPath();