在"uta使用说明"中,对cpgf生成的代码需要手工处理(2.7,2.8),为了消除此环节对cpgf的metagen工具进行修改.
代码修改后新的配置文件(TestService.js)内容如下:
var config = { projectID:"TestService", mainSourceFile:"register_meta_TestService", headerOutput : "./TestService/output", sourceOutput:"./TestService/output", excludedClass:["^[A-Za-z_]\\w*__isset$","^TestService_\\w+_result$","^TestService_\\w+_args$","^TestService_\\w+_presult$","^TestService_\\w+_pargs$","TestServiceIf"], stripPath:true, stripIncPath:"./services/TestService" }; |
代码修改记录如下:其中红色标记的为新增内容.
增加STLCategory.java
STL模板类型枚举类型定义,目前仅支持vector。
package org.cpgf.metagen.metadata;
public enum STLCategory { Vector } |
增加STLParameterType.java
STL参数化类型定义,如vector<stA>.
package org.cpgf.metagen.metadata;
public class STLParameterType { public STLCategory category; public String name; private String nameSpace; public CppClass cppClass; public STLParameterType(String s,STLCategory c,CppClass cls) { name = s; category = c; cppClass = cls;
int pos = cppClass.getLiteralName().lastIndexOf(':'); nameSpace = pos<0 ? "" : cppClass.getLiteralName().substring(0,pos-1); } public String getNameSpace() { return nameSpace; } } |
Config.java修改
新增3个配置项.
public String[] excludedClass = null;///{"^[A-Za-z_]\\w*__isset$"}; public boolean stripPath = false; public String stripIncPath=""; |
excludedClass: 不需要导出的类匹配模式字符串数组,指定不需要导出的类
stripPath:指定是否需要剥离源文件路径.兼容性考虑
stripIncPath:指定剥离文件路径后的包含路径
DoxygenXmlParser.java修改
import org.cpgf.metagen.metadata.STLCategory; import org.cpgf.metagen.metadata.STLCategory; import org.cpgf.metagen.metadata.STLParameterType;
///< 按配置过滤不需要导出的类 private boolean doFilterClass(String className) { for (int i=0;i<config.excludedClass.length;i++) { if (className.matches(config.excludedClass[i])) return true; }
return false; }
private void doParseClass(Node node, String location) { String className = Util.getNodeText(Util.getNode(node, "compoundname")); ///< 过滤不需要导出的类 if (doFilterClass(Util.getItemBaseName(className))) return; CppClass cppClass = this.enterClass(className); cppClass.setLocation(location);
try { this.doParseBaseClasses(node); this.doParseInnerClasses(node); this.doParseAllSectionDef(node, location); this.doParseTemplateParams(node, cppClass);
this.resolveNamespace(cppClass); } finally { this.leaveClass(); } }
private Item doParseMethod(Node node, String name) { if(! this.getCurrentClass().isGlobal()) { if(name.indexOf('~') >= 0 && ! name.matches("operator\\s*~")) { Destructor destructor = new Destructor(); this.getCurrentClass().setDestructor(destructor);
return destructor; }
if(this.getCurrentClass().getPrimaryName().equals(name)) { // constructor Constructor constructor = new Constructor(); this.doParseParams(node, constructor); this.doParseTemplateParams(node, constructor); this.getCurrentClass().getConstructorList().add(constructor); constructor.setExplicit(Util.isValueYes(Util.getAttribute(node, "explicit")));
return constructor; } }
Pattern pattern = Pattern.compile("^.*\\boperator(.*)$"); Matcher matcher = pattern.matcher(name);
if(matcher.matches()) { // operator String op = matcher.group(1); Operator operator = new Operator( op, new CppType(this.metaInfo.getTypeSolver(), Util.getNodeText(Util.getNode(node, "type"))) );
operator.setStatic(Util.isValueYes(Util.getAttribute(node, "static"))); operator.setConst(Util.isValueYes(Util.getAttribute(node, "const")));
if(operator.getResultType().isEmpty()) { // type convertion operator, T() operator.setResultType(new CppType(this.metaInfo.getTypeSolver(), operator.getOperator())); } this.doParseParams(node, operator); ///< operator方法若参数名称为null则不导出 for (Parameter item : operator.getParameterList()) { if (item.getName()==null) return null; } this.doParseTemplateParams(node, operator); this.getCurrentClass().getOperatorList().add(operator);
return operator; }
// method CppMethod method = new CppMethod( name, new CppType(this.metaInfo.getTypeSolver(), Util.getNodeText(Util.getNode(node, "type"))) ); method.setStatic(Util.isValueYes(Util.getAttribute(node, "static"))); method.setConst(Util.isValueYes(Util.getAttribute(node, "const"))); method.setVirtual(Util.getAttribute(node, "virt").equals("virtual")); method.setPureVirtual(Util.getAttribute(node, "virt").equals("pure-virtual"));
this.doParseParams(node, method); this.doParseTemplateParams(node, method); this.getCurrentClass().getMethodList().add(method);
return method; }
private Item doParseField(Node node, String name) { CppField field = new CppField(name, this.getType(node));
field.setStatic(Util.isValueYes(Util.getAttribute(node, "static")));
Node bitFieldNode = Util.getNode(node, "bitfield"); if(bitFieldNode != null) { field.setBitField(Integer.parseInt(Util.getNodeText(bitFieldNode))); }
///< 如果是STL vector成员,则保存参数化类型对象. this.getCurrentClass().getFieldList().add(field);
if (field.getType().getParsedType().getBaseType().equals("std::vector")) { Pattern pattern = Pattern.compile(".*<(.+)>$"); Matcher matcher=pattern.matcher(field.getType().getParsedType().getLiteralType()); if (matcher.matches()) { String typeName = matcher.group(1).trim();
boolean found = false; for (STLParameterType stlParameterType : this.metaInfo.stlParameterTypeList) { if (stlParameterType.name.equals(typeName)) { found = true; break; } } if (!found) { for (CppClass cppClass : this.metaInfo.getClassList()) { if (cppClass.getPrimaryName().equals(typeName)) { STLParameterType stlParameterType = new STLParameterType(typeName,STLCategory.Vector,cppClass); this.metaInfo.stlParameterTypeList.add(stlParameterType); break; } } } } }
return field; } |
MetaInfo.java修改
public List<STLParameterType> stlParameterTypeList;
public MetaInfo(Config config) { this.config = config;
this.classList = new ArrayList<CppClass>(); this.typeSolver = new TypeSolver(this, this.config.classTraits);
this.templateInstanceList = new ArrayList<TemplateInstance>();
this.callbackClassMap = new OutputCallbackClassMap(this.config);
this.operatorNameMap = new OperatorNameMap();
this.stlParameterTypeList = new ArrayList<STLParameterType>(); }
|
ClassSourceFileWriter.java修改
import org.cpgf.metagen.metadata.STLParameterType;
protected void doWrite(CppWriter codeWriter) throws Exception { if(this.getConfig().sourceHeaderCode != null) { codeWriter.write(this.getConfig().sourceHeaderCode); codeWriter.writeLine(""); } ///< 转换include文件路径 if (this.getConfig().stripPath) { String fn = this.sourceFileName.substring(Math.max(this.sourceFileName.lastIndexOf('\\'), this.sourceFileName.lastIndexOf('/'))+1); String fileName = this.getConfig().stripIncPath.isEmpty() ? fn : this.getConfig().stripIncPath+"/"+ fn; codeWriter.include(WriterUtil.formatSourceIncludeHeader(this.getConfig(), fileName)); } else codeWriter.include(WriterUtil.formatSourceIncludeHeader(this.getConfig(), this.sourceFileName)); codeWriter.writeLine("");
codeWriter.include(this.getConfig().metaHeaderPath + this.targetFileName + ".h"); codeWriter.writeLine("");
codeWriter.useNamespace("cpgf"); codeWriter.writeLine("");
codeWriter.beginNamespace(this.getConfig().cppNamespace);
List<CppClass> sortedClassList = Util.sortClassList(this.masterClassList); for(CppClass cppClass : sortedClassList) { MetaClassCode classCode = this.getClassCode(cppClass); if(classCode.sourceCode.length() > 0) { codeWriter.write(classCode.sourceCode);
codeWriter.writeLine(""); codeWriter.writeLine(""); } }
codeWriter.endNamespace(this.getConfig().cppNamespace); }
|
MainHeaderFileWriter.java修改
import org.cpgf.metagen.metadata.MetaInfo; import org.cpgf.metagen.metadata.STLCategory; import org.cpgf.metagen.metadata.STLParameterType;
public MainHeaderFileWriter(Config config, MetaInfo metaInfo,List<String> creationFunctionNames) { super(config, metaInfo, null);
this.creationFunctionNames = creationFunctionNames; }
protected void doWrite(CppWriter codeWriter) throws Exception { codeWriter.beginIncludeGuard(Util.normalizeSymbol(this.getOutputFileName()));
codeWriter.include("cpgf/gmetadefine.h");
codeWriter.writeLine(""); codeWriter.writeLine("");
codeWriter.useNamespace("cpgf"); codeWriter.writeLine("");
codeWriter.beginNamespace(this.getConfig().cppNamespace);
for (STLParameterType stlParameterType : this.getMetaInfo().stlParameterTypeList) { String funcName = "createMetaClass_"+stlParameterType.name + "_Vector"; codeWriter.writeLine("GDefineMetaInfo " + funcName + "();"); } List<String> sortedCreateFunctionNames = Util.sortStringList(creationFunctionNames); for(String funcName : sortedCreateFunctionNames) { codeWriter.writeLine("GDefineMetaInfo " + funcName + "();"); }
codeWriter.writeLine(""); codeWriter.writeLine("");
codeWriter.writeLine("template <typename Meta>"); codeWriter.writeLine("void " + this.getMainFunctionName() + "(Meta _d)");
codeWriter.beginBlock();
for (STLParameterType stlParameterType : this.getMetaInfo().stlParameterTypeList) { String funcName = "createMetaClass_"+stlParameterType.name + "_Vector"; codeWriter.writeLine("_d._class(" + funcName + "());"); }
for(String funcName : sortedCreateFunctionNames) { codeWriter.writeLine("_d._class(" + funcName + "());"); }
codeWriter.endBlock();
codeWriter.writeLine("");
codeWriter.endNamespace(this.getConfig().cppNamespace);
codeWriter.endIncludeGuard(); } |
MainSourceFileWriter.java修改
import java.util.HashMap; import java.util.Map;
import org.cpgf.metagen.metadata.MetaInfo; import org.cpgf.metagen.metadata.STLParameterType;
public MainSourceFileWriter(Config config,MetaInfo metaInfo) { super(config, metaInfo, null); }
protected void doWrite(CppWriter codeWriter) throws Exception { codeWriter.include(this.getConfig().metaHeaderPath + this.getConfig().mainSourceFile + ".h"); codeWriter.include("cpgf/gmetadefine.h"); codeWriter.include("cpgf/goutmain.h");
Map<String,Integer> stlParameterFiles = new HashMap<String,Integer>(); for (STLParameterType stlParameterType : this.getMetaInfo().stlParameterTypeList) { stlParameterFiles.put(stlParameterType.cppClass.getLocation(),0); } for (String sourceFileName : stlParameterFiles.keySet()) { if (this.getConfig().stripPath) { String fn = sourceFileName.substring(Math.max(sourceFileName.lastIndexOf('\\'), sourceFileName.lastIndexOf('/'))+1); String fileName = this.getConfig().stripIncPath.isEmpty() ? fn : this.getConfig().stripIncPath+"/"+ fn; codeWriter.include(WriterUtil.formatSourceIncludeHeader(this.getConfig(), fileName)); } else codeWriter.include(WriterUtil.formatSourceIncludeHeader(this.getConfig(), sourceFileName)); } codeWriter.include("cpgf/metadata/stl/gmetadata_vector.h");
codeWriter.writeLine(""); codeWriter.writeLine("");
codeWriter.useNamespace("cpgf"); codeWriter.writeLine(""); for (STLParameterType stlParameterType : this.getMetaInfo().stlParameterTypeList) { String funcName = "createMetaClass_"+stlParameterType.name + "_Vector"; codeWriter.writeLine("GDefineMetaInfo " + funcName + "()");
codeWriter.beginBlock(); codeWriter.useNamespace(stlParameterType.getNameSpace()); codeWriter.writeLine("GDefineMetaGlobalDangle _d = GDefineMetaGlobalDangle::dangle();"); codeWriter.writeLine("GDefineMetaClass<std::vector<"+stlParameterType.name+"> > define = " + "GDefineMetaClass<std::vector<"+stlParameterType.name+"> >::declare(\""+stlParameterType.name+"_Vector\");");
codeWriter.writeLine("buildMetaData_vector(0,define,GMetaPolicyDefault());");
codeWriter.writeLine("_d._class(define);");
codeWriter.writeLine("return _d.getMetaInfo();");
codeWriter.endBlock(); }
codeWriter.beginNamespace(this.getConfig().cppNamespace);
codeWriter.beginNamespace("");
codeWriter.writeLine("G_AUTO_RUN_BEFORE_MAIN()");
codeWriter.beginBlock();
CppClass global = new CppClass(null); WriterUtil.defineMetaClass(this.getConfig(), codeWriter, global, "_d", "define");
codeWriter.writeLine(this.getMainFunctionName() + "(_d);");
codeWriter.endBlock(); codeWriter.writeLine("");
codeWriter.endNamespace("");
codeWriter.endNamespace(this.getConfig().cppNamespace); } |
MetaWriter.java修改
private void buildMainFileWriterList() { List<String> creationFunctionNames = new ArrayList<String>();
for(CodeFileWriter fileWriter : this.fileWriterList) { fileWriter.getCreationFunctionNames(creationFunctionNames); }
this.fileWriterList.add(new MainHeaderFileWriter(this.config, this.metaInfo,creationFunctionNames)); this.fileWriterList.add(new MainSourceFileWriter(this.config,this.metaInfo)); } |