You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/05/25 14:20:18 UTC
[plc4x] 02/02: [CODE-GEN] Improvements in the code generation stuff.
This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch feature/code-gen-julian
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit ccc66617a0cd2edb7a45f6c9b78b1fee1a8ea283
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat May 25 16:20:10 2019 +0200
[CODE-GEN] Improvements in the code generation stuff.
---
.../java/org/apache/plc4x/codegen/api/Buffer.java | 4 ++
.../org/apache/plc4x/codegen/ast/Expressions.java | 6 +-
.../apache/plc4x/codegen/ast/JavaGenerator.java | 6 +-
.../apache/plc4x/codegen/ast/PythonGenerator.java | 13 +++-
.../org/apache/plc4x/codegen/ast/TypeUtil.java | 2 +
.../plugins/codegenerator/example/COTPPacket.java | 18 ++++++
.../plugins/codegenerator/example/Context.java | 8 +++
.../plugins/codegenerator/example/TPKTPacket.java | 34 ++++++++++
.../codegenerator/example/TPKTPacketFactory.java | 17 +++++
.../codegenerator/parser/MessageFormatParser.java | 74 +++++++++++++++++++++-
.../src/test/resources/specs/s7.spec | 2 +-
11 files changed, 173 insertions(+), 11 deletions(-)
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
index 3cbf658..1896bcd 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
@@ -28,4 +28,8 @@ public interface Buffer {
Integer readUint16();
Long readUint32();
+
+ void writeUint8(short n);
+
+ void writeUint16(int n);
}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
index cc9f505..1ec969e 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
@@ -143,7 +143,7 @@ public class Expressions {
* @param statements
* @return
*/
- public static Statement block(Node... statements) {
+ public static Block block(Node... statements) {
return new Block(statements);
}
@@ -259,9 +259,9 @@ public class Expressions {
/**
* Simple call to a method which throws no exception and that stuff.
*/
- public static Expression call(Node target, String methodName, Node... arguments) {
+ public static Expression call(Node target, String methodName, TypeDefinition returnType, Node... arguments) {
return new CallExpression(
- new Method(UnknownType.INSTANCE, methodName, UnknownType.INSTANCE,
+ new Method(UnknownType.INSTANCE, methodName, returnType,
Collections.<TypeDefinition>emptyList(), Collections.<ExceptionType>emptyList()),
target,
arguments
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
index da87f90..9b04996 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
@@ -110,6 +110,8 @@ public class JavaGenerator implements Generator {
// Dont to the wrapping for If Statements
if (statement instanceof IfStatement) {
statement.write(this);
+ } else if (statement instanceof LineComment) { // Special handling of comments
+ statement.write(this);
} else {
writer.startLine("");
statement.write(this);
@@ -313,7 +315,7 @@ public class JavaGenerator implements Generator {
}
@Override public void generateNoOp() {
- writer.write(";");
+ //writer.write(";");
}
private String getOperator(BinaryExpression.Operation op) {
@@ -322,6 +324,8 @@ public class JavaGenerator implements Generator {
return "==";
case PLUS:
return "+";
+ case NEQ:
+ return "!=";
}
throw new UnsupportedOperationException("The Operator " + op + " is currently not implemented!");
}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
index 9e4b17e..b026415 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
@@ -19,6 +19,7 @@ under the License.
package org.apache.plc4x.codegen.ast;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
public class PythonGenerator implements Generator {
@@ -108,19 +109,23 @@ public class PythonGenerator implements Generator {
@Override public void writeBlock(Block statements) {
writer.startBlock();
- if (statements.getStatements().isEmpty()) {
- writer.writeLine("pass");
- }
for (Node statement : statements.getStatements()) {
// Dont to the wrapping for If Statements
if (statement instanceof IfStatement) {
statement.write(this);
+ } else if (statement instanceof LineComment) {
+ statement.write(this);
} else {
writer.startLine("");
statement.write(this);
writer.endLine();
}
}
+ // Pass, if necessary
+ final long stmtCount = statements.getStatements().stream().filter(stmt -> !(stmt instanceof LineComment)).count();
+ if (stmtCount == 0) {
+ writer.writeLine("pass");
+ }
writer.endBlock();
}
@@ -312,6 +317,8 @@ public class PythonGenerator implements Generator {
return "==";
case PLUS:
return "+";
+ case NEQ:
+ return "!=";
}
throw new UnsupportedOperationException("The Operator " + op + " is currently not implemented!");
}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
index e27d2aa..28e185d 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
@@ -23,6 +23,8 @@ public class TypeUtil {
public static TypeDefinition infer(Object o) {
if (o instanceof Double) {
return Primitive.DOUBLE;
+ } else if (o instanceof Integer) {
+ return Primitive.INTEGER;
}
throw new UnsupportedOperationException("No type available for object " + o);
}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java
new file mode 100644
index 0000000..76a458c
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java
@@ -0,0 +1,18 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+public class COTPPacket {
+
+ int getSize() {
+ return 0;
+ }
+
+ public static COTPPacket read(Buffer buffer, Context context) {
+ return null;
+ }
+
+ public void write(Buffer buffer) {
+
+ }
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java
new file mode 100644
index 0000000..bdc68b3
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java
@@ -0,0 +1,8 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+public class Context {
+
+ public void put(String key, Object value) {
+
+ }
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java
new file mode 100644
index 0000000..ede0f05
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java
@@ -0,0 +1,34 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+/**
+ * Example... for
+ * <code>
+ * [type 'TPKTPacket'
+ * [const uint8 'protocolId' '0x3']
+ * [reserved uint8 '0x0']
+ * [field uint16 'len']
+ * [field COTPPacket 'payload' {payloadLength: 'len - 4'}]
+ * ]
+ * </code>
+ */
+public class TPKTPacket {
+
+ public static final short PROTOCOL_ID = 0x3;
+ public static final short RESERVED_1 = 0x0;
+
+ private final COTPPacket payload;
+
+ public TPKTPacket(COTPPacket payload) {
+ this.payload = payload;
+ }
+
+ public void write(Buffer buffer) {
+ buffer.writeUint8(PROTOCOL_ID);
+ buffer.writeUint8(RESERVED_1);
+ buffer.writeUint16(payload.getSize() + 4);
+ payload.write(buffer);
+ }
+
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java
new file mode 100644
index 0000000..62837a3
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java
@@ -0,0 +1,17 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+public class TPKTPacketFactory {
+
+ public TPKTPacket read(Buffer buffer) {
+ assert buffer.readUint8() == TPKTPacket.PROTOCOL_ID;
+ assert buffer.readUint8() == TPKTPacket.RESERVED_1;
+ int len = buffer.readUint16();
+ final Context context = new Context();
+ context.put("payloadLength", len - 4);
+ COTPPacket cotpPacket = COTPPacket.read(buffer, context);
+ return new TPKTPacket(cotpPacket);
+ }
+
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
index 9fa4f3c..202fa45 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
@@ -23,13 +23,18 @@ import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.apache.plc4x.codegen.ast.BinaryExpression;
+import org.apache.plc4x.codegen.ast.BlockBuilder;
import org.apache.plc4x.codegen.ast.ClassDeclaration;
import org.apache.plc4x.codegen.ast.CodeWriter;
+import org.apache.plc4x.codegen.ast.Expression;
import org.apache.plc4x.codegen.ast.Expressions;
import org.apache.plc4x.codegen.ast.Generator;
import org.apache.plc4x.codegen.ast.JavaGenerator;
+import org.apache.plc4x.codegen.ast.Method;
+import org.apache.plc4x.codegen.ast.ParameterExpression;
import org.apache.plc4x.codegen.ast.Primitive;
-import org.apache.plc4x.codegen.ast.TypeDefinition;
+import org.apache.plc4x.codegen.ast.PythonGenerator;
import org.apache.plc4x.codegen.util.PojoFactory;
import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryLexer;
import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryParser;
@@ -48,6 +53,7 @@ import org.apache.plc4x.plugins.codegenerator.model.fields.SwitchField;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -97,7 +103,7 @@ public class MessageFormatParser {
final List<ClassBuilder> classes = new ArrayList<>();
for (Map.Entry<String, ComplexType> entry : complexTypes.entrySet()) {
final CodeWriter writer = new CodeWriter(4);
- final Generator generator = new JavaGenerator(writer);
+ final Generator generator = new PythonGenerator(writer);
System.out.println("// ----------------------");
System.out.println("// " + entry.getKey() + " ");
System.out.println("// ----------------------");
@@ -109,7 +115,7 @@ public class MessageFormatParser {
.collect(Collectors.toList());
final PojoFactory.PojoDescription pojoDesc = new PojoFactory.PojoDescription(entry.getKey(), fields);
final ClassDeclaration classDeclaration = factory.create(pojoDesc);
- classDeclaration.write(generator);
+ // classDeclaration.write(generator);
// Output POJO
// System.out.println(writer.getCode());
@@ -120,14 +126,71 @@ public class MessageFormatParser {
classBuilder.withName(entry.getKey());
int constCount = 1;
int implicitCount = 1;
+ int tmpCount = 1;
+ BlockBuilder writerBuilder = new BlockBuilder();
+ BlockBuilder readerBuilder = new BlockBuilder();
+ final ParameterExpression _buffer = Expressions.parameter("buffer", Expressions.typeOf("Buffer"));
+ final Method _writeUint8 = Expressions.method(Expressions.typeOf("Buffer"), "writeUint8", Primitive.VOID, Collections.singletonList(Primitive.INTEGER), Collections.emptyList());
+ final Method _readUint8 = Expressions.method(Expressions.typeOf("Buffer"), "readUint8", Primitive.INTEGER, Collections.emptyList(), Collections.emptyList());
for (Field field : type.getFields()) {
if (field instanceof ArrayField) {
// do nothing
System.out.println("Skipping Array field...");
} else if (field instanceof ConstField) {
classBuilder.withConstant("CONST_" + constCount++, ((ConstField) field).getType().getName(), ((ConstField) field).getReferenceValue(), new ClassBuilder.Documentation("Constant expression"));
+
+ String constString = ((ConstField) field).getReferenceValue().toString();
+ constString = constString.replace("'", "");
+ final Expression _const = Expressions.constant(Integer.decode(constString));
+
+ // Writer
+ writerBuilder.add(Expressions.comment("Constant"));
+ writerBuilder.add(Expressions.call(
+ _buffer,
+ _writeUint8,
+ _const
+ ));
+
+ // Reader
+ readerBuilder.add(Expressions.comment("This should be a check on the expected value"));
+ String tmpVar = "tmp" + tmpCount++;
+ readerBuilder.add(Expressions.declaration(
+ tmpVar,
+ Expressions.call(_buffer, _readUint8)
+ ));
+ readerBuilder.add(Expressions.ifElse(
+ Expressions.binaryExpression(Primitive.BOOLEAN, Expressions.parameter(tmpVar, Primitive.VOID), _const, BinaryExpression.Operation.NEQ),
+ Expressions.block(
+ Expressions.comment("We should throw an exception here")
+ )
+ ));
+
} else if (field instanceof SimpleField) {
classBuilder.withField(((SimpleField) field).getName(), ((SimpleField) field).getType().getName(), new ClassBuilder.Documentation("Simple Field..."));
+
+ // Writer
+
+ final ParameterExpression parameter = Expressions.parameter(
+ ((SimpleField) field).getName(),
+ Expressions.typeOf(((SimpleField) field).getType().getName())
+ );
+ if (((SimpleField) field).getType().getName().startsWith("uint")) {
+ writerBuilder.add(Expressions.call(
+ _buffer,
+ _writeUint8,
+ parameter
+ ));
+ } else {
+ writerBuilder.add(Expressions.call(
+ parameter,
+ "write",
+ Primitive.VOID,
+ _buffer
+ ));
+ }
+
+ // Reader
+
} else if (field instanceof ImplicitField) {
classBuilder.withField("implicit" + implicitCount, ((ImplicitField) field).getType().getName(), ((ImplicitField) field).getSerializationExpression(), new ClassBuilder.Documentation("Implicitly defined field"));
} else if (field instanceof DiscriminatorField) {
@@ -150,6 +213,11 @@ public class MessageFormatParser {
}
// System.out.println(classBuilder.toString());
+
+ // Print something here
+ writerBuilder.toBlock().write(generator);
+ readerBuilder.toBlock().write(generator);
+ System.out.println(writer.getCode());
}
// Now print all Classes
diff --git a/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
index f46d8a9..dcfd4ab 100644
--- a/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
+++ b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
@@ -5,7 +5,7 @@
[type 'TPKTPacket'
[const uint8 'protocolId' '0x3']
[reserved uint8 '0x0']
- [implicit uint16 'len' 'payload.size + 4']
+ [field uint16 'len']
[field COTPPacket 'payload' {payloadLength: 'len - 4'}]
]