From 69920b65f078e098a76cbcf2735bb30e95b96ef8 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Sun, 2 Apr 2023 16:22:08 +0800 Subject: [PATCH 1/5] (v2,v3): fix v3 nested struct not generate bug, fix v2 generate bug, add v2 test. (#12) --- .../v2/wrapper/SolidityContractWrapper.java | 98 +++++++++--- .../codegen/v3/wrapper/ContractWrapper.java | 13 +- .../bcos/codegen/v2/test/CodeGenV2Test.java | 143 ++++++++++++++++++ src/test/resources/HelloWorld.abi | 2 +- 4 files changed, 234 insertions(+), 22 deletions(-) create mode 100644 src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java 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 08b0364..41c2907 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 @@ -104,7 +104,7 @@ public class SolidityContractWrapper { private static final Pattern pattern = Pattern.compile(regex); private static final String TUPLE_PACKAGE_NAME = - "org.fisco.bcos.sdk.codec.datatypes.generated.tuples.generated"; + "org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated"; private static final HashMap structClassNameMap = new HashMap<>(); private static final List structsNamedTypeList = new ArrayList<>(); @@ -569,9 +569,7 @@ private String createMappedParameterTypes(ParameterSpec parameterSpec) { + parameterSpecType + "(\n" + " " - + componentType - + ".class,\n" - + " org.fisco.bcos.sdk.codec.Utils.typeMap(" + + " org.fisco.bcos.sdk.abi.Utils.typeMap(" + parameterSpec.name + ", " + typeMapInput @@ -1560,8 +1558,11 @@ private List buildStructTypes(List functionDefinitions) if (namedType.getType().equals("tuple[]") && internalType.endsWith("[]")) { internalType = internalType.substring(0, internalType.lastIndexOf("[")); } - - structName = internalType.substring(internalType.lastIndexOf(" ") + 1); + if (internalType.contains(".")) { + structName = internalType.substring(internalType.lastIndexOf(".") + 1); + } else { + structName = internalType.substring(internalType.lastIndexOf(" ") + 1); + } } final TypeSpec.Builder builder = @@ -1586,6 +1587,7 @@ private List buildStructTypes(List functionDefinitions) + ")"); for (ABIDefinition.NamedType component : namedType.getComponents()) { + String getValue = ".getValue()"; if (component.getType().equals("tuple")) { final TypeName typeName = structClassNameMap.get(component.structIdentifier()); builder.addField(typeName, component.getName(), Modifier.PUBLIC); @@ -1597,6 +1599,21 @@ private List buildStructTypes(List functionDefinitions) builder.addField(typeName, component.getName(), Modifier.PUBLIC); constructorBuilder.addParameter(typeName, component.getName()); nativeConstructorBuilder.addParameter(typeName, component.getName()); + + getValue = ""; + } else if (component.getType().endsWith("]")) { + final TypeName typeName = buildTypeName(component.getType()); + final TypeName nativeTypeName = getNativeType(typeName); + builder.addField(nativeTypeName, component.getName(), Modifier.PUBLIC); + constructorBuilder.addParameter(typeName, component.getName()); + nativeConstructorBuilder.addParameter(nativeTypeName, component.getName()); + + ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName; + TypeName argumentType = parameterizedTypeName.typeArguments.get(0); + getValue += + ".stream().map(" + + argumentType + + "::getValue).collect(java.util.stream.Collectors.toList())"; } else { final TypeName typeName = buildTypeName(component.getType()); final TypeName nativeTypeName = getNativeType(typeName); @@ -1613,7 +1630,7 @@ private List buildStructTypes(List functionDefinitions) + component.getName() + (structClassNameMap.keySet().stream() .noneMatch(i -> i == component.structIdentifier()) - ? ".getValue()" + ? getValue : "")); } @@ -1656,17 +1673,21 @@ private List extractStructs( }) .forEach( namedType -> { - int structIdentifier = namedType.structIdentifier(); + int structIdentifier = getStructIdentifier(namedType); if (!structMap.containsKey(structIdentifier)) { structMap.put(structIdentifier, namedType); } extractNested(namedType).stream() .filter(this::isStructType) .forEach( - nestedNamedType -> + nestedNamedType -> { + int structIdentifier1 = + getStructIdentifier(nestedNamedType); + if (!structMap.containsKey(structIdentifier1)) { structMap.put( - nestedNamedType.structIdentifier(), - nestedNamedType)); + structIdentifier1, nestedNamedType); + } + }); }); return structMap.values().stream() @@ -1674,6 +1695,26 @@ private List extractStructs( .collect(Collectors.toList()); } + private static int getStructIdentifier(ABIDefinition.NamedType namedType) { + String typeIdentifier = + (namedType.getInternalType() == null || namedType.getInternalType().isEmpty()) + ? namedType.getType() + : namedType.getInternalType(); + if (typeIdentifier.endsWith("[]")) { + typeIdentifier = typeIdentifier.substring(0, typeIdentifier.indexOf('[')); + } + int structIdentifier = + (typeIdentifier + + namedType.getComponents().stream() + .map( + nestedNameType -> + String.valueOf( + nestedNameType.structIdentifier())) + .collect(Collectors.joining())) + .hashCode(); + return structIdentifier; + } + private ABIDefinition.NamedType normalizeNamedType(ABIDefinition.NamedType namedType) { if (namedType.getType().endsWith("[]") && namedType.getInternalType().endsWith("[]")) { return new ABIDefinition.NamedType( @@ -1726,14 +1767,33 @@ private String buildStructConstructorParameterDefinition( final ABIDefinition.NamedType component = components.get(i); stringBuilder.append(i > 0 ? "," : ""); if (useNativeJavaTypes) { - stringBuilder.append( - !component.getType().startsWith("tuple") - ? "new " - + buildTypeName(component.getType()) - + "(" - + component.getName() - + ")" - : component.getName()); + String state = ""; + if (component.getType().startsWith("tuple")) { + // if struct + state = component.getName(); + } else if (component.getType().endsWith("]")) { + // if list + ParameterizedTypeName typeName = + (ParameterizedTypeName) buildTypeName(component.getType()); + TypeName argumentType = typeName.typeArguments.get(0); + state = + "new " + + buildTypeName(component.getType()) + + "(" + + component.getName() + + ".stream().map(" + + argumentType + + "::new).collect(java.util.stream.Collectors.toList())" + + ")"; + } else { + state = + "new " + + buildTypeName(component.getType()) + + "(" + + component.getName() + + ")"; + } + stringBuilder.append(state); } else { stringBuilder.append(component.getName()); } 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 dbecda4..9b84a4b 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 @@ -514,8 +514,17 @@ private List extractStructs( if (!structMap.containsKey(structIdentifier)) { structMap.put(structIdentifier, namedType); } - // Note: structA in structB, structA must exist in struct map, so no - // need to exact struct again + extractNested(namedType).stream() + .filter(this::isStructType) + .forEach( + nestedNamedType -> { + if (!structMap.containsKey( + nestedNamedType.structIdentifier())) { + structMap.put( + nestedNamedType.structIdentifier(), + nestedNamedType); + } + }); }); return structMap.values().stream() 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 new file mode 100644 index 0000000..c6e0eb1 --- /dev/null +++ b/src/test/java/org/fisco/bcos/codegen/v2/test/CodeGenV2Test.java @@ -0,0 +1,143 @@ +package org.fisco.bcos.codegen.v2.test; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; +import org.fisco.bcos.codegen.CodeGenMain; +import org.junit.Assert; +import org.junit.Test; + +public class CodeGenV2Test { + private static final String JAVA_OUTPUT_DIR = "sdk"; + private static final String DEFAULT_PACKAGE = "com"; + + static class MyJavaFileObject extends SimpleJavaFileObject { + + private String source; + private ByteArrayOutputStream outputStream; + + /** + * Construct a SimpleJavaFileObject of the given kind and with the given URI. + * + * @param uri the URI for this file object + * @param kind the kind of this file object + */ + protected MyJavaFileObject(URI uri, Kind kind) { + super(uri, kind); + } + + public MyJavaFileObject(String name, String source) { + this(URI.create("String:///" + name + Kind.SOURCE.extension), Kind.SOURCE); + this.source = source; + } + + @Override + public OutputStream openOutputStream() throws IOException { + outputStream = new ByteArrayOutputStream(); + return outputStream; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + if (source == null) { + throw new IOException("Empty source"); + } + return source; + } + } + + @Test + public void complexABICodeGen() throws IOException { + final String COMPLEX_ABI_FILE = "ComplexCodecTest.abi"; + final String COMPLEX_NAME = "ComplexCodecTest"; + codeGenTest(COMPLEX_ABI_FILE, COMPLEX_NAME); + } + + @Test + public void tableABICodeGen() throws IOException { + final String ABI_FILE = "Table.abi"; + final String CONTRACT_NAME = "Table"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + + @Test + public void codecTestABICodeGen() throws IOException { + final String ABI_FILE = "CodecTest.abi"; + final String CONTRACT_NAME = "CodecTest"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + + @Test + public void weidABICodeGen() throws IOException { + final String ABI_FILE = "Weid.abi"; + final String CONTRACT_NAME = "Weid"; + 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(); + String javaOutPut = new File(abiFile).getParent() + File.separator + JAVA_OUTPUT_DIR; + CodeGenMain.main( + Arrays.asList( + "-v", + "V2", + "-a", + abiFile, + "-b", + binFile, + "-s", + binFile, + "-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/resources/HelloWorld.abi b/src/test/resources/HelloWorld.abi index 40d013f..4c6bf94 100644 --- a/src/test/resources/HelloWorld.abi +++ b/src/test/resources/HelloWorld.abi @@ -1 +1 @@ -[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"}],"indexed":false,"internalType":"struct HelloWorld.Test","name":"t","type":"tuple"}],"name":"Log","type":"event"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"}],"internalType":"struct HelloWorld.Test","name":"t","type":"tuple"}],"name":"set","outputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"}],"internalType":"struct HelloWorld.Test","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"n","type":"string"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"},{"components":[{"internalType":"string[]","name":"s","type":"string[]"}],"internalType":"struct HelloWorld.TestInSide","name":"t","type":"tuple"}],"indexed":false,"internalType":"struct HelloWorld.Test","name":"t","type":"tuple"}],"name":"Log","type":"event"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"},{"components":[{"internalType":"string[]","name":"s","type":"string[]"}],"internalType":"struct HelloWorld.TestInSide","name":"t","type":"tuple"}],"internalType":"struct HelloWorld.Test","name":"t","type":"tuple"}],"name":"set","outputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string[]","name":"s","type":"string[]"},{"internalType":"int256","name":"b","type":"int256"},{"components":[{"internalType":"string[]","name":"s","type":"string[]"}],"internalType":"struct HelloWorld.TestInSide","name":"t","type":"tuple"}],"internalType":"struct HelloWorld.Test","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file From d7a18f7c1d3f8e15b28dbd8bb0a70a941606292e Mon Sep 17 00:00:00 2001 From: kyonRay Date: Tue, 18 Apr 2023 15:10:38 +0800 Subject: [PATCH 2/5] (codegen): fix event overload and struct bug. --- .../codegen/v3/wrapper/ContractWrapper.java | 32 +++++++++++++++---- .../bcos/codegen/v3/test/CodeGenV3Test.java | 7 ++++ src/test/resources/EventSubDemo.abi | 1 + 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/EventSubDemo.abi 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 9b84a4b..c3ef8b1 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 @@ -229,9 +229,10 @@ private FieldSpec createDefinition(String type, String binaryArrayName) { .build(); } - private FieldSpec createEventDefinition(String name, List parameters) { + private FieldSpec createEventDefinition( + String rawEventName, String name, List parameters) { - CodeBlock initializer = buildVariableLengthEventInitializer(name, parameters); + CodeBlock initializer = buildVariableLengthEventInitializer(rawEventName, parameters); return FieldSpec.builder(Event.class, this.buildEventDefinitionName(name)) .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) @@ -258,6 +259,20 @@ private static boolean isOverLoadFunction( return count > 1; } + private static boolean isOverLoadEvent(String name, List functionDefinitions) { + int count = 0; + for (ABIDefinition functionDefinition : functionDefinitions) { + if (!functionDefinition.getType().equals("event")) { + continue; + } + + if (functionDefinition.getName().equals(name)) { + count += 1; + } + } + return count > 1; + } + private List buildFunctionDefinitions( TypeSpec.Builder classBuilder, List functionDefinitions) throws ClassNotFoundException { @@ -290,7 +305,11 @@ private List buildFunctionDefinitions( } } } else if (functionDefinition.getType().equals("event")) { - methodSpecs.addAll(this.buildEventFunctions(functionDefinition, classBuilder)); + boolean isOverloadEvent = + isOverLoadEvent(functionDefinition.getName(), functionDefinitions); + methodSpecs.addAll( + this.buildEventFunctions( + functionDefinition, classBuilder, isOverloadEvent)); } } @@ -1571,9 +1590,9 @@ private MethodSpec buildEventTransactionReceiptFunction( } private List buildEventFunctions( - ABIDefinition functionDefinition, TypeSpec.Builder classBuilder) + ABIDefinition functionDefinition, TypeSpec.Builder classBuilder, boolean isOverload) throws ClassNotFoundException { - String functionName = functionDefinition.getName(); + String functionName = getInputOutputFunctionName(functionDefinition, isOverload); List inputs = functionDefinition.getInputs(); String responseClassName = StringUtils.capitaliseFirstLetter(functionName) + "EventResponse"; @@ -1619,7 +1638,8 @@ private List buildEventFunctions( parameters.add(parameter); } - classBuilder.addField(this.createEventDefinition(functionName, parameters)); + classBuilder.addField( + this.createEventDefinition(functionDefinition.getName(), functionName, parameters)); classBuilder.addType( this.buildEventResponseObject( 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 7b4b3b1..9d36a51 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 @@ -116,6 +116,13 @@ public void liquidComplexCodeTestCodeGen() throws IOException { codeGenTest(ABI_FILE, codeFilePath, CONTRACT_NAME); } + @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 { codeGenTest(abiFileName, abiFileName, contractName); } diff --git a/src/test/resources/EventSubDemo.abi b/src/test/resources/EventSubDemo.abi new file mode 100644 index 0000000..e77a517 --- /dev/null +++ b/src/test/resources/EventSubDemo.abi @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"u","type":"uint256"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"i","type":"int256"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"s","type":"string"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"u","type":"uint256"},{"indexed":true,"internalType":"int256","name":"i","type":"int256"},{"indexed":true,"internalType":"string","name":"s","type":"string"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"bsn","type":"bytes32"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"bs","type":"bytes"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"bsn","type":"bytes32"},{"indexed":true,"internalType":"bytes","name":"bs","type":"bytes"}],"name":"Echo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"from_account","type":"string"},{"indexed":true,"internalType":"string","name":"to_account","type":"string"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"from_account","type":"string"},{"indexed":true,"internalType":"string","name":"to_account","type":"string"}],"name":"TransferAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferAmount","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"string","name":"from_account","type":"string"},{"internalType":"string","name":"to_account","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":true,"internalType":"struct EventSubDemo.TransferStruct[]","name":"ts","type":"tuple[]"}],"name":"TransferData","type":"event"},{"inputs":[{"internalType":"bytes32","name":"bsn","type":"bytes32"},{"internalType":"bytes","name":"bs","type":"bytes"}],"name":"echo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"u","type":"uint256"},{"internalType":"int256","name":"i","type":"int256"},{"internalType":"string","name":"s","type":"string"}],"name":"echo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"from_account","type":"string"},{"internalType":"string","name":"to_account","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file From 3f4218372cbeed6c898c61a4a3cd5ca7e222a322 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Mon, 29 May 2023 14:19:43 +0800 Subject: [PATCH 3/5] (v2): fix v2 struc bug, add test. (#18) --- .../v2/wrapper/SolidityContractWrapper.java | 118 ++++++++++++++---- .../bcos/codegen/v2/test/CodeGenV2Test.java | 22 ++++ 2 files changed, 117 insertions(+), 23 deletions(-) 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(); From d3127059e731ee8e81bf7b3a39755d6706ce20f3 Mon Sep 17 00:00:00 2001 From: kyonRay Date: Thu, 10 Aug 2023 14:19:43 +0800 Subject: [PATCH 4/5] (v2,v3): fix v3,v2 lib struct name compile error, fix v2 event overload bug. --- build.gradle | 2 +- .../v2/wrapper/SolidityContractWrapper.java | 54 ++++++++++++++----- .../codegen/v3/wrapper/ContractWrapper.java | 21 +++++--- .../bcos/codegen/v2/test/CodeGenV2Test.java | 19 ++++++- .../bcos/codegen/v3/test/CodeGenV3Test.java | 16 ++++++ src/test/resources/StructReqRespContract.abi | 1 + src/test/resources/SupplyChainFin.abi | 1 + 7 files changed, 93 insertions(+), 21 deletions(-) create mode 100644 src/test/resources/StructReqRespContract.abi create mode 100644 src/test/resources/SupplyChainFin.abi diff --git a/build.gradle b/build.gradle index 2a6d525..f2545b0 100644 --- a/build.gradle +++ b/build.gradle @@ -50,7 +50,7 @@ sourceSets { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.code-generator' - version = '1.1.0' + version = '1.2.0-SNAPSHOT' apply plugin: 'maven-publish' apply plugin: 'idea' apply plugin: 'eclipse' 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 5de004a..eb97518 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 @@ -241,9 +241,10 @@ private FieldSpec createDefinition(String type, String binayArrayName) { .build(); } - private FieldSpec createEventDefinition(String name, List parameters) { + private FieldSpec createEventDefinition( + String rawEventName, String name, List parameters) { - CodeBlock initializer = buildVariableLengthEventInitializer(name, parameters); + CodeBlock initializer = buildVariableLengthEventInitializer(rawEventName, parameters); return FieldSpec.builder(Event.class, buildEventDefinitionName(name)) .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) @@ -270,6 +271,20 @@ private static boolean isOverLoadFunction( return count > 1; } + private static boolean isOverLoadEvent(String name, List functionDefinitions) { + int count = 0; + for (ABIDefinition functionDefinition : functionDefinitions) { + if (!functionDefinition.getType().equals("event")) { + continue; + } + + if (functionDefinition.getName().equals(name)) { + count += 1; + } + } + return count > 1; + } + private List buildFunctionDefinitions( TypeSpec.Builder classBuilder, List functionDefinitions) throws ClassNotFoundException { @@ -302,7 +317,11 @@ private List buildFunctionDefinitions( } } } else if (functionDefinition.getType().equals("event")) { - methodSpecs.addAll(buildEventFunctions(functionDefinition, classBuilder)); + boolean isOverloadEvent = + isOverLoadEvent(functionDefinition.getName(), functionDefinitions); + + methodSpecs.addAll( + buildEventFunctions(functionDefinition, classBuilder, isOverloadEvent)); } } @@ -1209,9 +1228,10 @@ private MethodSpec buildEventTransactionReceiptFunction( } private List buildEventFunctions( - ABIDefinition functionDefinition, TypeSpec.Builder classBuilder) + ABIDefinition functionDefinition, TypeSpec.Builder classBuilder, boolean isOverload) throws ClassNotFoundException { - String functionName = functionDefinition.getName(); + + String functionName = getInputOutputFunctionName(functionDefinition, isOverload); List inputs = functionDefinition.getInputs(); String responseClassName = StringUtils.capitaliseFirstLetter(functionName) + "EventResponse"; @@ -1255,7 +1275,8 @@ private List buildEventFunctions( parameters.add(parameter); } - classBuilder.addField(createEventDefinition(functionName, parameters)); + classBuilder.addField( + createEventDefinition(functionDefinition.getName(), functionName, parameters)); classBuilder.addType( buildEventResponseObject( @@ -1819,12 +1840,21 @@ private static TypeName buildStructArrayTypeName(ABIDefinition.NamedType namedTy .structIdentifier()) .toString(); } else { - structName = - namedType - .getInternalType() - .substring( - namedType.getInternalType().lastIndexOf(" ") + 1, - namedType.getInternalType().indexOf("[")); + if (namedType.getInternalType().contains(".")) { + structName = + namedType + .getInternalType() + .substring( + namedType.getInternalType().lastIndexOf(".") + 1, + namedType.getInternalType().indexOf("[")); + } else { + structName = + namedType + .getInternalType() + .substring( + namedType.getInternalType().lastIndexOf(" ") + 1, + namedType.getInternalType().indexOf("[")); + } } return ParameterizedTypeName.get( 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 7a94dc2..94c6c2b 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 @@ -837,12 +837,21 @@ private TypeName buildStructArrayTypeName(ABIDefinition.NamedType namedType) { namedType.getInternalType().lastIndexOf(".") + 1, namedType.getInternalType().indexOf("[")); } else { - structName = - namedType - .getInternalType() - .substring( - namedType.getInternalType().lastIndexOf(" ") + 1, - namedType.getInternalType().indexOf("[")); + if (namedType.getInternalType().contains(".")) { + structName = + namedType + .getInternalType() + .substring( + namedType.getInternalType().lastIndexOf(".") + 1, + namedType.getInternalType().indexOf("[")); + } else { + structName = + namedType + .getInternalType() + .substring( + namedType.getInternalType().lastIndexOf(" ") + 1, + namedType.getInternalType().indexOf("[")); + } } } 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 1bf167f..6e76193 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,8 +100,23 @@ public void weidABICodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } - // FIXME: v2 event override bug - // @Test + @Test + public void StructReqRespCodeGen() throws IOException { + // abi from https://github.com/FISCO-BCOS/code-generator/issues/19 + final String ABI_FILE = "StructReqRespContract.abi"; + final String CONTRACT_NAME = "StructReqRespContract"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + + @Test + public void SupplyChainFinCodeGen() throws IOException { + // abi from https://github.com/FISCO-BCOS/java-sdk/issues/801 + final String ABI_FILE = "SupplyChainFin.abi"; + final String CONTRACT_NAME = "SupplyChainFin"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + + @Test public void eventTestCodeGen() throws IOException { final String ABI_FILE = "EventSubDemo.abi"; final String CONTRACT_NAME = "EventSubDemo"; 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 9d36a51..9308638 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 @@ -100,6 +100,22 @@ public void weidABICodeGen() throws IOException { codeGenTest(ABI_FILE, CONTRACT_NAME); } + @Test + public void StructReqRespCodeGen() throws IOException { + // abi from https://github.com/FISCO-BCOS/code-generator/issues/19 + final String ABI_FILE = "StructReqRespContract.abi"; + final String CONTRACT_NAME = "StructReqRespContract"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + + @Test + public void SupplyChainFinCodeGen() throws IOException { + // abi from https://github.com/FISCO-BCOS/java-sdk/issues/801 + final String ABI_FILE = "SupplyChainFin.abi"; + final String CONTRACT_NAME = "SupplyChainFin"; + codeGenTest(ABI_FILE, CONTRACT_NAME); + } + @Test public void liquidCodeTestCodeGen() throws IOException { final String ABI_FILE = "codec_test.abi"; diff --git a/src/test/resources/StructReqRespContract.abi b/src/test/resources/StructReqRespContract.abi new file mode 100644 index 0000000..bfd744e --- /dev/null +++ b/src/test/resources/StructReqRespContract.abi @@ -0,0 +1 @@ +[{"inputs":[{"components":[{"components":[{"internalType":"string","name":"req","type":"string"}],"internalType":"struct StructLibrary.Req[]","name":"reqs","type":"tuple[]"}],"internalType":"struct StructLibrary.StructReq","name":"req","type":"tuple"}],"name":"request","outputs":[{"components":[{"internalType":"string","name":"resp","type":"string"}],"internalType":"struct StructLibrary.StructResp","name":"resp","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/test/resources/SupplyChainFin.abi b/src/test/resources/SupplyChainFin.abi new file mode 100644 index 0000000..b9d67e8 --- /dev/null +++ b/src/test/resources/SupplyChainFin.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"banks","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"senderAddress","type":"address"},{"name":"accepterAddress","type":"address"},{"name":"amount","type":"uint256"},{"name":"receiptType","type":"uint8"}],"name":"companyToCompanyReceipt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"companies","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"bankAddress","type":"address"},{"name":"credit","type":"uint256"}],"name":"addBank","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"companyAddress","type":"address"}],"name":"addCompany","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"senderAddress","type":"address"},{"name":"accepterAddress","type":"address"},{"name":"amount","type":"uint256"},{"name":"receiptType","type":"uint8"}],"name":"companyToBankReceipt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"companyAddress","type":"address"}],"name":"getCompany","outputs":[{"name":"","type":"string"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllBankAddress","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"receiptIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"senderAddress","type":"address"},{"name":"accepterAddress","type":"address"},{"name":"amount","type":"uint256"},{"name":"receiptType","type":"uint8"}],"name":"bankToCompanyReceipt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"bankAddress","type":"address"}],"name":"getBank","outputs":[{"name":"","type":"string"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"superviosrIns","outputs":[{"name":"supervisorName","type":"string"},{"name":"supervisorAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"getReceipt","outputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint8"},{"name":"","type":"uint8"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllCompanyAddress","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"name","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}] \ No newline at end of file From eada1939808842e5ab796a8323a616fed6ffeff7 Mon Sep 17 00:00:00 2001 From: kyonRay Date: Mon, 16 Oct 2023 11:01:26 +0800 Subject: [PATCH 5/5] (project): update version to 1.2.0. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f2545b0..07fd567 100644 --- a/build.gradle +++ b/build.gradle @@ -50,7 +50,7 @@ sourceSets { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.code-generator' - version = '1.2.0-SNAPSHOT' + version = '1.2.0' apply plugin: 'maven-publish' apply plugin: 'idea' apply plugin: 'eclipse'