From 63e2f6812efecef878f971b5d8ad83eb1ff9824a Mon Sep 17 00:00:00 2001 From: rtrimana Date: Tue, 22 Nov 2016 10:12:03 -0800 Subject: [PATCH] Adding enum support in compiler --- config/iotpolicy/camerapolicy.pol | 2 + iotjava/Makefile | 6 +- iotjava/iotpolicy/IoTCompiler.java | 711 +++++++++++++++--- iotjava/iotpolicy/tree/Declaration.java | 6 + iotjava/iotpolicy/tree/EnumDecl.java | 2 +- .../iotrmi/C++/sample/TestClass_Skeleton.hpp | 6 +- 6 files changed, 609 insertions(+), 124 deletions(-) diff --git a/config/iotpolicy/camerapolicy.pol b/config/iotpolicy/camerapolicy.pol index 809f12d..2a69e55 100644 --- a/config/iotpolicy/camerapolicy.pol +++ b/config/iotpolicy/camerapolicy.pol @@ -7,6 +7,7 @@ public interface Camera { public float MethodD(List G, float H); public boolean MethodE(String I, boolean J); public void MethodF(LightBulb K); + public Enum MethodG(Enum L); capability ImageCapture { description = "The quick brown fox jumps over the smart dog"; @@ -15,6 +16,7 @@ public interface Camera { method = "MethodB(int C, String D[])"; method = "MethodC(String E, List F)"; method = "MethodF(LightBulb K)"; + method = "MethodG(Enum L)"; } capability VideoRecording { diff --git a/iotjava/Makefile b/iotjava/Makefile index f1bb89a..d7f6a9d 100644 --- a/iotjava/Makefile +++ b/iotjava/Makefile @@ -32,9 +32,9 @@ PHONY += compile compile: cd $(BIN_DIR)/iotpolicy/output_files; cp *.java ./Java cd $(BIN_DIR)/iotpolicy/output_files; cp *.hpp ./Cplus - cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) *.java - cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./*.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/ -# cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./CameraWithCaptureAndData_CallbackStub.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/ +# cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) *.java +# cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./*.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/ + cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./Camera_Skeleton.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/ PHONY += clean clean: diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index 8c84a4c..db60fcc 100644 --- a/iotjava/iotpolicy/IoTCompiler.java +++ b/iotjava/iotpolicy/IoTCompiler.java @@ -68,7 +68,9 @@ public class IoTCompiler { PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc. NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc. - USERDEFINED // Non-supported type by default; assumed as driver classes + ENUM, // Enum type + STRUCT, // Struct type + USERDEFINED // Assumed as driver classes } /** @@ -233,50 +235,72 @@ public class IoTCompiler { /** - * HELPER: writeEnumJava() writes the enumeration declaration + * HELPER: generateEnumJava() writes the enumeration declaration */ - private void writeEnumJava(EnumDecl enumDecl) { + private void generateEnumJava() throws IOException { - Set enumTypes = enumDecl.getEnumDeclarations(); - // Iterate over enum declarations - for (String enType : enumTypes) { - - println("public enum " + enType + " {"); - List enumMembers = enumDecl.getMembers(enType); - for (int i = 0; i < enumMembers.size(); i++) { - - String member = enumMembers.get(i); - print(member); - // Check if this is the last element (don't print a comma) - if (i != enumMembers.size() - 1) - println(","); - else - println(""); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right EnumDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set enumTypes = enumDecl.getEnumDeclarations(); + // Iterate over enum declarations + for (String enType : enumTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + enType + ".java"); + pw = new PrintWriter(new BufferedWriter(fw)); + println("public enum " + enType + " {"); + List enumMembers = enumDecl.getMembers(enType); + for (int i = 0; i < enumMembers.size(); i++) { + + String member = enumMembers.get(i); + print(member); + // Check if this is the last element (don't print a comma) + if (i != enumMembers.size() - 1) + println(","); + else + println(""); + } + println("}\n"); + pw.close(); + System.out.println("IoTCompiler: Generated enum class " + enType + ".java..."); } - println("}\n"); } } /** - * HELPER: writeStructJava() writes the struct declaration + * HELPER: generateStructJava() writes the struct declaration */ - private void writeStructJava(StructDecl structDecl) { - - List structTypes = structDecl.getStructTypes(); - // Iterate over enum declarations - for (String stType : structTypes) { + private void generateStructJava() throws IOException { - println("public class " + stType + " {"); - List structMemberTypes = structDecl.getMemberTypes(stType); - List structMembers = structDecl.getMembers(stType); - for (int i = 0; i < structMembers.size(); i++) { - - String memberType = structMemberTypes.get(i); - String member = structMembers.get(i); - println("public static " + memberType + " " + member + ";"); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List structTypes = structDecl.getStructTypes(); + // Iterate over enum declarations + for (String stType : structTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + stType + ".java"); + pw = new PrintWriter(new BufferedWriter(fw)); + println("public class " + stType + " {"); + List structMemberTypes = structDecl.getMemberTypes(stType); + List structMembers = structDecl.getMembers(stType); + for (int i = 0; i < structMembers.size(); i++) { + + String memberType = structMemberTypes.get(i); + String member = structMembers.get(i); + println("public static " + memberType + " " + member + ";"); + } + println("}\n"); + pw.close(); + System.out.println("IoTCompiler: Generated struct class " + stType + ".java..."); } - println("}\n"); } } @@ -307,11 +331,11 @@ public class IoTCompiler { println(""); println("public interface " + intface + " {"); // Write enum if any... - EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); - writeEnumJava(enumDecl); + //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + //writeEnumJava(enumDecl); // Write struct if any... - StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); - writeStructJava(structDecl); + //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + //writeStructJava(structDecl); // Write methods writeMethodJavaLocalInterface(methods, intDecl); println("}"); @@ -506,6 +530,74 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeJavaStub(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + if (isArray(param)) { // An array + println("int len" + i + " = " + param + ".length;"); + println("int paramEnum" + i + "[] = new int[len];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = " + param + "[i].ordinal();"); + println("}"); + } else if (isList(paramType)) { // A list + println("int len" + i + " = " + param + ".size();"); + println("int paramEnum" + i + "[] = new int[len];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = " + param + ".get(i).ordinal();"); + println("}"); + } else { // Just one element + println("int paramEnum" + i + "[] = new int[1];"); + println("paramEnum" + i + "[0] = " + param + ".ordinal();"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeJavaStub(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getSimpleType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(retType)[0]; + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + println("int[] retEnum = (int[]) retObj;"); + println(pureType + "[] enumVals = " + pureType + ".values();"); + if (isArray(retType)) { // An array + println("int retLen = retEnum.length;"); + println(pureType + "[] enumRetVal = new " + pureType + "[retLen];"); + println("for (int i = 0; i < retLen; i++) {"); + println("enumRetVal[i] = enumVals[retEnum[i]];"); + println("}"); + } else if (isList(retType)) { // A list + println("int retLen = retEnum.length;"); + println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();"); + println("for (int i = 0; i < retLen; i++) {"); + println("enumRetVal.add(enumVals[retEnum[i]]);"); + println("}"); + } else { // Just one element + println(pureType + " enumRetVal = enumVals[retEnum[0]];"); + } + println("return enumRetVal;"); + } + } + + /** * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class */ @@ -514,12 +606,13 @@ public class IoTCompiler { println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - println("Class retType = " + getSimpleType(retType) + ".class;"); + println("Class retType = " + getSimpleType(getEnumType(retType)) + ".class;"); + checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes); // Generate array of parameter types print("Class[] paramCls = new Class[] { "); for (int i = 0; i < methParams.size(); i++) { String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print(getSimpleType(paramType) + ".class"); + print(getSimpleType(getEnumType(paramType)) + ".class"); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -529,7 +622,7 @@ public class IoTCompiler { // Generate array of parameter objects print("Object[] paramObj = new Object[] { "); for (int i = 0; i < methParams.size(); i++) { - print(getSimpleIdentifier(methParams.get(i))); + print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -546,6 +639,10 @@ public class IoTCompiler { println("Class retGenValType = " + retGenValType[0] + ".class;"); println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);"); println("return (" + retType + ")retObj;"); + } else if (getParamCategory(retType) == ParamCategory.ENUM) { + // This is an enum type + println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); + checkAndWriteEnumRetTypeJavaStub(retType); } else { println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); println("return (" + retType + ")retObj;"); @@ -606,7 +703,7 @@ public class IoTCompiler { println("}\n"); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - println("Class retType = " + getSimpleType(retType) + ".class;"); + println("Class retType = " + getSimpleType(getEnumType(retType)) + ".class;"); // Generate array of parameter types print("Class[] paramCls = new Class[] { "); for (int i = 0; i < methParams.size(); i++) { @@ -626,9 +723,10 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - if (isArray(methPrmTypes.get(i), methParams.get(i))) + //if (isArray(methPrmTypes.get(i), methParams.get(i))) + if (isArray(methParams.get(i))) print(getSimpleIdentifier(methParams.get(i)) + ".length"); - else if (isList(methPrmTypes.get(i), methParams.get(i))) + else if (isList(methPrmTypes.get(i))) print(getSimpleIdentifier(methParams.get(i)) + ".size()"); else print("new Integer(1)"); @@ -963,10 +1061,10 @@ public class IoTCompiler { println("try {"); String exchParamType = checkAndGetParamClass(paramType); // Print array if this is array or list if this is a list of callback objects - if (isArray(paramType, param)) { + if (isArray(param)) { println("int numStubs" + i + " = (int) paramObj[" + i + "];"); println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];"); - } else if (isList(paramType, param)) { + } else if (isList(paramType)) { println("int numStubs" + i + " = (int) paramObj[" + i + "];"); println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();"); } else { @@ -977,12 +1075,12 @@ public class IoTCompiler { // Generate a loop if needed if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object String exchParamType = checkAndGetParamClass(paramType); - if (isArray(paramType, param)) { + if (isArray(param)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); println("objIdCnt++;"); println("}"); - } else if (isList(paramType, param)) { + } else if (isList(paramType)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));"); println("objIdCnt++;"); @@ -995,6 +1093,97 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeJavaSkeleton(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + println("int paramInt" + i + "[] = (int[]) paramObj[" + i + "];"); + println(simpleType + "[] enumVals = " + simpleType + ".values();"); + if (isArray(param)) { // An array + println("int len" + i + " = paramInt" + i + ".length;"); + println(simpleType + "[] paramEnum = new " + simpleType + "[len];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum[i] = enumVals[paramInt" + i + "[i]];"); + println("}"); + } else if (isList(paramType)) { // A list + println("int len" + i + " = paramInt" + i + ".length;"); + println("List<" + simpleType + "> paramEnum = new ArrayList<" + simpleType + ">();"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum.add(enumVals[paramInt" + i + "[i]]);"); + println("}"); + } else { // Just one element + println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getSimpleType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(retType)[0]; + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + if (isArray(retType)) { // An array + print(pureType + "[] retEnum = " + methodId + "("); + } else if (isList(retType)) { // A list + print("List<" + pureType + "> retEnum = " + methodId + "("); + } else { // Just one element + print(pureType + " retEnum = " + methodId + "("); + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetConvJavaSkeleton(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getSimpleType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(retType)[0]; + if (isEnumClass(pureType)) { + // Check if this is enum type + if (isArray(retType)) { // An array + println("int retLen = retEnum.length;"); + println("int[] retEnumVal = new int[retLen];"); + println("for (int i = 0; i < retLen; i++) {"); + println("retEnumVal[i] = retEnum[i].ordinal();"); + println("}"); + } else if (isList(retType)) { // A list + println("int retLen = retEnum.size();"); + println("List<" + pureType + "> retEnumVal = new ArrayList<" + pureType + ">();"); + println("for (int i = 0; i < retLen; i++) {"); + println("retEnumVal.add(retEnum[i].ordinal());"); + println("}"); + } else { // Just one element + println("int[] retEnumVal = new int[1];"); + println("retEnumVal[0] = retEnum.ordinal();"); + } + println("Object retObj = retEnumVal;"); + } + } + + /** * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class */ @@ -1013,7 +1202,7 @@ public class IoTCompiler { print("int.class"); } else { // Generate normal classes if it's not a callback object String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print(getSimpleType(prmType) + ".class"); + print(getSimpleType(getEnumType(prmType)) + ".class"); } if (i != methParams.size() - 1) print(", "); @@ -1031,6 +1220,7 @@ public class IoTCompiler { print(", "); } println(" });"); + checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes); Map mapStubParam = null; if (isCallbackMethod) mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType); @@ -1038,6 +1228,8 @@ public class IoTCompiler { String retType = intDecl.getMethodType(method); if (retType.equals("void")) { print(intDecl.getMethodId(method) + "("); + } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type + checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method)); } else { // We do have a return value print("Object retObj = " + intDecl.getMethodId(method) + "("); } @@ -1045,6 +1237,8 @@ public class IoTCompiler { if (isCallbackMethod) { print(mapStubParam.get(i)); // Get the callback parameter + } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class + print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i)); } else { String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); print("(" + prmType + ") paramObj[" + i + "]"); @@ -1053,8 +1247,11 @@ public class IoTCompiler { print(", "); } println(");"); - if (!retType.equals("void")) + if (!retType.equals("void")) { + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + checkAndWriteEnumRetConvJavaSkeleton(retType); println("rmiObj.sendReturnObj(retObj);"); + } if (isCallbackMethod) { // Catch exception if this is callback println("} catch(Exception ex) {"); println("ex.printStackTrace();"); @@ -1401,52 +1598,82 @@ public class IoTCompiler { /** - * HELPER: writeEnumCplus() writes the enumeration declaration + * HELPER: generateEnumCplus() writes the enumeration declaration */ - private void writeEnumCplus(EnumDecl enumDecl) { - - Set enumTypes = enumDecl.getEnumDeclarations(); - // Iterate over enum declarations - for (String enType : enumTypes) { - - println("enum " + enType + " {"); - List enumMembers = enumDecl.getMembers(enType); - for (int i = 0; i < enumMembers.size(); i++) { + public void generateEnumCplus() throws IOException { - String member = enumMembers.get(i); - print(member); - // Check if this is the last element (don't print a comma) - if (i != enumMembers.size() - 1) - println(","); - else - println(""); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set enumTypes = enumDecl.getEnumDeclarations(); + // Iterate over enum declarations + for (String enType : enumTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + // Write file headers + println("#ifndef _" + enType.toUpperCase() + "_HPP__"); + println("#define _" + enType.toUpperCase() + "_HPP__"); + println("enum " + enType + " {"); + List enumMembers = enumDecl.getMembers(enType); + for (int i = 0; i < enumMembers.size(); i++) { + + String member = enumMembers.get(i); + print(member); + // Check if this is the last element (don't print a comma) + if (i != enumMembers.size() - 1) + println(","); + else + println(""); + } + println("};\n"); + println("#endif"); + pw.close(); + System.out.println("IoTCompiler: Generated enum " + enType + ".hpp..."); } - println("};\n"); } } /** - * HELPER: writeStructCplus() writes the struct declaration + * HELPER: generateStructCplus() writes the struct declaration */ - private void writeStructCplus(StructDecl structDecl) { - - List structTypes = structDecl.getStructTypes(); - // Iterate over enum declarations - for (String stType : structTypes) { + public void generateStructCplus() throws IOException { - println("struct " + stType + " {"); - List structMemberTypes = structDecl.getMemberTypes(stType); - List structMembers = structDecl.getMembers(stType); - for (int i = 0; i < structMembers.size(); i++) { - - String memberType = structMemberTypes.get(i); - String member = structMembers.get(i); - String structTypeC = checkAndGetCplusType(memberType); - String structComplete = checkAndGetCplusArray(structTypeC, member); - println(structComplete + ";"); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List structTypes = structDecl.getStructTypes(); + // Iterate over enum declarations + for (String stType : structTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + // Write file headers + println("#ifndef _" + stType.toUpperCase() + "_HPP__"); + println("#define _" + stType.toUpperCase() + "_HPP__"); + println("struct " + stType + " {"); + List structMemberTypes = structDecl.getMemberTypes(stType); + List structMembers = structDecl.getMembers(stType); + for (int i = 0; i < structMembers.size(); i++) { + + String memberType = structMemberTypes.get(i); + String member = structMembers.get(i); + String structTypeC = checkAndGetCplusType(memberType); + String structComplete = checkAndGetCplusArray(structTypeC, member); + println(structComplete + ";"); + } + println("};\n"); + println("#endif"); + pw.close(); + System.out.println("IoTCompiler: Generated struct " + stType + ".hpp..."); } - println("};\n"); } } @@ -1475,15 +1702,15 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); printIncludeStatements(includeClasses); println(""); println("using namespace std;\n"); // Write enum if any... - EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); - writeEnumCplus(enumDecl); + //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + //writeEnumCplus(enumDecl); // Write struct if any... - StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); - writeStructCplus(structDecl); + //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + //writeStructCplus(structDecl); println("class " + intface); println("{"); println("public:"); // Write methods @@ -1521,7 +1748,7 @@ public class IoTCompiler { println("#define _" + newIntface.toUpperCase() + "_HPP__"); println("#include "); // Pass in set of methods and get import classes - Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, false); + Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -1665,6 +1892,62 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeCplusStub(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + if (isArrayOrList(paramType, param)) { // An array or vector + println("int len" + i + " = " + param + ".size();"); + println("vector paramEnum" + i + "(len);"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = (int) " + param + "[i];"); + println("}"); + } else { // Just one element + println("vector paramEnum" + i + "(1);"); + println("paramEnum" + i + "[0] = (int) " + param + ";"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeCplusStub(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getSimpleType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(retType)[0]; + if (isEnumClass(pureType)) { + // Check if this is enum type + println("vector retEnumInt;"); + println("void* retObj = &retEnumInt;"); + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); + if (isArrayOrList(retType, retType)) { // An array or vector + println("int retLen = retEnumInt.size();"); + println("vector<" + pureType + "> retVal(retLen);"); + println("for (int i = 0; i < retLen; i++) {"); + println("retVal[i] = (" + pureType + ") retEnumInt[i];"); + println("}"); + } else { // Just one element + println(pureType + " retVal = (" + pureType + ") retEnumInt[0];"); + } + println("return retVal;"); + } + } + + /** * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class */ @@ -1675,23 +1958,24 @@ public class IoTCompiler { println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); String retTypeC = checkAndGetCplusType(retType); - println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";"); + println("string retType = \"" + checkAndGetCplusArrayType(getEnumType(retTypeC)) + "\";"); // Generate array of parameter types print("string paramCls[] = { "); for (int i = 0; i < methParams.size(); i++) { String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - print("\"" + paramType + "\""); + print("\"" + getEnumType(paramType) + "\""); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); } } println(" };"); + checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); // Generate array of parameter objects print("void* paramObj[] = { "); for (int i = 0; i < methParams.size(); i++) { - print("&" + getSimpleIdentifier(methParams.get(i))); + print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -1703,13 +1987,17 @@ public class IoTCompiler { println("void* retObj = NULL;"); println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); } else { // We do have a return value - if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - println(checkAndGetCplusType(retType) + " retVal;"); - else - println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); - println("void* retObj = &retVal;"); - println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); - println("return retVal;"); + if (getParamCategory(retType) == ParamCategory.ENUM) { + checkAndWriteEnumRetTypeCplusStub(retType); + } else { + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + println(checkAndGetCplusType(retType) + " retVal;"); + else + println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); + println("void* retObj = &retVal;"); + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); + println("return retVal;"); + } } } @@ -2247,6 +2535,60 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeCplusSkeleton(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + if (isArrayOrList(paramType, param)) { // An array + println("int len" + i + " = paramEnumInt" + i + ".size();"); + println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");"); + println("for (int i=0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];"); + println("}"); + } else { // Just one element + println(simpleType + " paramEnum" + i + ";"); + println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getSimpleType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(retType)[0]; + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + if (isArrayOrList(retType, retType)) { // An array + println("int retLen = retEnum.size();"); + println("vector retEnumInt(retLen);"); + println("for (int i=0; i < retLen; i++) {"); + println("retEnumInt[i] = (int) retEnum[i];"); + println("}"); + } else { // Just one element + println("vector retEnumInt(1);"); + println("retEnumInt[0] = (int) retEnum;"); + } + } + } + + /** * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class */ @@ -2266,7 +2608,7 @@ public class IoTCompiler { } else { // Generate normal classes if it's not a callback object String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - print("\"" + prmType + "\""); + print("\"" + getEnumType(prmType) + "\""); } if (i != methParams.size() - 1) { print(", "); @@ -2279,10 +2621,14 @@ public class IoTCompiler { // Generate parameters for (int i = 0; i < methParams.size(); i++) { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (!callbackClasses.contains(paramType)) { + if (!callbackClasses.contains(paramType)) { String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); - String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i)); - println(methParamComplete + ";"); + if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i)); + println(methParamComplete + ";"); + } } } // Generate array of parameter objects @@ -2291,6 +2637,8 @@ public class IoTCompiler { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(paramType)) print("&numStubs" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("¶mEnumInt" + i); else print("&" + getSimpleIdentifier(methParams.get(i))); if (i != methParams.size() - 1) { @@ -2301,6 +2649,7 @@ public class IoTCompiler { println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); if (isCallbackMethod) writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType); + checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes); String retType = intDecl.getMethodType(method); // Check if this is "void" if (retType.equals("void")) { @@ -2309,6 +2658,8 @@ public class IoTCompiler { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(paramType)) print("stub" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("paramEnum" + i); else print(getSimpleIdentifier(methParams.get(i))); if (i != methParams.size() - 1) { @@ -2317,11 +2668,17 @@ public class IoTCompiler { } println(");"); } else { // We do have a return value - print(checkAndGetCplusType(retType) + " retVal = " + methodId + "("); + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + print(checkAndGetCplusType(retType) + " retEnum = "); + else + print(checkAndGetCplusType(retType) + " retVal = "); + print(methodId + "("); for (int i = 0; i < methParams.size(); i++) { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(paramType)) print("stub" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("paramEnum" + i); else print(getSimpleIdentifier(methParams.get(i))); if (i != methParams.size() - 1) { @@ -2329,9 +2686,13 @@ public class IoTCompiler { } } println(");"); - println("void* retObj = &retVal;"); + checkAndWriteEnumRetTypeCplusSkeleton(retType); + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + println("void* retObj = &retEnumInt;"); + else + println("void* retObj = &retVal;"); String retTypeC = checkAndGetCplusType(retType); - println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusArrayType(retTypeC) + "\");"); + println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");"); } } @@ -2452,7 +2813,7 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -2639,7 +3000,7 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -2890,6 +3251,10 @@ public class IoTCompiler { // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) { return ParamCategory.NONPRIMITIVES; + } else if (isEnumClass(paramType)) { + return ParamCategory.ENUM; + } else if (isStructClass(paramType)) { + return ParamCategory.STRUCT; } else return ParamCategory.USERDEFINED; } @@ -2988,8 +3353,98 @@ public class IoTCompiler { } + // Handle and return the correct enum declaration + // In Java, if we declare enum in Camera interface, then it becomes "Camera." + private String getEnumParamDecl(String type, InterfaceDecl intDecl) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(type)[0]; + if (isEnumClass(pureType)) { + String enumType = intDecl.getInterface() + "." + type; + return enumType; + } else + return type; + } + + + // Handle and return the correct type + private String getEnumParam(String type, String param, int i) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(type)[0]; + if (isEnumClass(pureType)) { + String enumParam = "paramEnum" + i; + return enumParam; + } else + return param; + } + + + // Handle and return the correct enum declaration translate into int[] + private String getEnumType(String type) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(type)[0]; + if (isEnumClass(pureType)) { + String enumType = "int[]"; + return enumType; + } else + return type; + } + + + // Handle and return the correct struct declaration + private String getStructType(String type) { + + if (isStructClass(type)) { + // TODO: complete this method + return type; + } else + return type; + } + + + // Check if this an enum declaration + private boolean isEnumClass(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set setEnumDecl = enumDecl.getEnumDeclarations(); + if (setEnumDecl.contains(type)) + return true; + } + return false; + } + + + // Check if this an struct declaration + private boolean isStructClass(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List listStructDecl = structDecl.getStructTypes(); + if (listStructDecl.contains(type)) + return true; + } + return false; + } + + // Generate a set of classes for include statements - private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl, boolean needExchange) { + private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl, String intface, boolean needExchange) { Set includeClasses = new HashSet(); for (String method : methods) { @@ -3011,6 +3466,8 @@ public class IoTCompiler { includeClasses.add("\"" + simpleType + ".hpp\""); includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\""); } + } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) { + includeClasses.add("\"" + simpleType + ".hpp\""); } else if (param.contains("[]")) { // Check if this is array for C++; translate into vector includeClasses.add(""); @@ -3074,6 +3531,18 @@ public class IoTCompiler { } + // This helper function strips off array declaration, e.g. int[] becomes int + private String getSimpleArrayType(String type) { + + // Handle [ for array declaration + String substr = type; + if (type.contains("[]")) { + substr = type.split("\\[\\]")[0]; + } + return substr; + } + + // This helper function strips off array declaration, e.g. D[] becomes D private String getSimpleIdentifier(String ident) { @@ -3193,17 +3662,17 @@ public class IoTCompiler { private boolean isArrayOrList(String paramType, String param) { // Check for array declaration - if (isArray(paramType, param)) + if (isArray(param)) return true; - else if (isList(paramType, param)) + else if (isList(paramType)) return true; else return false; } - // Is array or list? - private boolean isArray(String paramType, String param) { + // Is array? For return type we put the return type as input parameter + private boolean isArray(String param) { // Check for array declaration if (param.contains("[]")) @@ -3213,8 +3682,8 @@ public class IoTCompiler { } - // Is array or list? - private boolean isList(String paramType, String param) { + // Is list? + private boolean isList(String paramType) { // Check for array declaration if (paramType.contains("List")) @@ -3299,12 +3768,16 @@ public class IoTCompiler { // Generate everything if we don't see "-java" or "-cplus" if (i == args.length) { + comp.generateEnumJava(); + comp.generateStructJava(); comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); comp.generateJavaCallbackStubClasses(); comp.generateJavaSkeletonClass(); comp.generateJavaCallbackSkeletonClass(); + comp.generateEnumCplus(); + comp.generateStructCplus(); comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); @@ -3325,6 +3798,8 @@ public class IoTCompiler { throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i]); if (args[i].equals("-java")) { + comp.generateEnumJava(); + comp.generateStructJava(); comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); @@ -3332,6 +3807,8 @@ public class IoTCompiler { comp.generateJavaSkeletonClass(); comp.generateJavaCallbackSkeletonClass(); } else { + comp.generateEnumCplus(); + comp.generateStructCplus(); comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); diff --git a/iotjava/iotpolicy/tree/Declaration.java b/iotjava/iotpolicy/tree/Declaration.java index ee2d9c8..b47d964 100644 --- a/iotjava/iotpolicy/tree/Declaration.java +++ b/iotjava/iotpolicy/tree/Declaration.java @@ -27,5 +27,11 @@ public abstract class Declaration { origInt = _origInt; } + + + public String getInterface() { + + return origInt; + } } diff --git a/iotjava/iotpolicy/tree/EnumDecl.java b/iotjava/iotpolicy/tree/EnumDecl.java index 96e57ec..9d3a380 100644 --- a/iotjava/iotpolicy/tree/EnumDecl.java +++ b/iotjava/iotpolicy/tree/EnumDecl.java @@ -63,7 +63,7 @@ public class EnumDecl extends Declaration { } else { // New declaration List newMemberList = new ArrayList(); - newMemberList.add(enumType); + newMemberList.add(newMember); mapEnumMembers.put(enumType, newMemberList); } } diff --git a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp index c42f31a..96b37b4 100644 --- a/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp +++ b/iotjava/iotrmi/C++/sample/TestClass_Skeleton.hpp @@ -368,7 +368,7 @@ int TestClass_Skeleton::___enumSize() { } -void TestClass_Skeleton::___handleEnum(int enumsize1) { +void TestClass_Skeleton::___handleEnum() { int numParam = 1; string paramCls[] = { "int[]" }; @@ -400,7 +400,7 @@ void TestClass_Skeleton::___handleEnum(int enumsize1) { void TestClass_Skeleton::___waitRequestInvokeMethod() { int structsize1 = 0; - int enumsize1 = 0; + // Loop continuously waiting for incoming bytes while (true) { @@ -439,7 +439,7 @@ void TestClass_Skeleton::___waitRequestInvokeMethod() { // Handle struct case 10: ___handleStruct(structsize1); break; case 11: structsize1 = ___structSize(); break; - case 12: ___handleEnum(enumsize1); break; + case 12: ___handleEnum(); break; default: string error = "Method Id not recognized!"; throw error; -- 2.34.1