1
0

refactor: finish loading in ExpFctsRender

This commit is contained in:
2026-01-28 13:50:59 +08:00
parent f5645a06de
commit 69ac25a70b
6 changed files with 278 additions and 190 deletions

View File

@@ -1,184 +1,30 @@
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}.
* The class represent a single parameter (argument) of function.
*/
public static class ExpFctParam {
/**
* The type of this parameter.
*/
public VariableType mVarType;
public String mVarType;
/**
* The name of this parameter.
*/
public String mVarName;
/**
* True if this paramter is marked as input parameter, otherwise false.
* True if this parameter is marked as input parameter, otherwise false.
* <p>
* Input parameter and output paramter is commonly used in C/C++ code. By using
* Input parameter and output parameter 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
* processing output parameter, especially for the scenario that the target
* language do not support explicit output parameter keyword.
*/
public boolean mIsInput;
@@ -186,7 +32,7 @@ public class ExpFctsHelper {
* 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
* underlying C++ type to tell end user how to treat this parameter 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
@@ -195,7 +41,7 @@ public class ExpFctsHelper {
public String mVarDesc;
public ExpFctParam() {
mVarType = new VariableType();
mVarType = "";
mVarName = "";
mVarDesc = "";
mIsInput = true;
@@ -215,9 +61,9 @@ public class ExpFctsHelper {
/**
* The return value type of this function.
*/
public VariableType mFctRetType;
public String mFctRvType;
/**
* The parameters (arguments) list of this function. Each items are
* The parameters (arguments) list of this function. Each item are
* {@linkplain ExpFctParam} and represent parameter one by one from left to
* right.
*/
@@ -225,7 +71,7 @@ public class ExpFctsHelper {
public ExpFct() {
mFctName = "";
mFctRetType = new VariableType();
mFctRvType = "";
mFctParams = new Vector<ExpFctParam>();
}

View File

@@ -1,4 +1,5 @@
import java.util.Collections;
import java.util.Objects;
import java.util.stream.Collectors;
public class ExpFctsWalker extends ExpFctsParserBaseListener {
@@ -32,8 +33,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
// set name
mCurrentFct.mFctName = ctx.EXPFCTS_IDENTIFIER().getText();
// check return type
if (!mCurrentFct.mFctRetType.isValid() || mCurrentFct.mFctRetType.isPointer()
|| !mCurrentFct.mFctRetType.getBaseType().equals("bool"))
if (!Objects.equals(mCurrentFct.mFctRvType, "bool"))
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
// add into list
@@ -47,7 +47,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
param.mVarDesc = "The pointer to corresponding BMFile.";
param.mIsInput = true;
param.mVarType.fromCType("BMap::BMFile*");
param.mVarType = "BMap::BMFile*";
mCurrentFct.mFctParams.add(param);
}
@@ -57,7 +57,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
param.mVarDesc = "The pointer to corresponding BMMeshTransition.";
param.mIsInput = true;
param.mVarType.fromCType("BMap::BMMeshTransition*");
param.mVarType = "BMap::BMMeshTransition*";
mCurrentFct.mFctParams.add(param);
}
@@ -67,14 +67,14 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
firstParam.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
firstParam.mVarDesc = "The pointer to corresponding BMFile.";
firstParam.mIsInput = true;
firstParam.mVarType.fromCType("BMap::BMFile*");
firstParam.mVarType = "BMap::BMFile*";
mCurrentFct.mFctParams.add(firstParam);
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");
secondParam.mVarType = "LibCmo::CK2::CK_ID";
mCurrentFct.mFctParams.add(secondParam);
}
@@ -118,12 +118,15 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
ctype += String.join("", Collections.nCopies(ctx.EXPFCTS_STAR().size(), "*"));
}
if (!mCurrentFct.mFctRetType.isValid()) {
// if there is function return value is not filled,
// we fill it first because return value type is the first captured type in function statement.
// otherwise we fill parameter type.
if (mCurrentFct.mFctRvType.isEmpty()) {
// fill function ret type first
mCurrentFct.mFctRetType.fromCType(ctype);
mCurrentFct.mFctRvType = ctype;
} else {
// otherwise, fill param data
mCurrentParam.mVarType.fromCType(ctype);
mCurrentParam.mVarType = ctype;
}
}

View File

@@ -8,26 +8,13 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonWriter {
private static JsonObject writeVariableType(ExpFctsHelper.VariableType vt) {
JsonObject data = new JsonObject();
JsonArray hierarchy = new JsonArray();
for (String item : vt.getBaseTypeHierarchy()) {
hierarchy.add(item);
}
data.add("hierarchy", hierarchy);
data.addProperty("pointer_level", vt.getPointerLevel());
return data;
}
private static JsonObject writeExpFctParam(ExpFctsHelper.ExpFctParam param) {
JsonObject data = new JsonObject();
data.addProperty("type", param.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;
}
@@ -35,7 +22,7 @@ public class JsonWriter {
private static JsonObject writeExpFct(ExpFctsHelper.ExpFct fct) {
JsonObject data = new JsonObject();
data.addProperty("name", fct.mFctName);
data.add("return", writeVariableType(fct.mFctRetType));
data.addProperty("return", fct.mFctRvType);
JsonArray paramList = new JsonArray();
for (ExpFctsHelper.ExpFctParam param : fct.mFctParams) {