refactor: finish refactor ExpFctsAnalyzer in BMapBinder
This commit is contained in:
@@ -1,286 +0,0 @@
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CSharpWriter {
|
||||
|
||||
/**
|
||||
* The class represent the C# type corresponding to extracted variable type.
|
||||
*/
|
||||
private static class CsInteropType {
|
||||
public CsInteropType() {
|
||||
mMarshalAs = null;
|
||||
mCsType = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The argument of MarshalAsAttribute constructor. In generation, this field
|
||||
* should be used like this: "[MarshalAs(THIS)]" (for parameter) or "[return:
|
||||
* MarshalAs(THIS)]" (for return value).
|
||||
*/
|
||||
public String mMarshalAs;
|
||||
/**
|
||||
* The C# type used in interop function declaration for corresponding parameter.
|
||||
*/
|
||||
public String mCsType;
|
||||
}
|
||||
|
||||
/**
|
||||
* C# specified function which get C# used interop MarshalAs constructor
|
||||
* arguments and C# type used in interop function declaration.
|
||||
*
|
||||
* @param vt The instance of {@linkplain VariableType} for fetching interop
|
||||
* type.
|
||||
* @return The corresponding interop type of given variable type.
|
||||
*/
|
||||
private static CsInteropType getCsInteropType(ExpFctParamDecl paramdecl) {
|
||||
// get essential variable type properties first
|
||||
VariableType vt = paramdecl.mVarType;
|
||||
String vt_base_type = vt.getBaseType();
|
||||
int vt_pointer_level = vt.getPointerLevel();
|
||||
|
||||
// create return value
|
||||
CsInteropType ret = new CsInteropType();
|
||||
|
||||
// use "switch" to check variable type
|
||||
switch (vt_base_type) {
|
||||
case "CKSTRING":
|
||||
// decide direction cookies
|
||||
String direction_cookie = "";
|
||||
if (paramdecl.mIsInput) {
|
||||
direction_cookie = "In";
|
||||
} else {
|
||||
direction_cookie = "Out";
|
||||
}
|
||||
// only allow 0 and 1 pointer level for string.
|
||||
switch (vt_pointer_level) {
|
||||
case 0:
|
||||
ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
|
||||
// ret.mMarshalAs = "UnmanagedType.LPUTF8Str";
|
||||
ret.mCsType = "string";
|
||||
break;
|
||||
case 1:
|
||||
ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
|
||||
ret.mCsType = "string[]";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "CKDWORD":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.U4";
|
||||
ret.mCsType = "uint";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CKWORD":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.U2";
|
||||
ret.mCsType = "ushort";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CKINT":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.I4";
|
||||
ret.mCsType = "int";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "bool":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.U1";
|
||||
ret.mCsType = "bool";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CKFLOAT":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.R4";
|
||||
ret.mCsType = "float";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CKBYTE":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.U1";
|
||||
ret.mCsType = "byte";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CK_ID":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.U4";
|
||||
ret.mCsType = "uint";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "NakedOutputCallback":
|
||||
// callback actually is a function pointer
|
||||
// so it only allow base type without any pointer level.
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.FunctionPtr";
|
||||
ret.mCsType = "OutputCallback";
|
||||
}
|
||||
break;
|
||||
case "BMFile":
|
||||
// In any case, BMFile only should be raw pointer
|
||||
if (vt_pointer_level != 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "BMMeshTransition":
|
||||
// In any case, BMMeshTransition only should be raw pointer
|
||||
if (vt_pointer_level != 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "VxVector3":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
||||
ret.mCsType = "VxVector3";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "VxVector2":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
||||
ret.mCsType = "VxVector2";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "VxColor":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
||||
ret.mCsType = "VxColor";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "VxMatrix":
|
||||
if (vt_pointer_level == 0) {
|
||||
ret.mMarshalAs = "UnmanagedType.Struct";
|
||||
ret.mCsType = "VxMatrix";
|
||||
} else {
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
case "CK_TEXTURE_SAVEOPTIONS":
|
||||
case "VX_PIXELFORMAT":
|
||||
case "VXLIGHT_TYPE":
|
||||
case "VXTEXTURE_BLENDMODE":
|
||||
case "VXTEXTURE_FILTERMODE":
|
||||
case "VXTEXTURE_ADDRESSMODE":
|
||||
case "VXBLEND_MODE":
|
||||
case "VXFILL_MODE":
|
||||
case "VXSHADE_MODE":
|
||||
case "VXCMPFUNC":
|
||||
case "VXMESH_LITMODE":
|
||||
// all enum type use the same strategy
|
||||
if (vt_pointer_level == 0) {
|
||||
// all enum type should be marshaled as its underlying type
|
||||
// but we can use its name in C# directly.
|
||||
ret.mMarshalAs = "UnmanagedType.U4";
|
||||
ret.mCsType = vt_base_type;
|
||||
} else {
|
||||
// for pointer type, use IntPtr instead.
|
||||
ret.mMarshalAs = "UnmanagedType.SysInt";
|
||||
ret.mCsType = "IntPtr";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// check whether we successfully get result
|
||||
if (ret.mMarshalAs == null || ret.mCsType == null) {
|
||||
throw new IllegalArgumentException("Unexpected type: " + vt.toCType());
|
||||
}
|
||||
|
||||
// return value
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void writeCSharpCode(Vector<ExpFctDecl> data) throws Exception {
|
||||
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.cs");
|
||||
IndentHelper helper = new IndentHelper(writer);
|
||||
|
||||
// write function decls
|
||||
for (ExpFctDecl fctdecl : data) {
|
||||
// write annotation
|
||||
// summary (just plain function name)
|
||||
helper.printf("/// <summary>%s</summary>", fctdecl.mFctName);
|
||||
// parameter list
|
||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
||||
helper.printf("/// <param name=\"%s\">Type: %s. %s%s</param>", paramdecl.mVarName,
|
||||
paramdecl.mVarType.toCType(), (paramdecl.mIsInput ? "" : "This is OUT parameter. "),
|
||||
paramdecl.mVarDesc);
|
||||
}
|
||||
// return value
|
||||
helper.puts("/// <returns>True if no error, otherwise False.</returns>");
|
||||
|
||||
// write real function declaration
|
||||
// first, write DllImportAttribute
|
||||
helper.printf(
|
||||
"[DllImport(g_DllName, EntryPoint = \"%s\", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]",
|
||||
fctdecl.mFctName);
|
||||
// second, write return value MarshalAsAttribute
|
||||
helper.printf("[return: MarshalAs(UnmanagedType.U1)]");
|
||||
// then, before we write function body, we need origanize its parameter list
|
||||
// first
|
||||
Vector<String> cs_param_list = new Vector<String>();
|
||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
||||
// create string builder
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// push in out symbol
|
||||
if (paramdecl.mIsInput) {
|
||||
sb.append("[In, ");
|
||||
} else {
|
||||
sb.append("[Out, ");
|
||||
}
|
||||
// get interop type now
|
||||
CsInteropType interop_type = getCsInteropType(paramdecl);
|
||||
// push MarshalAsAttribute
|
||||
sb.append("MarshalAs(");
|
||||
sb.append(interop_type.mMarshalAs);
|
||||
sb.append(")] ");
|
||||
// push out keyword if parameter is out parameter
|
||||
if (!paramdecl.mIsInput) {
|
||||
sb.append("out ");
|
||||
}
|
||||
// push parameter cs type
|
||||
sb.append(interop_type.mCsType);
|
||||
sb.append(" ");
|
||||
// push parameter name
|
||||
sb.append(paramdecl.mVarName);
|
||||
// insert built string into list
|
||||
cs_param_list.add(sb.toString());
|
||||
}
|
||||
// join built parameter list and output real function declaration
|
||||
helper.printf("internal static extern bool %s(%s);", fctdecl.mFctName,
|
||||
cs_param_list.stream().collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,29 +3,32 @@ import java.io.FileOutputStream;
|
||||
//import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class CommonHelper {
|
||||
|
||||
// public static InputStreamReader openReader(String filename) throws Exception {
|
||||
// FileInputStream fs = new FileInputStream(filename);
|
||||
// return new InputStreamReader(fs, StandardCharsets.UTF_8);
|
||||
// }
|
||||
// =========== File Operations ===========
|
||||
|
||||
public static OutputStreamWriter openWriter(String filename) throws Exception {
|
||||
FileOutputStream fs = new FileOutputStream(filename);
|
||||
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||
private static Path getRootDirectoryPath() throws Exception {
|
||||
String rootDir = System.getenv("BMAP_BINDER_ROOT");
|
||||
if (rootDir == null) {
|
||||
throw new RuntimeException("Can not find essential environment variable BMAP_BINDER_ROOT");
|
||||
} else {
|
||||
return Paths.get(rootDir);
|
||||
}
|
||||
}
|
||||
|
||||
// public static void writeSnippet(OutputStreamWriter writer, String snippet_path) throws Exception {
|
||||
// // open snippet
|
||||
// InputStreamReader reader = openReader(snippet_path);
|
||||
// // write into writer
|
||||
// reader.transferTo(writer);
|
||||
// reader.close();
|
||||
// }
|
||||
|
||||
public static String getDoxygenInOutStr(boolean isInput) {
|
||||
return isInput ? "in" : "out";
|
||||
public static String getInputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Extracted").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
public static String getOutputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Analyzed").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* The class represent an export BMap function.
|
||||
*/
|
||||
public class ExpFctDecl {
|
||||
|
||||
/**
|
||||
* The name of this function.
|
||||
*/
|
||||
public String mFctName;
|
||||
/**
|
||||
* The return value type of this function.
|
||||
*/
|
||||
public VariableType mFctRetType;
|
||||
/**
|
||||
* The parameters (arguments) list of this function. Each items are
|
||||
* {@linkplain ExpFctParamDecl} and represent parameter one by one from left to
|
||||
* right.
|
||||
*/
|
||||
public Vector<ExpFctParamDecl> mFctParams;
|
||||
|
||||
public ExpFctDecl() {
|
||||
mFctName = "";
|
||||
mFctRetType = new VariableType();
|
||||
mFctParams = new Vector<ExpFctParamDecl>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
/**
|
||||
* The class represent a single parameter (argument) of function. This class
|
||||
* usually is the member of {@linkplain ExpFctDecl}.
|
||||
*/
|
||||
public class ExpFctParamDecl {
|
||||
|
||||
/**
|
||||
* The type of this parameter.
|
||||
*/
|
||||
public VariableType mVarType;
|
||||
/**
|
||||
* The name of this parameter.
|
||||
*/
|
||||
public String mVarName;
|
||||
/**
|
||||
* True if this paramter is marked as input parameter, otherwise false.
|
||||
* <p>
|
||||
* Input parameter and output paramter is commonly used in C/C++ code. By using
|
||||
* this feature, each function can receive multiple arguments and return
|
||||
* multiple arguments without defining a struct to hold it.
|
||||
* <p>
|
||||
* The type of input parameter is itself. However, the type of output parameter
|
||||
* is the pointer of itself. So you may need get its pointer type when
|
||||
* processing output paramter, especially for the scenario that the target
|
||||
* language do not support explicit output parameter keyword.
|
||||
*/
|
||||
public boolean mIsInput;
|
||||
/**
|
||||
* The description of this parameter.
|
||||
* <p>
|
||||
* This description is generated by this program. It will indicate the
|
||||
* underlying C++ type to tell end user how to treat this paramter because some
|
||||
* target languages' native calling style can not represent these detail.
|
||||
* <p>
|
||||
* In this program, this field must be written as a annotation of corresponding
|
||||
* function.
|
||||
*/
|
||||
public String mVarDesc;
|
||||
|
||||
public ExpFctParamDecl() {
|
||||
mVarType = new VariableType();
|
||||
mVarName = "";
|
||||
mVarDesc = "";
|
||||
mIsInput = true;
|
||||
}
|
||||
|
||||
}
|
||||
248
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
248
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
@@ -0,0 +1,248 @@
|
||||
import java.util.Collections;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ExpFctsHelper {
|
||||
|
||||
/**
|
||||
* The class represent the type of each parameters and function return value.
|
||||
*/
|
||||
public static class VariableType {
|
||||
/**
|
||||
* The base type of this variable removing all ending stars (remove all pointer levels).
|
||||
* Each item in this Vector is a part of namespace and the last one must be the type itself
|
||||
* (without any namespace constraint).
|
||||
* If no namespace constraint for this type, this Vector will only have one item.
|
||||
* <p>
|
||||
* For end user, it is enough that knowing the last item is type itself.
|
||||
*/
|
||||
private Vector<String> mBaseType;
|
||||
/**
|
||||
* The pointer level of this type. It is equal to the count of trailing star of
|
||||
* this field in C style representation.
|
||||
*/
|
||||
private int mPointerLevel;
|
||||
|
||||
/**
|
||||
* Construct an empty varible type. This is commonly used constructor.
|
||||
*/
|
||||
public VariableType() {
|
||||
mBaseType = new Vector<String>();
|
||||
mPointerLevel = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor used for cloning self. This constructor is only can be used
|
||||
* by self.
|
||||
*
|
||||
* @param base_type The hierarchy of the variable type.
|
||||
* @param pointer_level The pointer level of new created variable type.
|
||||
*/
|
||||
private VariableType(Vector<String> base_type, int pointer_level) {
|
||||
mBaseType = (Vector<String>) base_type.clone();
|
||||
mPointerLevel = pointer_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this variable type with a type string in C/C++ style. For example
|
||||
* "NSTest::NSTest2::MyType**".
|
||||
*
|
||||
* @param ctype The type string in C/C++ style.
|
||||
*/
|
||||
public void fromCType(String ctype) {
|
||||
if (ctype.isEmpty())
|
||||
throw new IllegalArgumentException("empty string can not be parsed.");
|
||||
|
||||
// get pointer part and name part
|
||||
int len = ctype.length();
|
||||
int star_pos = ctype.indexOf('*');
|
||||
String namepart;
|
||||
if (star_pos == -1) {
|
||||
// no star
|
||||
namepart = ctype;
|
||||
mPointerLevel = 0;
|
||||
} else {
|
||||
// has star
|
||||
if (star_pos == 0)
|
||||
throw new IllegalArgumentException("base type not found.");
|
||||
namepart = ctype.substring(0, star_pos);
|
||||
mPointerLevel = len - star_pos;
|
||||
}
|
||||
|
||||
// resolve name part
|
||||
mBaseType.clear();
|
||||
for (String item : namepart.split("::")) {
|
||||
mBaseType.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a type string represented by this variable type in C/C++ style.
|
||||
*
|
||||
* @return The type string in C/C++ style.
|
||||
*/
|
||||
public String toCType() {
|
||||
return mBaseType.stream().collect(Collectors.joining("::"))
|
||||
+ String.join("", Collections.nCopies(mPointerLevel, "*"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base type of this variable type without any namespace. It just simply
|
||||
* get the last entry in type hierarchy.
|
||||
*
|
||||
* @return The base type string without namespace prefix.
|
||||
*/
|
||||
public String getBaseType() {
|
||||
return mBaseType.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this variable type is a pointer. This function just check
|
||||
* whether the pointer level of this variavle type is zero.
|
||||
*
|
||||
* @return True if it is pointer, otherwise false.
|
||||
*/
|
||||
public boolean isPointer() {
|
||||
return mPointerLevel != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pointer level of this variable type. You can simply assume the
|
||||
* pointer level is equal to the count of trailing star.
|
||||
*
|
||||
* @return The pointer level integer. Zero means that this type is not a
|
||||
* pointer.
|
||||
*/
|
||||
public int getPointerLevel() {
|
||||
return mPointerLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the clone of the type hierarchy of this variable type.
|
||||
* <p>
|
||||
* It is rarely used. This only should be used when you need the namespace
|
||||
* hierarchy of this variable type.
|
||||
*
|
||||
* @return The clone of current variable type hierarchy.
|
||||
*/
|
||||
public Vector<String> getBaseTypeHierarchy() {
|
||||
return (Vector<String>) mBaseType.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this type is a valid one. It actually check whether type
|
||||
* hierarchy include at least one entry.
|
||||
*
|
||||
* @return True if no problem of this type, otherwise false.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return mBaseType.size() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new created variable type which is the pointer of this variable
|
||||
* type.
|
||||
* <p>
|
||||
* In internal implementation, it just create a clone of current variable type
|
||||
* with the increase of pointer level by 1.
|
||||
*
|
||||
* @return The new created pointer type of this variable type.
|
||||
*/
|
||||
public VariableType getPointerOfThis() {
|
||||
return new VariableType(mBaseType, mPointerLevel + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The class represent a single parameter (argument) of function. This class
|
||||
* usually is the member of {@linkplain ExpFct}.
|
||||
*/
|
||||
public static class ExpFctParam {
|
||||
|
||||
/**
|
||||
* The type of this parameter.
|
||||
*/
|
||||
public VariableType mVarType;
|
||||
/**
|
||||
* The name of this parameter.
|
||||
*/
|
||||
public String mVarName;
|
||||
/**
|
||||
* True if this paramter is marked as input parameter, otherwise false.
|
||||
* <p>
|
||||
* Input parameter and output paramter is commonly used in C/C++ code. By using
|
||||
* this feature, each function can receive multiple arguments and return
|
||||
* multiple arguments without defining a struct to hold it.
|
||||
* <p>
|
||||
* The type of input parameter is itself. However, the type of output parameter
|
||||
* is the pointer of itself. So you may need get its pointer type when
|
||||
* processing output paramter, especially for the scenario that the target
|
||||
* language do not support explicit output parameter keyword.
|
||||
*/
|
||||
public boolean mIsInput;
|
||||
/**
|
||||
* The description of this parameter.
|
||||
* <p>
|
||||
* This description is generated by this program. It will indicate the
|
||||
* underlying C++ type to tell end user how to treat this paramter because some
|
||||
* target languages' native calling style can not represent these detail.
|
||||
* <p>
|
||||
* In this program, this field must be written as a annotation of corresponding
|
||||
* function.
|
||||
*/
|
||||
public String mVarDesc;
|
||||
|
||||
public ExpFctParam() {
|
||||
mVarType = new VariableType();
|
||||
mVarName = "";
|
||||
mVarDesc = "";
|
||||
mIsInput = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The class represent an export BMap function.
|
||||
*/
|
||||
public static class ExpFct {
|
||||
|
||||
/**
|
||||
* The name of this function.
|
||||
*/
|
||||
public String mFctName;
|
||||
/**
|
||||
* The return value type of this function.
|
||||
*/
|
||||
public VariableType mFctRetType;
|
||||
/**
|
||||
* The parameters (arguments) list of this function. Each items are
|
||||
* {@linkplain ExpFctParam} and represent parameter one by one from left to
|
||||
* right.
|
||||
*/
|
||||
public Vector<ExpFctParam> mFctParams;
|
||||
|
||||
public ExpFct() {
|
||||
mFctName = "";
|
||||
mFctRetType = new VariableType();
|
||||
mFctParams = new Vector<ExpFctParam>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The class represent a collection of export BMap functions.
|
||||
*/
|
||||
public static class ExpFctCollection {
|
||||
/**
|
||||
* The collection of exported BMap functions.
|
||||
*/
|
||||
public Vector<ExpFct> mFcts;
|
||||
|
||||
public ExpFctCollection() {
|
||||
mFcts = new Vector<ExpFct>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +1,30 @@
|
||||
import java.util.Collections;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
|
||||
public ExpFctsWalker() {
|
||||
mFctList = new Vector<ExpFctDecl>();
|
||||
mFctCollection = null;
|
||||
mCurrentFct = null;
|
||||
mCurrentParam = null;
|
||||
}
|
||||
|
||||
public Vector<ExpFctDecl> getResult() {
|
||||
return mFctList;
|
||||
public ExpFctsHelper.ExpFctCollection getResult() {
|
||||
return mFctCollection;
|
||||
}
|
||||
|
||||
private Vector<ExpFctDecl> mFctList;
|
||||
private ExpFctDecl mCurrentFct;
|
||||
private ExpFctParamDecl mCurrentParam;
|
||||
private ExpFctsHelper.ExpFctCollection mFctCollection;
|
||||
private ExpFctsHelper.ExpFct mCurrentFct;
|
||||
private ExpFctsHelper.ExpFctParam mCurrentParam;
|
||||
|
||||
@Override
|
||||
public void enterProgram(ExpFctsParser.ProgramContext ctx) {
|
||||
mFctList.clear();
|
||||
mFctCollection = new ExpFctsHelper.ExpFctCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
||||
mCurrentFct = new ExpFctDecl();
|
||||
mCurrentFct = new ExpFctsHelper.ExpFct();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,50 +37,50 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
|
||||
|
||||
// add into list
|
||||
mFctList.add(mCurrentFct);
|
||||
mFctCollection.mFcts.add(mCurrentFct);
|
||||
mCurrentFct = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
param.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
param.mIsInput = true;
|
||||
param.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
param.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||
param.mIsInput = true;
|
||||
param.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||
mCurrentFct.mFctParams.add(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
||||
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
||||
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||
first_decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
first_decl.mIsInput = true;
|
||||
first_decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(first_decl);
|
||||
ExpFctsHelper.ExpFctParam firstParam = new ExpFctsHelper.ExpFctParam();
|
||||
firstParam.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||
firstParam.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
firstParam.mIsInput = true;
|
||||
firstParam.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(firstParam);
|
||||
|
||||
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
||||
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||
second_decl.mVarDesc = "The CKID of object you accessing.";
|
||||
second_decl.mIsInput = true;
|
||||
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||
mCurrentFct.mFctParams.add(second_decl);
|
||||
ExpFctsHelper.ExpFctParam secondParam = new ExpFctsHelper.ExpFctParam();
|
||||
secondParam.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||
secondParam.mVarDesc = "The CKID of object you accessing.";
|
||||
secondParam.mIsInput = true;
|
||||
secondParam.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||
mCurrentFct.mFctParams.add(secondParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFctArgParamIn(ExpFctsParser.FctArgParamInContext ctx) {
|
||||
mCurrentParam = new ExpFctParamDecl();
|
||||
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +94,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterFctArgParamOut(ExpFctsParser.FctArgParamOutContext ctx) {
|
||||
mCurrentParam = new ExpFctParamDecl();
|
||||
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class IndentHelper {
|
||||
public IndentHelper(OutputStreamWriter writer) {
|
||||
mIndent = 0;
|
||||
mWriter = writer;
|
||||
}
|
||||
|
||||
private int mIndent;
|
||||
private OutputStreamWriter mWriter;
|
||||
|
||||
public void inc() {
|
||||
++mIndent;
|
||||
}
|
||||
|
||||
public void dec() {
|
||||
--mIndent;
|
||||
}
|
||||
|
||||
private void indent() throws Exception {
|
||||
for (int i = 0; i < mIndent; ++i) {
|
||||
mWriter.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void lineBreak() throws Exception {
|
||||
mWriter.write(System.lineSeparator());
|
||||
}
|
||||
|
||||
public void puts(String data) throws Exception {
|
||||
indent();
|
||||
mWriter.write(data);
|
||||
lineBreak();
|
||||
}
|
||||
|
||||
public void printf(String fmt, Object... args) throws Exception {
|
||||
indent();
|
||||
mWriter.write(String.format(fmt, args));
|
||||
lineBreak();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Vector;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.Gson;
|
||||
@@ -7,7 +9,7 @@ import com.google.gson.GsonBuilder;
|
||||
|
||||
public class JsonWriter {
|
||||
|
||||
private static JsonObject writeVariableType(VariableType vt) {
|
||||
private static JsonObject writeVariableType(ExpFctsHelper.VariableType vt) {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
JsonArray hierarchy = new JsonArray();
|
||||
@@ -20,41 +22,44 @@ public class JsonWriter {
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonObject writeExpFctParamDecl(ExpFctParamDecl paramdecl) {
|
||||
private static JsonObject writeExpFctParam(ExpFctsHelper.ExpFctParam param) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("name", paramdecl.mVarName);
|
||||
data.addProperty("is_input", paramdecl.mIsInput);
|
||||
data.addProperty("desc", paramdecl.mVarDesc);
|
||||
data.add("type", writeVariableType(paramdecl.mVarType));
|
||||
data.addProperty("name", param.mVarName);
|
||||
data.addProperty("is_input", param.mIsInput);
|
||||
data.addProperty("desc", param.mVarDesc);
|
||||
data.add("type", writeVariableType(param.mVarType));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonObject writeExpFctDecl(ExpFctDecl fctdecl) {
|
||||
private static JsonObject writeExpFct(ExpFctsHelper.ExpFct fct) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("name", fctdecl.mFctName);
|
||||
data.add("return", writeVariableType(fctdecl.mFctRetType));
|
||||
data.addProperty("name", fct.mFctName);
|
||||
data.add("return", writeVariableType(fct.mFctRetType));
|
||||
|
||||
JsonArray paramlist = new JsonArray();
|
||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
||||
paramlist.add(writeExpFctParamDecl(paramdecl));
|
||||
JsonArray paramList = new JsonArray();
|
||||
for (ExpFctsHelper.ExpFctParam param : fct.mFctParams) {
|
||||
paramList.add(writeExpFctParam(param));
|
||||
}
|
||||
data.add("params", paramlist);
|
||||
data.add("params", paramList);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void writeJson(Vector<ExpFctDecl> data) throws Exception {
|
||||
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.json");
|
||||
//Gson gson_instance = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
Gson gson_instance = new GsonBuilder().disableHtmlEscaping().create();
|
||||
|
||||
JsonArray fcts = new JsonArray();
|
||||
for (ExpFctDecl fctdecl : data) {
|
||||
fcts.add(writeExpFctDecl(fctdecl));
|
||||
|
||||
private static JsonArray writeExpFctCollection(ExpFctsHelper.ExpFctCollection fctCollection) {
|
||||
JsonArray data = new JsonArray();
|
||||
for (ExpFctsHelper.ExpFct fct : fctCollection.mFcts) {
|
||||
data.add(writeExpFct(fct));
|
||||
}
|
||||
|
||||
writer.write(gson_instance.toJson(fcts));
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void writeJson(ExpFctsHelper.ExpFctCollection data) throws Exception {
|
||||
FileOutputStream fs = new FileOutputStream(CommonHelper.getOutputFilePath("BMExports.json"));
|
||||
OutputStreamWriter writer = new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||
//Gson gsonInstance = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
||||
writer.write(gsonInstance.toJson(writeExpFctCollection(data)));
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ public class MainRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// get interface structure
|
||||
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
||||
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
||||
FileInputStream fs = new FileInputStream(CommonHelper.getInputFilePath("BMExports.hpp"));
|
||||
CharStream antlrStream = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
ExpFctsParser parser = new ExpFctsParser(tokens);
|
||||
|
||||
@@ -23,12 +23,10 @@ public class MainRunner {
|
||||
fs.close();
|
||||
|
||||
// get data and write them
|
||||
Vector<ExpFctDecl> result = worker.getResult();
|
||||
PythonWriter.writePythonCode(result);
|
||||
CSharpWriter.writeCSharpCode(result);
|
||||
ExpFctsHelper.ExpFctCollection result = worker.getResult();
|
||||
JsonWriter.writeJson(result);
|
||||
|
||||
// print message.
|
||||
System.out.println("DONE!");
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PythonWriter {
|
||||
|
||||
private static final Map<String, String> g_CppTypeMap = cppTypeMapCreator();
|
||||
|
||||
private static Map<String, String> cppTypeMapCreator() {
|
||||
Map<String, String> cache = new HashMap<String, String>();
|
||||
cache.put("CKSTRING", "CKSTRING");
|
||||
cache.put("CKDWORD", "CKDWORD");
|
||||
cache.put("CKWORD", "CKWORD");
|
||||
cache.put("CKINT", "CKINT");
|
||||
cache.put("bool", "bool");
|
||||
cache.put("CKFLOAT", "CKFLOAT");
|
||||
cache.put("CKBYTE", "CKBYTE");
|
||||
cache.put("CK_ID", "CKID");
|
||||
cache.put("NakedOutputCallback", "callback");
|
||||
cache.put("BMFile", "void");
|
||||
cache.put("BMMeshTransition", "void");
|
||||
cache.put("VxVector3", "VxVector3");
|
||||
cache.put("VxVector2", "VxVector2");
|
||||
cache.put("VxColor", "VxColor");
|
||||
cache.put("VxMatrix", "VxMatrix");
|
||||
cache.put("CK_TEXTURE_SAVEOPTIONS", "enum");
|
||||
cache.put("VX_PIXELFORMAT", "enum");
|
||||
cache.put("VXLIGHT_TYPE", "enum");
|
||||
cache.put("VXTEXTURE_BLENDMODE", "enum");
|
||||
cache.put("VXTEXTURE_FILTERMODE", "enum");
|
||||
cache.put("VXTEXTURE_ADDRESSMODE", "enum");
|
||||
cache.put("VXBLEND_MODE", "enum");
|
||||
cache.put("VXFILL_MODE", "enum");
|
||||
cache.put("VXSHADE_MODE", "enum");
|
||||
cache.put("VXCMPFUNC", "enum");
|
||||
cache.put("VXMESH_LITMODE", "enum");
|
||||
return Collections.unmodifiableMap(cache);
|
||||
}
|
||||
|
||||
private static String pythonTypeGetter(ExpFctParamDecl paramdecl) throws IllegalArgumentException {
|
||||
VariableType vt = paramdecl.mVarType;
|
||||
if (!paramdecl.mIsInput) {
|
||||
vt = vt.getPointerOfThis();
|
||||
}
|
||||
|
||||
// create string builder for build final type string
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// add type prefix
|
||||
sb.append("bm_");
|
||||
// try getting cpp type from base type
|
||||
String cpp_type = g_CppTypeMap.get(vt.getBaseType());
|
||||
if (cpp_type == null) {
|
||||
throw new IllegalArgumentException("Unexpected type: " + vt.toCType());
|
||||
}
|
||||
// assign cpp type
|
||||
sb.append(cpp_type);
|
||||
// add pointer suffix
|
||||
if (vt.isPointer()) {
|
||||
sb.append("_");
|
||||
sb.append(String.join("", Collections.nCopies(vt.getPointerLevel(), "p")));
|
||||
}
|
||||
// return built type string.
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void writePythonCode(Vector<ExpFctDecl> data) throws Exception {
|
||||
OutputStreamWriter writer = CommonHelper.openWriter("dest/BMExports.py");
|
||||
IndentHelper helper = new IndentHelper(writer);
|
||||
|
||||
// write function decls
|
||||
for (ExpFctDecl fctdecl : data) {
|
||||
// write annotation
|
||||
// function name
|
||||
helper.printf("## %s", fctdecl.mFctName);
|
||||
// param
|
||||
for (ExpFctParamDecl paramdecl : fctdecl.mFctParams) {
|
||||
helper.printf("# @param %s[%s] Type: %s. %s%s", paramdecl.mVarName,
|
||||
CommonHelper.getDoxygenInOutStr(paramdecl.mIsInput), paramdecl.mVarType.toCType(),
|
||||
(paramdecl.mIsInput ? "" : "Use ctypes.byref(data) pass it. "), paramdecl.mVarDesc);
|
||||
}
|
||||
// return val
|
||||
helper.puts("# @return True if no error, otherwise False.");
|
||||
|
||||
// write real declaration
|
||||
// first, we need join all param
|
||||
helper.printf("%s = _create_bmap_func('%s', [%s])", fctdecl.mFctName, fctdecl.mFctName, fctdecl.mFctParams
|
||||
.stream().map(value -> pythonTypeGetter(value)).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
import java.util.Collections;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The class represent the type of each parameters and function return value.
|
||||
*/
|
||||
public class VariableType {
|
||||
/**
|
||||
* The base type of this variable removing all ending stars (remove all pointer
|
||||
* levels) Each item in this a part of namespace and the last one must be the
|
||||
* type itself (without any namespace restriction). If no namespace restriction
|
||||
* for this type, this Vector will only have one item.
|
||||
* <p>
|
||||
* For end user, it is enough that knowing the last item is type itself.
|
||||
*/
|
||||
private Vector<String> mBaseType;
|
||||
/**
|
||||
* The pointer level of this type. It is equal to the count of trailing star of
|
||||
* this field in C style representation.
|
||||
*/
|
||||
private int mPointerLevel;
|
||||
|
||||
/**
|
||||
* Construct an empty varible type. This is commonly used constructor.
|
||||
*/
|
||||
public VariableType() {
|
||||
mBaseType = new Vector<String>();
|
||||
mPointerLevel = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor used for cloning self. This constructor is only can be used
|
||||
* by self.
|
||||
*
|
||||
* @param base_type The hierarchy of the variable type.
|
||||
* @param pointer_level The pointer level of new created variable type.
|
||||
*/
|
||||
private VariableType(Vector<String> base_type, int pointer_level) {
|
||||
mBaseType = (Vector<String>) base_type.clone();
|
||||
mPointerLevel = pointer_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this variable type with a type string in C/C++ style. For example
|
||||
* "NSTest::NSTest2::MyType**".
|
||||
*
|
||||
* @param ctype The type string in C/C++ style.
|
||||
*/
|
||||
public void fromCType(String ctype) {
|
||||
if (ctype.isEmpty())
|
||||
throw new IllegalArgumentException("empty string can not be parsed.");
|
||||
|
||||
// get pointer part and name part
|
||||
int len = ctype.length();
|
||||
int star_pos = ctype.indexOf('*');
|
||||
String namepart;
|
||||
if (star_pos == -1) {
|
||||
// no star
|
||||
namepart = ctype;
|
||||
mPointerLevel = 0;
|
||||
} else {
|
||||
// has star
|
||||
if (star_pos == 0)
|
||||
throw new IllegalArgumentException("base type not found.");
|
||||
namepart = ctype.substring(0, star_pos);
|
||||
mPointerLevel = len - star_pos;
|
||||
}
|
||||
|
||||
// resolve name part
|
||||
mBaseType.clear();
|
||||
for (String item : namepart.split("::")) {
|
||||
mBaseType.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a type string represented by this variable type in C/C++ style.
|
||||
*
|
||||
* @return The type string in C/C++ style.
|
||||
*/
|
||||
public String toCType() {
|
||||
return mBaseType.stream().collect(Collectors.joining("::"))
|
||||
+ String.join("", Collections.nCopies(mPointerLevel, "*"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base type of this variable type without any namespace. It just simply
|
||||
* get the last entry in type hierarchy.
|
||||
*
|
||||
* @return The base type string without namespace prefix.
|
||||
*/
|
||||
public String getBaseType() {
|
||||
return mBaseType.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this variable type is a pointer. This function just check
|
||||
* whether the pointer level of this variavle type is zero.
|
||||
*
|
||||
* @return True if it is pointer, otherwise false.
|
||||
*/
|
||||
public boolean isPointer() {
|
||||
return mPointerLevel != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pointer level of this variable type. You can simply assume the
|
||||
* pointer level is equal to the count of trailing star.
|
||||
*
|
||||
* @return The pointer level integer. Zero means that this type is not a
|
||||
* pointer.
|
||||
*/
|
||||
public int getPointerLevel() {
|
||||
return mPointerLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the clone of the type hierarchy of this variable type.
|
||||
* <p>
|
||||
* It is rarely used. This only should be used when you need the namespace
|
||||
* hierarchy of this variable type.
|
||||
*
|
||||
* @return The clone of current variable type hierarchy.
|
||||
*/
|
||||
public Vector<String> getBaseTypeHierarchy() {
|
||||
return (Vector<String>) mBaseType.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this type is a valid one. It actually check whether type
|
||||
* hierarchy include at least one entry.
|
||||
*
|
||||
* @return True if no problem of this type, otherwise false.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return mBaseType.size() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new created variable type which is the pointer of this variable
|
||||
* type.
|
||||
* <p>
|
||||
* In internal implementation, it just create a clone of current variable type
|
||||
* with the increase of pointer level by 1.
|
||||
*
|
||||
* @return The new created pointer type of this variable type.
|
||||
*/
|
||||
public VariableType getPointerOfThis() {
|
||||
return new VariableType(mBaseType, mPointerLevel + 1);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user