From 842e38f5894eac6a9988f2f079a289f8d23c0225 Mon Sep 17 00:00:00 2001 From: dw <307665930@qq.com> Date: Wed, 10 Apr 2024 15:56:29 +0800 Subject: [PATCH 1/3] feat: support generated java comments by solidity devdoc. (#39) Co-authored-by: dwzhan --- .../org/fisco/bcos/codegen/CodeGenMain.java | 13 +- .../fisco/bcos/codegen/v2/utils/Devdoc.java | 54 ++++ .../fisco/bcos/codegen/v2/utils/DocUtils.java | 74 +++++ .../v2/wrapper/SolidityContractGenerator.java | 5 + .../v2/wrapper/SolidityContractWrapper.java | 49 ++++ .../fisco/bcos/codegen/v3/utils/Devdoc.java | 54 ++++ .../fisco/bcos/codegen/v3/utils/DocUtils.java | 74 +++++ .../codegen/v3/wrapper/ContractGenerator.java | 19 +- .../codegen/v3/wrapper/ContractWrapper.java | 86 +++++- .../bcos/codegen/v2/test/CodeGenV2Test.java | 70 +++++ .../bcos/codegen/v3/test/CodeGenV3Test.java | 74 +++++ src/test/resources/ERC721.abi | 274 ++++++++++++++++++ src/test/resources/ERC721.devdoc | 84 ++++++ src/test/resources/ERC721.userdoc | 31 ++ 14 files changed, 943 insertions(+), 18 deletions(-) create mode 100644 src/main/java/org/fisco/bcos/codegen/v2/utils/Devdoc.java create mode 100644 src/main/java/org/fisco/bcos/codegen/v2/utils/DocUtils.java create mode 100644 src/main/java/org/fisco/bcos/codegen/v3/utils/Devdoc.java create mode 100644 src/main/java/org/fisco/bcos/codegen/v3/utils/DocUtils.java create mode 100644 src/test/resources/ERC721.abi create mode 100644 src/test/resources/ERC721.devdoc create mode 100644 src/test/resources/ERC721.userdoc diff --git a/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java b/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java index a6e3ce5..3bd71a1 100644 --- a/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java +++ b/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java @@ -107,6 +107,11 @@ static class PicocliRunner implements Runnable { required = true) private File smBinFile; + @Option( + names = {"-d", "--devdoc"}, + description = "solidity devdoc file generated by NatSpec style comments.") + private File devdocFile; + @Option( names = {"-o", "--outputDir"}, description = "destination base directory.", @@ -134,7 +139,12 @@ public void run() { if (version.equals(Version.V2)) { try { new org.fisco.bcos.codegen.v2.wrapper.SolidityContractGenerator( - binFile, smBinFile, abiFile, destinationFileDir, packageName) + binFile, + smBinFile, + abiFile, + devdocFile, + destinationFileDir, + packageName) .generateJavaFiles(); } catch (Exception e) { org.fisco.bcos.codegen.v2.utils.CodeGenUtils.exitError(e); @@ -145,6 +155,7 @@ public void run() { binFile, smBinFile, abiFile, + devdocFile, destinationFileDir, packageName, enableAsyncCall, diff --git a/src/main/java/org/fisco/bcos/codegen/v2/utils/Devdoc.java b/src/main/java/org/fisco/bcos/codegen/v2/utils/Devdoc.java new file mode 100644 index 0000000..3d35165 --- /dev/null +++ b/src/main/java/org/fisco/bcos/codegen/v2/utils/Devdoc.java @@ -0,0 +1,54 @@ +package org.fisco.bcos.codegen.v2.utils; + +import java.util.Map; + +public class Devdoc { + private String details; + private Map methods; + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Map getMethods() { + return methods; + } + + public void setMethods(Map methods) { + this.methods = methods; + } + + public static class Method { + private String details; + private Map params; + private Map returns; + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } + + public Map getReturns() { + return returns; + } + + public void setReturns(Map returns) { + this.returns = returns; + } + } +} diff --git a/src/main/java/org/fisco/bcos/codegen/v2/utils/DocUtils.java b/src/main/java/org/fisco/bcos/codegen/v2/utils/DocUtils.java new file mode 100644 index 0000000..c42d1a5 --- /dev/null +++ b/src/main/java/org/fisco/bcos/codegen/v2/utils/DocUtils.java @@ -0,0 +1,74 @@ +package org.fisco.bcos.codegen.v2.utils; + +import com.squareup.javapoet.MethodSpec; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import org.fisco.bcos.codegen.v2.exceptions.CodeGenException; +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.transaction.tools.JsonUtils; +import org.fisco.bcos.sdk.utils.StringUtils; + +public class DocUtils { + + public static Devdoc.Method getMethod(Devdoc devdoc, ABIDefinition functionDefinition) { + if (devdoc != null && devdoc.getMethods() != null) { + return devdoc.getMethods().get(functionDefinition.getMethodSignatureAsString()); + } + + return null; + } + + public static void addMethodComments(Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for method + if (!StringUtils.isEmpty(method.getDetails())) { + methodBuilder.addJavadoc("$L \n", method.getDetails()); + } + } + + public static void addParamsComments(Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for params + Map params = method.getParams(); + if (params != null) { + for (String p : params.keySet()) { + if (!StringUtils.isEmpty(params.get(p))) { + methodBuilder.addJavadoc("@param $N $L \n", p, params.get(p)); + } + } + } + } + + public static void addReturnsComments( + String comments, Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for returns + Map returns = method.getReturns(); + if (returns != null) { + for (String r : returns.keySet()) { + if (!StringUtils.isEmpty(returns.get(r))) { + methodBuilder.addJavadoc("$L $N $L \n", comments, r, returns.get(r)); + } + } + } + } + + public static Devdoc convertDevDoc(File devdocFile) throws CodeGenException, IOException { + if (devdocFile != null && devdocFile.exists()) { + byte[] devdocBytes = CodeGenUtils.readBytes(devdocFile); + return JsonUtils.fromJson(new String(devdocBytes), Devdoc.class); + } else { + return null; + } + } +} diff --git a/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractGenerator.java b/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractGenerator.java index 5fbe92d..4b80617 100644 --- a/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractGenerator.java +++ b/src/main/java/org/fisco/bcos/codegen/v2/wrapper/SolidityContractGenerator.java @@ -17,6 +17,7 @@ import java.io.IOException; import org.fisco.bcos.codegen.v2.exceptions.CodeGenException; import org.fisco.bcos.codegen.v2.utils.CodeGenUtils; +import org.fisco.bcos.codegen.v2.utils.DocUtils; /** Java wrapper source code generator for Solidity ABI format. */ public class SolidityContractGenerator { @@ -46,6 +47,7 @@ public class SolidityContractGenerator { private final File binFile; private final File smBinFile; private final File abiFile; + private final File devdocFile; private final File destinationDir; private final String basePackageName; @@ -53,11 +55,13 @@ public SolidityContractGenerator( File binFile, File smBinFile, File abiFile, + File devdocFile, File destinationDir, String basePackageName) { this.binFile = binFile; this.smBinFile = smBinFile; this.abiFile = abiFile; + this.devdocFile = devdocFile; this.destinationDir = destinationDir; this.basePackageName = basePackageName; } @@ -77,6 +81,7 @@ public void generateJavaFiles() throws IOException, ClassNotFoundException, Code new String(binary), new String(smBinary), new String(abiBytes), + DocUtils.convertDevDoc(devdocFile), destinationDir.toString(), basePackageName); } 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 9d355f0..29af75d 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 @@ -43,6 +43,8 @@ import javax.lang.model.element.Modifier; import org.fisco.bcos.codegen.v2.exceptions.CodeGenException; import org.fisco.bcos.codegen.v2.utils.CodeGenUtils; +import org.fisco.bcos.codegen.v2.utils.Devdoc; +import org.fisco.bcos.codegen.v2.utils.DocUtils; import org.fisco.bcos.sdk.abi.FunctionEncoder; import org.fisco.bcos.sdk.abi.FunctionReturnDecoder; import org.fisco.bcos.sdk.abi.TypeReference; @@ -109,15 +111,19 @@ public class SolidityContractWrapper { private static final HashMap structClassNameMap = new HashMap<>(); private static final List structsNamedTypeList = new ArrayList<>(); + private Devdoc devdoc; + public void generateJavaFiles( String contractName, String bin, String smBin, String abi, + Devdoc devdoc, String destinationDir, String basePackageName) throws IOException, ClassNotFoundException, UnsupportedOperationException, CodeGenException { + this.devdoc = devdoc; String className = StringUtils.capitaliseFirstLetter(contractName); logger.info("bin: {}", bin); @@ -745,6 +751,22 @@ private MethodSpec buildFunction(ABIDefinition functionDefinition) buildTransactionFunction(functionDefinition, methodBuilder, inputParams); } + Devdoc.Method method = DocUtils.getMethod(devdoc, functionDefinition); + DocUtils.addMethodComments(method, methodBuilder); + DocUtils.addParamsComments(method, methodBuilder); + if (functionDefinition.isConstant()) { + DocUtils.addReturnsComments("@return", method, methodBuilder); + } else { + methodBuilder.addJavadoc( + "@return TransactionReceipt Get more transaction info (e.g. txhash, block) from TransactionReceipt \n"); + if (functionDefinition.getOutputs().size() > 0) { + methodBuilder.addJavadoc( + " use get$NOutput(transactionReceipt) to get outputs \n", + StringUtils.capitaliseFirstLetter(functionDefinition.getName())); + } + DocUtils.addReturnsComments(" tuple", method, methodBuilder); + } + return methodBuilder.build(); } @@ -786,6 +808,33 @@ private MethodSpec buildFunctionWithCallback(ABIDefinition functionDefinition) buildTransactionFunctionWithCallback(functionDefinition, methodBuilder, inputParams); } + Devdoc.Method method = DocUtils.getMethod(devdoc, functionDefinition); + DocUtils.addMethodComments(method, methodBuilder); + DocUtils.addParamsComments(method, methodBuilder); + if (functionDefinition.isConstant()) { + // add comments for constant call callback + methodBuilder.addJavadoc( + "@param callback Get method outputs from constant call callback onResponse(List types) \n"); + + // add comments for constant call callback outputs + DocUtils.addReturnsComments(" callback.onResponse(types)", method, methodBuilder); + } else { + // add comments for transaction call callback + methodBuilder.addJavadoc( + "@param callback Get TransactionReceipt from TransactionCallback onResponse(TransactionReceipt receipt) \n"); + + if (functionDefinition.getOutputs().size() > 0) { + methodBuilder.addJavadoc( + " use get$NOutput(transactionReceipt) to get outputs \n", + StringUtils.capitaliseFirstLetter(functionDefinition.getName())); + } + + // add comments for how to get outputs in transaction call callback + DocUtils.addReturnsComments(" tuple", method, methodBuilder); + methodBuilder.addJavadoc( + "@return txHash Transaction hash of current transaction call \n"); + } + return methodBuilder.build(); } diff --git a/src/main/java/org/fisco/bcos/codegen/v3/utils/Devdoc.java b/src/main/java/org/fisco/bcos/codegen/v3/utils/Devdoc.java new file mode 100644 index 0000000..69a9775 --- /dev/null +++ b/src/main/java/org/fisco/bcos/codegen/v3/utils/Devdoc.java @@ -0,0 +1,54 @@ +package org.fisco.bcos.codegen.v3.utils; + +import java.util.Map; + +public class Devdoc { + private String details; + private Map methods; + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Map getMethods() { + return methods; + } + + public void setMethods(Map methods) { + this.methods = methods; + } + + public static class Method { + private String details; + private Map params; + private Map returns; + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } + + public Map getReturns() { + return returns; + } + + public void setReturns(Map returns) { + this.returns = returns; + } + } +} diff --git a/src/main/java/org/fisco/bcos/codegen/v3/utils/DocUtils.java b/src/main/java/org/fisco/bcos/codegen/v3/utils/DocUtils.java new file mode 100644 index 0000000..a62dc93 --- /dev/null +++ b/src/main/java/org/fisco/bcos/codegen/v3/utils/DocUtils.java @@ -0,0 +1,74 @@ +package org.fisco.bcos.codegen.v3.utils; + +import com.squareup.javapoet.MethodSpec; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import org.fisco.bcos.codegen.v3.exceptions.CodeGenException; +import org.fisco.bcos.sdk.v3.codec.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.v3.transaction.tools.JsonUtils; +import org.fisco.bcos.sdk.v3.utils.StringUtils; + +public class DocUtils { + + public static Devdoc.Method getMethod(Devdoc devdoc, ABIDefinition functionDefinition) { + if (devdoc != null && devdoc.getMethods() != null) { + return devdoc.getMethods().get(functionDefinition.getMethodSignatureAsString()); + } + + return null; + } + + public static void addMethodComments(Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for method + if (!StringUtils.isEmpty(method.getDetails())) { + methodBuilder.addJavadoc("$L \n", method.getDetails()); + } + } + + public static void addParamsComments(Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for params + Map params = method.getParams(); + if (params != null) { + for (String p : params.keySet()) { + if (!StringUtils.isEmpty(params.get(p))) { + methodBuilder.addJavadoc("@param $N $L \n", p, params.get(p)); + } + } + } + } + + public static void addReturnsComments( + String comments, Devdoc.Method method, MethodSpec.Builder methodBuilder) { + if (method == null) { + return; + } + + // add comments for returns + Map returns = method.getReturns(); + if (returns != null) { + for (String r : returns.keySet()) { + if (!StringUtils.isEmpty(returns.get(r))) { + methodBuilder.addJavadoc("$L $N $L \n", comments, r, returns.get(r)); + } + } + } + } + + public static Devdoc convertDevDoc(File devdocFile) throws CodeGenException, IOException { + if (devdocFile != null && devdocFile.exists()) { + byte[] devdocBytes = CodeGenUtils.readBytes(devdocFile); + return JsonUtils.fromJson(new String(devdocBytes), Devdoc.class); + } else { + return null; + } + } +} diff --git a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractGenerator.java b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractGenerator.java index 6909893..eda90a5 100644 --- a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractGenerator.java +++ b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractGenerator.java @@ -20,6 +20,7 @@ import java.util.Arrays; import org.fisco.bcos.codegen.v3.exceptions.CodeGenException; import org.fisco.bcos.codegen.v3.utils.CodeGenUtils; +import org.fisco.bcos.codegen.v3.utils.DocUtils; /** Java wrapper source code generator for Solidity ABI format. */ public class ContractGenerator { @@ -37,6 +38,7 @@ public class ContractGenerator { * generate deploy methods. * -s, --smBinFile= sm bin file with contract compiled code in order to * generate deploy methods. + * -d, --devdoc= solidity devdoc file generated by NatSpec style comments. * -o, --outputDir= * destination base directory. * -p, --package= @@ -49,6 +51,7 @@ public class ContractGenerator { private final File binFile; private final File smBinFile; private final File abiFile; + private final File devdocFile; private final File destinationDir; private String basePackageName; @@ -59,11 +62,13 @@ public ContractGenerator( File binFile, File smBinFile, File abiFile, + File devdocFile, File destinationDir, String basePackageName) { this.binFile = binFile; this.smBinFile = smBinFile; this.abiFile = abiFile; + this.devdocFile = devdocFile; this.destinationDir = destinationDir; this.basePackageName = basePackageName; } @@ -72,10 +77,11 @@ public ContractGenerator( File binFile, File smBinFile, File abiFile, + File devdocFile, File destinationDir, String basePackageName, boolean enableAsyncCall) { - this(binFile, smBinFile, abiFile, destinationDir, basePackageName); + this(binFile, smBinFile, abiFile, devdocFile, destinationDir, basePackageName); this.enableAsyncCall = enableAsyncCall; } @@ -83,11 +89,19 @@ public ContractGenerator( File binFile, File smBinFile, File abiFile, + File devdocFile, File destinationDir, String basePackageName, boolean enableAsyncCall, int transactionVersion) { - this(binFile, smBinFile, abiFile, destinationDir, basePackageName, enableAsyncCall); + this( + binFile, + smBinFile, + abiFile, + devdocFile, + destinationDir, + basePackageName, + enableAsyncCall); this.transactionVersion = transactionVersion; } @@ -114,6 +128,7 @@ public void generateJavaFiles() throws CodeGenException, IOException, ClassNotFo new String(binary), new String(smBinary), new String(abiBytes), + DocUtils.convertDevDoc(devdocFile), destinationDir.toString(), basePackageName, enableAsyncCall, diff --git a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java index 0b9c6a2..1a86739 100644 --- a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java +++ b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java @@ -30,6 +30,8 @@ import javax.lang.model.element.Modifier; import org.fisco.bcos.codegen.CodeGenMain; import org.fisco.bcos.codegen.v3.utils.CodeGenUtils; +import org.fisco.bcos.codegen.v3.utils.Devdoc; +import org.fisco.bcos.codegen.v3.utils.DocUtils; import org.fisco.bcos.sdk.v3.client.Client; import org.fisco.bcos.sdk.v3.client.protocol.model.TransactionAttribute; import org.fisco.bcos.sdk.v3.codec.datatypes.Address; @@ -105,6 +107,7 @@ public class ContractWrapper { private boolean enableAsyncCall = false; private int transactionVersion = 0; + private Devdoc devdoc; public ContractWrapper(boolean isWasm) { this.isWasm = isWasm; @@ -115,6 +118,7 @@ public void generateJavaFiles( String bin, String smBin, String abi, + Devdoc devdoc, String destinationDir, String basePackageName, boolean enableAsyncCall, @@ -122,6 +126,7 @@ public void generateJavaFiles( throws IOException, ClassNotFoundException, UnsupportedOperationException { this.enableAsyncCall = enableAsyncCall; this.transactionVersion = transactionVersion; + this.devdoc = devdoc; String[] nameParts = contractName.split("_"); for (int i = 0; i < nameParts.length; ++i) { nameParts[i] = StringUtils.capitaliseFirstLetter(nameParts[i]); @@ -186,21 +191,28 @@ protected void write(String packageName, TypeSpec typeSpec, String destinationDi private TypeSpec.Builder createClassBuilder( String className, String binary, String smBinary, String abi) { - return TypeSpec.classBuilder(className) - .addModifiers(Modifier.PUBLIC) - .superclass(Contract.class) - .addAnnotation( - AnnotationSpec.builder(SuppressWarnings.class) - .addMember("value", "$S", "unchecked") - .build()) - // binary fields - .addField(this.createArrayDefinition(BINARY_ARRAY_NAME, binary)) - .addField(this.createDefinition(BINARY_NAME, BINARY_ARRAY_NAME)) - .addField(this.createArrayDefinition(SM_BINARY_ARRAY_NAME, smBinary)) - .addField(this.createDefinition(SM_BINARY_NAME, SM_BINARY_ARRAY_NAME)) - // abi fields - .addField(this.createArrayDefinition(ABI_ARRAY_NAME, abi)) - .addField(this.createDefinition(ABI_NAME, ABI_ARRAY_NAME)); + TypeSpec.Builder builder = + TypeSpec.classBuilder(className) + .addModifiers(Modifier.PUBLIC) + .superclass(Contract.class) + .addAnnotation( + AnnotationSpec.builder(SuppressWarnings.class) + .addMember("value", "$S", "unchecked") + .build()) + // binary fields + .addField(this.createArrayDefinition(BINARY_ARRAY_NAME, binary)) + .addField(this.createDefinition(BINARY_NAME, BINARY_ARRAY_NAME)) + .addField(this.createArrayDefinition(SM_BINARY_ARRAY_NAME, smBinary)) + .addField(this.createDefinition(SM_BINARY_NAME, SM_BINARY_ARRAY_NAME)) + // abi fields + .addField(this.createArrayDefinition(ABI_ARRAY_NAME, abi)) + .addField(this.createDefinition(ABI_NAME, ABI_ARRAY_NAME)); + + if (this.devdoc != null && !StringUtils.isEmpty(this.devdoc.getDetails())) { + builder.addJavadoc(this.devdoc.getDetails()); + } + + return builder; } public List stringToArrayString(String binary) { @@ -1217,6 +1229,23 @@ private MethodSpec buildFunction(ABIDefinition functionDefinition) } this.buildTransactionFunction(functionDefinition, methodBuilder, inputParams); } + + Devdoc.Method method = DocUtils.getMethod(devdoc, functionDefinition); + DocUtils.addMethodComments(method, methodBuilder); + DocUtils.addParamsComments(method, methodBuilder); + if (functionDefinition.isConstant()) { + DocUtils.addReturnsComments("@return", method, methodBuilder); + } else { + methodBuilder.addJavadoc( + "@return TransactionReceipt Get more transaction info (e.g. txhash, block) from TransactionReceipt \n"); + if (functionDefinition.getOutputs().size() > 0) { + methodBuilder.addJavadoc( + " use get$NOutput(transactionReceipt) to get outputs \n", + StringUtils.capitaliseFirstLetter(functionDefinition.getName())); + } + DocUtils.addReturnsComments(" tuple", method, methodBuilder); + } + return methodBuilder.build(); } @@ -1271,6 +1300,33 @@ private MethodSpec buildFunctionWithCallback(ABIDefinition functionDefinition) functionDefinition, methodBuilder, inputParams); } + Devdoc.Method method = DocUtils.getMethod(devdoc, functionDefinition); + DocUtils.addMethodComments(method, methodBuilder); + DocUtils.addParamsComments(method, methodBuilder); + if (functionDefinition.isConstant()) { + // add comments for constant call callback + methodBuilder.addJavadoc( + "@param callback Get method outputs from constant call callback onResponse(List types) \n"); + + // add comments for constant call callback outputs + DocUtils.addReturnsComments(" callback.onResponse(types)", method, methodBuilder); + } else { + // add comments for transaction call callback + methodBuilder.addJavadoc( + "@param callback Get TransactionReceipt from TransactionCallback onResponse(TransactionReceipt receipt) \n"); + + if (functionDefinition.getOutputs().size() > 0) { + methodBuilder.addJavadoc( + " use get$NOutput(transactionReceipt) to get outputs \n", + StringUtils.capitaliseFirstLetter(functionDefinition.getName())); + } + + // add comments for how to get outputs in transaction call callback + DocUtils.addReturnsComments(" tuple", method, methodBuilder); + methodBuilder.addJavadoc( + "@return txHash Transaction hash of current transaction call \n"); + } + return methodBuilder.build(); } 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 5c52ce0..fa36f70 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 @@ -130,6 +130,12 @@ public void eventTestCodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void docTestCodeGen() throws IOException { + final String CONTRACT_NAME = "ERC721"; + codeGenDocTest(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(); @@ -184,4 +190,68 @@ private void codeGenTest(String abiFileName, String contractName) throws IOExcep collector.getDiagnostics().forEach(log -> System.out.println(log.toString())); Assert.assertTrue(call); } + + private void codeGenDocTest(String contractName) throws IOException { + String abiFile = + CodeGenV2Test.class.getClassLoader().getResource(contractName + ".abi").getPath(); + String binFile = + CodeGenV2Test.class.getClassLoader().getResource(contractName + ".abi").getPath(); + String docFile = + CodeGenV2Test.class + .getClassLoader() + .getResource(contractName + ".devdoc") + .getPath(); + String javaOutPut = new File(abiFile).getParent() + File.separator + JAVA_OUTPUT_DIR; + CodeGenMain.main( + Arrays.asList( + "-v", + "V2", + "-a", + abiFile, + "-b", + binFile, + "-s", + binFile, + "-d", + docFile, + "-p", + DEFAULT_PACKAGE, + "-o", + javaOutPut, + "-e") + .toArray(new String[0])); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticCollector collector = new DiagnosticCollector<>(); + JavaFileManager javaFileManager = + compiler.getStandardFileManager(collector, null, StandardCharsets.UTF_8); + String codeFileName = + javaOutPut + + File.separator + + File.separator + + DEFAULT_PACKAGE + + File.separator + + contractName + + ".java"; + + File codeFile = new File(codeFileName); + Long fileLength = codeFile.length(); + byte[] fileContent = new byte[fileLength.intValue()]; + FileInputStream in = new FileInputStream(codeFile); + in.read(fileContent); + in.close(); + String code = new String(fileContent, StandardCharsets.UTF_8); + + JavaFileObject myJavaFileObject = new MyJavaFileObject(contractName, code); + Boolean call = + compiler.getTask( + null, + javaFileManager, + collector, + null, + null, + Collections.singletonList(myJavaFileObject)) + .call(); + collector.getDiagnostics().forEach(log -> System.out.println(log.toString())); + Assert.assertTrue(call); + } } diff --git a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java index 6808fc3..884e587 100644 --- a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java +++ b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java @@ -166,6 +166,12 @@ public void payableTestCodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void docTestCodeGen() throws IOException { + final String CONTRACT_NAME = "ERC721"; + codeGenDocTest(CONTRACT_NAME); + } + private void codeGenTest(String abiFileName, String contractName) throws IOException { codeGenTest(abiFileName, abiFileName, contractName); } @@ -229,4 +235,72 @@ private void codeGenTest(String abiFileName, String codeFilePath, String contrac collector.getDiagnostics().forEach(log -> System.out.println(log.toString())); Assert.assertTrue(call); } + + private void codeGenDocTest(String contractName) throws IOException { + String abiFile = + CodeGenV3Test.class.getClassLoader().getResource(contractName + ".abi").getPath(); + String binFile = + CodeGenV3Test.class.getClassLoader().getResource(contractName + ".abi").getPath(); + String docFile = + CodeGenV3Test.class + .getClassLoader() + .getResource(contractName + ".devdoc") + .getPath(); + String javaOutPut = new File(abiFile).getParent() + File.separator + JAVA_OUTPUT_DIR; + ArrayList args = + new ArrayList<>( + Arrays.asList( + "-v", + "V3", + "-a", + abiFile, + "-b", + binFile, + "-s", + binFile, + "-d", + docFile, + "-p", + DEFAULT_PACKAGE, + "-o", + javaOutPut, + "-e")); + + args.add("-t"); + args.add(txVersion); + CodeGenMain.main(args.toArray(new String[0])); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticCollector collector = new DiagnosticCollector<>(); + JavaFileManager javaFileManager = + compiler.getStandardFileManager(collector, null, StandardCharsets.UTF_8); + String codeFileName = + javaOutPut + + File.separator + + File.separator + + DEFAULT_PACKAGE + + File.separator + + contractName + + ".java"; + + File codeFile = new File(codeFileName); + Long fileLength = codeFile.length(); + byte[] fileContent = new byte[fileLength.intValue()]; + FileInputStream in = new FileInputStream(codeFile); + in.read(fileContent); + in.close(); + String code = new String(fileContent, StandardCharsets.UTF_8); + + JavaFileObject myJavaFileObject = new MyJavaFileObject(contractName, code); + Boolean call = + compiler.getTask( + null, + javaFileManager, + collector, + null, + null, + Collections.singletonList(myJavaFileObject)) + .call(); + collector.getDiagnostics().forEach(log -> System.out.println(log.toString())); + Assert.assertTrue(call); + } } diff --git a/src/test/resources/ERC721.abi b/src/test/resources/ERC721.abi new file mode 100644 index 0000000..81ce652 --- /dev/null +++ b/src/test/resources/ERC721.abi @@ -0,0 +1,274 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_approved", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/test/resources/ERC721.devdoc b/src/test/resources/ERC721.devdoc new file mode 100644 index 0000000..8a91ea5 --- /dev/null +++ b/src/test/resources/ERC721.devdoc @@ -0,0 +1,84 @@ +{ + "details": "ERC-721 non-fungible token standard.", + "methods": { + "approve(address,uint256)": { + "details": "Set or reaffirm the approved address for an NFT. This function can be changed to payable.", + "params": { + "_approved": "The new approved NFT controller.", + "_tokenId": "The NFT to approve." + } + }, + "balanceOf(address)": { + "details": "Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are considered invalid, and this function throws for queries about the zero address.", + "params": { + "_owner": "Address for whom to query the balance." + }, + "returns": { + "_0": "Balance of _owner." + } + }, + "getApproved(uint256)": { + "details": "Get the approved address for a single NFT.", + "params": { + "_tokenId": "The NFT to find the approved address for." + }, + "returns": { + "_0": "Address that _tokenId is approved for." + } + }, + "isApprovedForAll(address,address)": { + "details": "Returns true if `_operator` is an approved operator for `_owner`, false otherwise.", + "params": { + "_operator": "The address that acts on behalf of the owner.", + "_owner": "The address that owns the NFTs." + }, + "returns": { + "_0": "True if approved for all, false otherwise." + } + }, + "ownerOf(uint256)": { + "details": "Returns the address of the owner of the NFT. NFTs assigned to the zero address are considered invalid, and queries about them do throw.", + "params": { + "_tokenId": "The identifier for an NFT." + }, + "returns": { + "_0": "Address of _tokenId owner." + } + }, + "safeTransferFrom(address,address,uint256)": { + "details": "Transfers the ownership of an NFT from one address to another address. This function can be changed to payable.", + "params": { + "_from": "The current owner of the NFT.", + "_to": "The new owner.", + "_tokenId": "The NFT to transfer." + } + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "details": "Transfers the ownership of an NFT from one address to another address. This function can be changed to payable.", + "params": { + "_data": "Additional data with no specified format, sent in call to `_to`.", + "_from": "The current owner of the NFT.", + "_to": "The new owner.", + "_tokenId": "The NFT to transfer." + }, + "returns": { + "_0": "Address of _tokenId owner." + } + }, + "setApprovalForAll(address,bool)": { + "details": "Enables or disables approval for a third party (\"operator\") to manage all of `msg.sender`'s assets. It also emits the ApprovalForAll event.", + "params": { + "_approved": "True if the operators is approved, false to revoke approval.", + "_operator": "Address to add to the set of authorized operators." + } + }, + "transferFrom(address,address,uint256)": { + "details": "Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable.", + "params": { + "_from": "The current owner of the NFT.", + "_to": "The new owner.", + "_tokenId": "The NFT to transfer." + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/ERC721.userdoc b/src/test/resources/ERC721.userdoc new file mode 100644 index 0000000..4d4082e --- /dev/null +++ b/src/test/resources/ERC721.userdoc @@ -0,0 +1,31 @@ +{ + "methods": { + "approve(address,uint256)": { + "notice": "The zero address indicates there is no approved address. Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner." + }, + "balanceOf(address)": { + "notice": "Count all NFTs assigned to an owner." + }, + "getApproved(uint256)": { + "notice": "Throws if `_tokenId` is not a valid NFT." + }, + "isApprovedForAll(address,address)": { + "notice": "Query if an address is an authorized operator for another address." + }, + "ownerOf(uint256)": { + "notice": "Find the owner of an NFT." + }, + "safeTransferFrom(address,address,uint256)": { + "notice": "This works identically to the other function with an extra data parameter, except this function just sets data to \"\"" + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "notice": "Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this function checks if `_to` is a smart contract (code size > 0). If so, it calls `onERC721Received` on `_to` and throws if the return value is not `bytes4(keccak256(\"onERC721Received(address,uint256,bytes)\"))`." + }, + "setApprovalForAll(address,bool)": { + "notice": "The contract MUST allow multiple operators per owner." + }, + "transferFrom(address,address,uint256)": { + "notice": "The caller is responsible to confirm that `_to` is capable of receiving NFTs or else they may be permanently lost." + } + } +} \ No newline at end of file From 3866d6928b2e13a6ce77dc6b2014a0b93dcfd518 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:27:08 +0800 Subject: [PATCH 2/3] (V2,V3): fix call get struct value bug. (#41) --- .github/workflows/workflow.yml | 2 +- build.gradle | 12 +-- .../org/fisco/bcos/codegen/CodeGenMain.java | 1 + .../v2/wrapper/SolidityContractWrapper.java | 83 +++++++------------ .../codegen/v3/wrapper/ContractWrapper.java | 74 ++--------------- .../bcos/codegen/v2/test/CodeGenV2Test.java | 7 ++ .../bcos/codegen/v3/test/CodeGenV3Test.java | 7 ++ src/test/resources/IRechargeV2.abi | 1 + 8 files changed, 62 insertions(+), 125 deletions(-) create mode 100644 src/test/resources/IRechargeV2.abi diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 7ef2c48..2c06c01 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -28,7 +28,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-latest] + os: [macos-12] steps: - uses: actions/checkout@v2 with: diff --git a/build.gradle b/build.gradle index 85e5e15..aa4e777 100644 --- a/build.gradle +++ b/build.gradle @@ -24,15 +24,15 @@ ext { ossrhPassword = "xxx" } // jackson version - jacksonVersion = '2.14.1' + jacksonVersion = '2.17.0' javapoetVersion = '1.13.0' - picocliVersion = '4.6.1' + picocliVersion = '4.7.6' junitVersion = '4.13.2' - commonsLang3Version = '3.12.0' + commonsLang3Version = '3.14.0' javaSDKVersion3 = "3.7.0" javaSDKVersion2 = "2.10.0" - slf4jVersion = "1.7.32" + slf4jVersion = "1.7.36" } sourceSets { @@ -54,7 +54,7 @@ configurations.all { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.code-generator' - version = '1.5.0' + version = '1.6.0-SNAPSHOT' apply plugin: 'maven-publish' apply plugin: 'idea' apply plugin: 'eclipse' @@ -86,7 +86,7 @@ allprojects { api("org.slf4j:slf4j-api:${slf4jVersion}") api("org.apache.commons:commons-lang3:${commonsLang3Version}") testImplementation("junit:junit:${junitVersion}") - testImplementation("org.mockito:mockito-core:4.6.0") + testImplementation('org.mockito:mockito-core:5.11.0') } clean.doLast { diff --git a/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java b/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java index 3bd71a1..0c7e6b7 100644 --- a/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java +++ b/src/main/java/org/fisco/bcos/codegen/CodeGenMain.java @@ -147,6 +147,7 @@ public void run() { packageName) .generateJavaFiles(); } catch (Exception e) { + e.printStackTrace(); org.fisco.bcos.codegen.v2.utils.CodeGenUtils.exitError(e); } } else if (version.equals(Version.V3)) { 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 29af75d..b2e6637 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 @@ -910,9 +910,10 @@ private MethodSpec buildFunctionWithInputDecoder( List.class, FunctionReturnDecoder.class); - buildTupleResultContainer0( + buildTupleResultContainer( methodBuilder, parameterizedTupleType, + inputTypes, buildTypeNames(functionDefinition.getInputs())); return methodBuilder.build(); @@ -963,9 +964,10 @@ private MethodSpec buildFunctionWithOutputDecoder( List.class, FunctionReturnDecoder.class); - buildTupleResultContainer0( + buildTupleResultContainer( methodBuilder, parameterizedTupleType, + outputTypes, buildTypeNames(functionDefinition.getOutputs())); return methodBuilder.build(); @@ -1070,7 +1072,15 @@ private void buildConstantFunction( buildVariableLengthReturnFunctionConstructor( methodBuilder, functionName, inputParams, outputParameterTypes); - buildTupleResultContainer(methodBuilder, parameterizedTupleType, outputParameterTypes); + methodBuilder.addStatement( + "$T results = executeCallWithMultipleValueReturn(function)", + ParameterizedTypeName.get( + List.class, org.fisco.bcos.sdk.abi.datatypes.Type.class)); + buildTupleResultContainer( + methodBuilder, + parameterizedTupleType, + functionDefinition.getOutputs(), + outputParameterTypes); } } @@ -1497,31 +1507,33 @@ private static void buildVariableLengthReturnFunctionConstructor( private void buildTupleResultContainer( MethodSpec.Builder methodBuilder, ParameterizedTypeName tupleType, + List namedTypes, List outputParameterTypes) { List typeArguments = tupleType.typeArguments; - CodeBlock.Builder tupleConstructor = CodeBlock.builder(); - tupleConstructor - .addStatement( - "$T results = executeCallWithMultipleValueReturn(function)", - ParameterizedTypeName.get(List.class, Type.class)) - .add("return new $T(", tupleType) - .add("$>$>"); + CodeBlock.Builder codeBuilder = CodeBlock.builder(); String resultStringSimple = "\n($T) results.get($L)"; - resultStringSimple += ".getValue()"; + String getValueString = ".getValue()"; String resultStringNativeList = "\nconvertToNative(($T) results.get($L).getValue())"; + String dynamicResultStringList = + "\nnew DynamicArray<>($T.class,($T) results.get($L).getValue())"; int size = typeArguments.size(); ClassName classList = ClassName.get(List.class); + ClassName dynamicArray = ClassName.get(org.fisco.bcos.sdk.abi.datatypes.DynamicArray.class); + ClassName staticArray = ClassName.get(org.fisco.bcos.sdk.abi.datatypes.StaticArray.class); for (int i = 0; i < size; i++) { TypeName param = outputParameterTypes.get(i); TypeName convertTo = typeArguments.get(i); - + ABIDefinition.NamedType namedType = namedTypes.get(i); String resultString = resultStringSimple; + if (!namedType.getType().contains("tuple")) { + resultString += getValueString; + } // If we use native java types we need to convert // elements of arrays to native java types too @@ -1534,50 +1546,15 @@ private void buildTupleResultContainer( ParameterizedTypeName.get(classList, oldContainer.typeArguments.get(0)); resultString = resultStringNativeList; } - } - - tupleConstructor.add(resultString, convertTo, i); - tupleConstructor.add(i < size - 1 ? ", " : ");\n"); - } - tupleConstructor.add("$<$<"); - methodBuilder.returns(tupleType).addCode(tupleConstructor.build()); - } - - private void buildTupleResultContainer0( - MethodSpec.Builder methodBuilder, - ParameterizedTypeName tupleType, - List outputParameterTypes) { - - List typeArguments = tupleType.typeArguments; - - CodeBlock.Builder codeBuilder = CodeBlock.builder(); - - String resultStringSimple = "\n($T) results.get($L)"; - String resultGetValue = ".getValue()"; - - String resultStringNativeList = "\nconvertToNative(($T) results.get($L).getValue())"; - - int size = typeArguments.size(); - 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 + resultGetValue; - - // If we use native java types we need to convert - // elements of arrays to native java types too - if (param.equals(convertTo)) { - resultString = resultStringSimple; - } else if (param instanceof ParameterizedTypeName) { - ParameterizedTypeName oldContainer = (ParameterizedTypeName) param; - ParameterizedTypeName newContainer = (ParameterizedTypeName) convertTo; - if (newContainer.rawType.compareTo(classList) == 0 + if ((newContainer.rawType.compareTo(dynamicArray) == 0 + || newContainer.rawType.compareTo(staticArray) == 0) && newContainer.typeArguments.size() == 1) { + resultString = dynamicResultStringList; convertTo = ParameterizedTypeName.get(classList, oldContainer.typeArguments.get(0)); - resultString = resultStringNativeList; + codeBuilder.add(resultString, oldContainer.typeArguments.get(0), convertTo, i); + codeBuilder.add(i < size - 1 ? ", " : "\n"); + continue; } } diff --git a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java index 1a86739..8a31ecb 100644 --- a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java +++ b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java @@ -1399,7 +1399,7 @@ private MethodSpec buildFunctionWithInputDecoder( "$T results = this.functionReturnDecoder.decode(data, function.getOutputParameters())", List.class); - this.buildTupleResultContainer0( + this.buildTupleResultContainer( methodBuilder, parameterizedTupleType, inputTypes, @@ -1450,7 +1450,7 @@ private MethodSpec buildFunctionWithOutputDecoder( "$T results = this.functionReturnDecoder.decode(data, function.getOutputParameters())", List.class); - this.buildTupleResultContainer0( + this.buildTupleResultContainer( methodBuilder, parameterizedTupleType, outputTypes, @@ -1769,8 +1769,14 @@ private void buildConstantFunction( buildVariableLengthReturnFunctionConstructor( methodBuilder, functionName, inputParams, outputParameterTypes); + methodBuilder.addStatement( + "$T results = executeCallWithMultipleValueReturn(function)", + ParameterizedTypeName.get(List.class, Type.class)); this.buildTupleResultContainer( - methodBuilder, parameterizedTupleType, outputParameterTypes); + methodBuilder, + parameterizedTupleType, + functionDefinition.getOutputs(), + outputParameterTypes); } } @@ -2230,68 +2236,6 @@ private static void buildVariableLengthReturnFunctionConstructor( } private void buildTupleResultContainer( - MethodSpec.Builder methodBuilder, - ParameterizedTypeName tupleType, - List outputParameterTypes) { - - List typeArguments = tupleType.typeArguments; - - CodeBlock.Builder tupleConstructor = CodeBlock.builder(); - tupleConstructor - .addStatement( - "$T results = executeCallWithMultipleValueReturn(function)", - ParameterizedTypeName.get(List.class, Type.class)) - .add("return new $T(", tupleType) - .add("$>$>"); - - String resultStringSimple = "\n($T) results.get($L)"; - resultStringSimple += ".getValue()"; - - String resultStringNativeList = "\nconvertToNative(($T) results.get($L).getValue())"; - String dynamicResultStringList = - "\nnew DynamicArray<>($T.class,($T) results.get($L).getValue())"; - - int size = typeArguments.size(); - ClassName classList = ClassName.get(List.class); - ClassName dynamicArray = ClassName.get(DynamicArray.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 (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; - } - if (newContainer.rawType.compareTo(dynamicArray) == 0 - && newContainer.typeArguments.size() == 1) { - resultString = dynamicResultStringList; - convertTo = - ParameterizedTypeName.get(classList, oldContainer.typeArguments.get(0)); - tupleConstructor.add( - resultString, oldContainer.typeArguments.get(0), convertTo, i); - tupleConstructor.add(i < size - 1 ? ", " : ");\n"); - continue; - } - } - - tupleConstructor.add(resultString, convertTo, i); - tupleConstructor.add(i < size - 1 ? ", " : ");\n"); - } - tupleConstructor.add("$<$<"); - methodBuilder.returns(tupleType).addCode(tupleConstructor.build()); - } - - private void buildTupleResultContainer0( MethodSpec.Builder methodBuilder, ParameterizedTypeName tupleType, List namedTypes, 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 fa36f70..b399ead 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 @@ -100,6 +100,13 @@ public void codecTestABICodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void RechargeTestCodeGen() throws IOException { + final String ABI_FILE = "IRechargeV2.abi"; + final String CONTRACT_NAME = "IRechargeV2"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + @Test public void weidABICodeGen() throws IOException { final String ABI_FILE = "Weid.abi"; diff --git a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java index 884e587..07ebaea 100644 --- a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java +++ b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java @@ -166,6 +166,13 @@ public void payableTestCodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void RechargeTestCodeGen() throws IOException { + final String ABI_FILE = "IRechargeV2.abi"; + final String CONTRACT_NAME = "IRechargeV2"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + @Test public void docTestCodeGen() throws IOException { final String CONTRACT_NAME = "ERC721"; diff --git a/src/test/resources/IRechargeV2.abi b/src/test/resources/IRechargeV2.abi new file mode 100644 index 0000000..b0c61ea --- /dev/null +++ b/src/test/resources/IRechargeV2.abi @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"orderID","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"string[]","name":"cards","type":"string[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"BindCardsWithValues","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"orderID","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"string[]","name":"physicalCards","type":"string[]"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"BindPhysicalCards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"orderID","type":"string"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"CancelHistoryRechargeOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawID","type":"uint256"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"CancelWithdrawOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"orderID","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"CreateRechargeOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"txHash","type":"string"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"CreateWithdrawOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawID","type":"uint256"},{"indexed":false,"internalType":"string[]","name":"physicalCards","type":"string[]"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"WithdrawPhysicalCards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawOrderIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"txHash","type":"string"},{"indexed":false,"internalType":"string[]","name":"vCards","type":"string[]"},{"indexed":false,"internalType":"string","name":"extraData","type":"string"}],"name":"WithdrawVCards","type":"event"},{"inputs":[],"name":"_contractType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bac20Address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string[]","name":"_physicalCards","type":"string[]"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"bindHistoryPhysicalCards","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"string[]","name":"_physicalCards","type":"string[]"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"bindPhysicalCards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"cancelHistoryRechargeOrderByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"uint256","name":"_withdrawID","type":"uint256"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"cancelWithdrawOrderByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cardLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"createHistoryRechargeOrder","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"createRechargeOrder","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"createWithdrawOrder","outputs":[{"internalType":"uint256","name":"withdrawOrderIndex","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"internalType":"struct IRechargeV2.WithdrawOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_txHash","type":"string"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"createWithdrawOrderByAdmin","outputs":[{"internalType":"uint256","name":"withdrawOrderIndex","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"internalType":"struct IRechargeV2.WithdrawOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getFailedWithdrawOrderIndex","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_physicalCardID","type":"string"}],"name":"getPhysicalCard","outputs":[{"components":[{"internalType":"string","name":"rechargeOrderID","type":"string"},{"internalType":"address","name":"withdrawUser","type":"address"},{"internalType":"uint256","name":"withdrawIndex","type":"uint256"},{"internalType":"bool","name":"withdrawState","type":"bool"},{"internalType":"uint256","name":"inBlockHeight","type":"uint256"},{"internalType":"uint256","name":"outBlockHeight","type":"uint256"}],"internalType":"struct IRechargeV2.PhysicalCard","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"}],"name":"getRechargeOrder","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"getVCardNum","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVCardTotalRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"getVCards","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_txHash","type":"string"}],"name":"getWithdrawIndexAndOrderByTxHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"internalType":"struct IRechargeV2.WithdrawOrder","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getWithdrawOrder","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"internalType":"struct IRechargeV2.WithdrawOrder","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_txHash","type":"string"}],"name":"getWithdrawOrderByTxHash","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"internalType":"struct IRechargeV2.WithdrawOrder","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bac20Address","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"string[]","name":"_vCards","type":"string[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"rechargeHistoryVCard","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"}],"name":"rechargeOrderCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"orderId","type":"string"}],"name":"rechargeOrderExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_orderID","type":"string"},{"internalType":"string[]","name":"_vCards","type":"string[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"rechargeVCard","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"blockHeight","type":"uint256"},{"internalType":"string[]","name":"physicalCardSerials","type":"string[]"},{"internalType":"bool","name":"physicalCardBound","type":"bool"}],"internalType":"struct IRechargeV2.RechargeOrder","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardLimit","type":"uint256"}],"name":"setCardLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setContractType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalCashRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOutbound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSettledRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTransit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVCardRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVCardSettledRecharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"txHash","type":"string"}],"name":"txHashExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"userWithdrawIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawID","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"string[]","name":"_physicalCards","type":"string[]"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"withdrawPhysicalCards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"string","name":"_txHash","type":"string"},{"internalType":"string","name":"_extraData","type":"string"}],"name":"withdrawVCard","outputs":[{"internalType":"uint256","name":"withdrawOrderIndex","type":"uint256"},{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file From f5ed6aa2f69f5dbe459384374c36b681e14c4135 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:32:17 +0800 Subject: [PATCH 3/3] (project): upgrade to 1.6.0 (#42) --- build.gradle | 4 ++-- .../org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java | 2 ++ .../java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java | 7 +++++++ src/test/resources/ListEventTest.abi | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/ListEventTest.abi diff --git a/build.gradle b/build.gradle index aa4e777..d17bb46 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ ext { junitVersion = '4.13.2' commonsLang3Version = '3.14.0' - javaSDKVersion3 = "3.7.0" + javaSDKVersion3 = "3.8.0" javaSDKVersion2 = "2.10.0" slf4jVersion = "1.7.36" } @@ -54,7 +54,7 @@ configurations.all { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.code-generator' - version = '1.6.0-SNAPSHOT' + version = '1.6.0' apply plugin: 'maven-publish' apply plugin: 'idea' apply plugin: 'eclipse' diff --git a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java index 8a31ecb..5ef70f8 100644 --- a/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java +++ b/src/main/java/org/fisco/bcos/codegen/v3/wrapper/ContractWrapper.java @@ -2124,6 +2124,7 @@ private CodeBlock buildTypedResponse( } else { builder.addStatement("$L.log = eventValues.getLog()", objectName); } + // indexed for (int i = 0; i < indexedParameters.size(); i++) { final NamedTypeName namedTypeName = indexedParameters.get(i); String nativeConversion; @@ -2153,6 +2154,7 @@ private CodeBlock buildTypedResponse( i); } + // non-indexed for (int i = 0; i < nonIndexedParameters.size(); i++) { final NamedTypeName namedTypeName = nonIndexedParameters.get(i); String result = "$L.$L = ($T) eventValues.getNonIndexedValues().get($L)"; diff --git a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java index 07ebaea..e39736c 100644 --- a/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java +++ b/src/test/java/org/fisco/bcos/codegen/v3/test/CodeGenV3Test.java @@ -173,6 +173,13 @@ public void RechargeTestCodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void ListEventTestCodeGen() throws IOException { + final String ABI_FILE = "ListEventTest.abi"; + final String CONTRACT_NAME = "ListEventTest"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + @Test public void docTestCodeGen() throws IOException { final String CONTRACT_NAME = "ERC721"; diff --git a/src/test/resources/ListEventTest.abi b/src/test/resources/ListEventTest.abi new file mode 100644 index 0000000..9ee3f29 --- /dev/null +++ b/src/test/resources/ListEventTest.abi @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256[]","name":"","type":"int256[]"},{"indexed":false,"internalType":"string[]","name":"","type":"string[]"},{"indexed":false,"internalType":"uint256[]","name":"","type":"uint256[]"}],"name":"listEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"numbers","type":"event"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mockFunctionOutOfGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"n","type":"string"}],"name":"set","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"n","type":"string"}],"name":"testEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file