diff --git a/src/intellij_plugin/ohosgen/src/main/java/antlr/typescript/TypeScriptCustomListener.java b/src/intellij_plugin/ohosgen/src/main/java/antlr/typescript/TypeScriptCustomListener.java index 66b2f5b58dc888804c9095feaf5669d45f28e98a..2e9ba4867d362837766fa14bdf90d7d3361bbfdb 100644 --- a/src/intellij_plugin/ohosgen/src/main/java/antlr/typescript/TypeScriptCustomListener.java +++ b/src/intellij_plugin/ohosgen/src/main/java/antlr/typescript/TypeScriptCustomListener.java @@ -492,6 +492,9 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple System.out.println("enterCallSignature: " + ctx.getText()); if (this.currentToken.equals(TsToken.TS_TOKEN_CLASS) && (this.currentObject instanceof ClassObj co)) { + if (findFunction(co)) { + return; + } String typeName = ctx.typeAnnotation().stop.getText(); FuncObj fo = new FuncObj(); fo.setRetValue(typeName); @@ -565,8 +568,9 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple } TypeScriptParser.PropertyMemberDeclarationContext pmdc = ctx.propertyMemberDeclaration(); - if (pmdc != null) { + if (pmdc instanceof TypeScriptParser.GetterSetterDeclarationExpressionContext gsdec) { System.out.println("Class property: " + pmdc.getText()); + setFuncAccessor(gsdec); } } @@ -578,23 +582,39 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple System.out.println("Method name: " + propertyName); String callSign = ctx.callSignature().getText(); System.out.println("Method callSign: " + callSign); - String typeAnno = ctx.callSignature().typeAnnotation().getText(); + String typeAnno = ""; TypeScriptParser.TypeAnnotationContext tac = ctx.callSignature().typeAnnotation(); - typeAnno = tac.stop.getText(); + if (tac != null && tac.type_() != null) { + typeAnno = tac.type_().getText(); + } + System.out.println("Method typeAnno: " + typeAnno); TypeScriptParser.ParameterListContext plc = ctx.callSignature().parameterList(); FuncObj fo = new FuncObj(); - fo.setType(typeAnno); + fo.setRetValue(typeAnno); fo.setName(propertyName); + if (ctx.propertyMemberBase() != null && ctx.propertyMemberBase().Async() != null) { + fo.setType(ctx.propertyMemberBase().Async().getText()); + } + + if (ctx.propertyMemberBase() != null && ctx.propertyMemberBase().accessibilityModifier() != null) { + fo.setAccessor(ctx.propertyMemberBase().accessibilityModifier().getText()); + } if (plc != null) { List plcList = ctx.callSignature().parameterList().parameter(); for (TypeScriptParser.ParameterContext pc : plcList) { System.out.println("Method param: " + pc.getText()); TypeScriptParser. RequiredParameterContext rpc = pc.requiredParameter(); - String ta = rpc.typeAnnotation().getText(); - String iop = rpc.identifierOrPattern().getText(); + String ta = ""; + if (rpc.typeAnnotation() != null && rpc.typeAnnotation().type_() != null) { + ta = rpc.typeAnnotation().type_().getText(); + } + String iop = ""; + if (rpc.identifierOrPattern() != null) { + iop = rpc.identifierOrPattern().getText(); + } System.out.println("Method type: " + ta + " name: " + iop); fo.addParam(iop, ta); } @@ -644,10 +664,10 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple System.out.println("Property property: " + ctx.getText()); String propertyName = ctx.propertyName().getText(); String typeName = ctx.typeAnnotation().stop.getText(); + String qualifier = ctx.start.getText(); System.out.println("Property name: " + propertyName + " type: " + typeName); - if ((this.currentObject != null) && (this.currentObject instanceof ClassObj)) { - ClassObj co = (ClassObj) this.currentObject; - co.addParam(propertyName, typeName); + if (this.currentObject instanceof ClassObj co) { + co.addParam(propertyName, typeName, qualifier); int lastIndex = this.classObjList.size() - 1; this.classObjList.set(lastIndex, co); @@ -746,6 +766,9 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple public void enterClassHeritage(TypeScriptParser.ClassHeritageContext ctx) { super.enterClassHeritage(ctx); System.out.println("enterClassHeritage: " + ctx.getText()); + if (this.currentObject instanceof ClassObj co) { + co.addHeritage(ctx.start.getText(), ctx.stop.getText()); + } } @Override @@ -792,6 +815,10 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple io.setName(interfaceName); for (TypeScriptParser.TypeMemberContext tmc : tmcList) { + if (tmc.callSignature() == null) { + io.addParam(tmc.start.getText(), tmc.stop.getText()); + continue; + } String callSign = tmc.callSignature().getText(); System.out.println("interface callSign: " + callSign); String typeAnno = tmc.callSignature().typeAnnotation().stop.getText(); @@ -858,4 +885,65 @@ public class TypeScriptCustomListener extends TypeScriptParserBaseListener imple Gson gson = new GsonBuilder().setPrettyPrinting().create(); return gson.toJson(this); } + + private boolean findFunction(ClassObj coItem) { + List fol = coItem.getFuncList(); + for (FuncObj foItem : fol) { + String fName = foItem.getName(); + if (fName.equals(this.currentIdentifier)) { + return true; + } + } + return false; + } + + private void setFuncAccessor(TypeScriptParser.GetterSetterDeclarationExpressionContext gsdec) { + if (gsdec.getAccessor() != null && gsdec.getAccessor().getter() != null) { + String type = gsdec.getAccessor().getter().identifier().getText(); + String name = gsdec.getAccessor().getter().classElementName().getText(); + FuncObj fo = new FuncObj(); + fo.setName(name); + fo.setType(type); + if (this.currentObject instanceof ClassObj co) { + co.addFunc(fo); + } + } else if (gsdec.setAccessor() != null) { + String type = gsdec.setAccessor().setter().identifier().getText(); + String name = gsdec.setAccessor().setter().classElementName().getText(); + gsdec.setAccessor().setter(); + FuncObj fo = new FuncObj(); + fo.setName(name); + fo.setType(type); + TypeScriptParser.FormalParameterListContext fplc = gsdec.setAccessor().formalParameterList(); + + if (fplc == null || !(this.currentObject instanceof ClassObj co)) { + return; + } + + int cnt = fplc.getChildCount(); + for (int i = 0; i < cnt; i++) { + ParseTree pt = fplc.getChild(i); + if (!(pt instanceof TypeScriptParser.FormalParameterArgContext fpac)) { + continue; + } + + String fType = ""; + if (fpac.typeAnnotation() != null && fpac.typeAnnotation().stop != null) { + fType = fpac.typeAnnotation().stop.getText(); + } + + String fName = ""; + if (fpac.assignable() != null) { + fName = fpac.assignable().getText(); + } + + if (type.isEmpty()) { + fType = fName; + } + fo.addParam(fName, fType); + } + + co.addFunc(fo); + } + } } diff --git a/src/intellij_plugin/ohosgen/src/main/java/grammar/ClassObj.java b/src/intellij_plugin/ohosgen/src/main/java/grammar/ClassObj.java index c725e178bad74277a870db3821608aa4496c66ff..eccfcfcec8105da01ce48055a5d56e2e34e4ea01 100644 --- a/src/intellij_plugin/ohosgen/src/main/java/grammar/ClassObj.java +++ b/src/intellij_plugin/ohosgen/src/main/java/grammar/ClassObj.java @@ -34,6 +34,8 @@ public class ClassObj extends GBaseObject { private String alias; private List paramList; private List funcList; + private List heritageTypeList; + private List heritageNameList; /** * 构造函数 @@ -43,6 +45,8 @@ public class ClassObj extends GBaseObject { this.paramList = new CopyOnWriteArrayList<>(); this.funcList = new CopyOnWriteArrayList<>(); + this.heritageTypeList = new CopyOnWriteArrayList<>(); + this.heritageNameList = new CopyOnWriteArrayList<>(); } /** @@ -124,6 +128,42 @@ public class ClassObj extends GBaseObject { this.paramList = paramList; } + /** + * 继承名称 + * + * @param heritageNameList 继承名称 + */ + public void setHeritageNameList(List heritageNameList) { + this.heritageNameList = heritageNameList; + } + + /** + * 继承名字 + * + * @return 继承名称 + */ + public List getHeritageNameList() { + return heritageNameList; + } + + /** + * 设置继承类型 + * + * @param heritageTypeList 继承类型 + */ + public void setHeritageTypeList(List heritageTypeList) { + this.heritageTypeList = heritageTypeList; + } + + /** + * 获取继承类型 + * + * @return 继承类型 + */ + public List getHeritageTypeList() { + return heritageTypeList; + } + /** * 读取方法 * @@ -155,6 +195,21 @@ public class ClassObj extends GBaseObject { this.paramList.add(po); } + /** + * 增加param + * + * @param name 名字 + * @param type 类型 + * @param qualifier 声明 + */ + public void addParam(String name, String type, String qualifier) { + ParamObj po = new ParamObj(); + po.setType(type); + po.setName(name); + po.setQualifier(qualifier); + this.paramList.add(po); + } + /** * 增加方法 * @@ -177,4 +232,15 @@ public class ClassObj extends GBaseObject { fo.setRetValue(ret); fo.setParamList(poList); } + + /** + * 增加heritage 的类型和名称 + * + * @param type 类型如 extend,implement + * @param name 名称 + */ + public void addHeritage(String type, String name) { + heritageNameList.add(name); + heritageTypeList.add(type); + } } diff --git a/src/intellij_plugin/ohosgen/src/main/java/grammar/FuncObj.java b/src/intellij_plugin/ohosgen/src/main/java/grammar/FuncObj.java index b16e66feb92ceb91af91e4c17c188d02c9f78a58..e5af7f8adce0d6e7f1e2534d6cf01b342b0f4f0b 100644 --- a/src/intellij_plugin/ohosgen/src/main/java/grammar/FuncObj.java +++ b/src/intellij_plugin/ohosgen/src/main/java/grammar/FuncObj.java @@ -30,6 +30,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * @since 2025-02-28 */ public class FuncObj extends GBaseObject { + private String accessor; private String type; private String name; private String retValue; @@ -79,6 +80,24 @@ public class FuncObj extends GBaseObject { return type; } + /** + * 设置访问属性 + * + * @param accessor 访问属性 + */ + public void setAccessor(String accessor) { + this.accessor = accessor; + } + + /** + * 获取访问属性 + * + * @return 访问属性 + */ + public String getAccessor() { + return accessor; + } + /** * 设置名称 * diff --git a/src/intellij_plugin/ohosgen/src/test/java/parse/ParseTsTest.java b/src/intellij_plugin/ohosgen/src/test/java/parse/ParseTsTest.java index a8e7ac3f7bfca1125d8c7b80beb47b7406b045ad..74fd4b3f81d8151c7ce85447426d809f6674947f 100644 --- a/src/intellij_plugin/ohosgen/src/test/java/parse/ParseTsTest.java +++ b/src/intellij_plugin/ohosgen/src/test/java/parse/ParseTsTest.java @@ -74,6 +74,104 @@ class ParseTsTest { " abstract nameAbs: string;\n" + "}"; + String testClass5 = "class Employee extends Person {\n" + + " empCode: number;\n" + + "\n" + + " constructor(name: string, code: number) {\n" + + " super(name); // must call super()\n" + + " this.empCode = code;\n" + + " }\n" + + "\n" + + " find(name:string): Person {\n" + + " // execute AJAX request to find an employee from a db\n" + + " return new Employee(name, 1);\n" + + " }\n" + + "}"; + + String testInterface1 = "export interface CallbackTest {\n" + + "\t(msg: string): void;\n" + + "};"; + + String testInterface2 = "interface IPerson {\n" + + " name: string;\n" + + "}"; + + String testClass6 = "interface IPerson {\n" + + " name: string;\n" + + "}\n" + + "\n" + + "class Person implements IPerson {\n" + + " public publicString: string;\n" + + " private privateString: string;\n" + + " protected protectedString: string;\n" + + " readonly readonlyString: string;\n" + + " name: string;\n" + + "\n" + + " constructor(name: string) {\n" + + " this.name = name;\n" + + " }\n" + + "}"; + + String testClass7 = "interface IPerson {\n" + + " name: string;\n" + + "}\n" + + "\n" + + "class Person implements IPerson {\n" + + " public publicString: string;\n" + + " private privateString: string;\n" + + " protected protectedString: string;\n" + + " readonly readonlyString: string;\n" + + " name: string;\n" + + "\n" + + " constructor(name: string) {\n" + + " this.name = name;\n" + + " }\n" + + "}\n" + + "\n" + + "class Employee extends Person {\n" + + " empCode: number;\n" + + " currentUser: any;\n" + + " static pi: number = 3.14;\n" + + "\n" + + " constructor(empcode: number, name:string) {\n" + + " super(name);\n" + + " this.empCode = empcode;\n" + + " }\n" + + "\n" + + " get user() {\n" + + " return this.currentUser;\n" + + " }\n" + + "\n" + + " set user(usr: any) {\n" + + " this.currentUser = usr;\n" + + " }\n" + + "\n" + + " displayName():void {\n" + + " console.log(\"Name = \" + this.name + \", Employee Code = \" + this.empCode);\n" + + " }\n" + + "}"; + + String testClass8 = "export class myClass {\n" + + " public async foo( ): Promise {\n" + + " }\n" + + "}"; + + String testClass9 = "export class NotController {\n" + + " @Post()\n" + + " notControllerPost(body) {\n" + + " return 'This is not an api method';\n" + + " }\n" + + "}"; + + String testClass10 = "export default class CustomerModel {\n" + + " constructor(data) {\n" + + " this.cardAccountId = data.cardAccountId;\n" + + " this.accountHolderId = data.accountHolderId;\n" + + " this.firstName = data.firstName;\n" + + " this.lastName = data.lastName;\n" + + " }\n" + + "}"; + @Test void parseFile() { } @@ -299,6 +397,252 @@ class ParseTsTest { assertEquals("string", poItem.getType()); } + @Test + void parseCStreamClass_5() { + String testClass = testClass5; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(1, col.size()); + ClassObj coItem = col.get(0); + assertEquals("Employee", coItem.getName()); + List hnl = coItem.getHeritageNameList(); + assertEquals(1, hnl.size()); + assertEquals("Person", hnl.get(0)); + List htl = coItem.getHeritageTypeList(); + assertEquals(1, htl.size()); + assertEquals("extends", htl.get(0)); + List pol = coItem.getParamList(); + assertEquals(1, pol.size()); + ParamObj poItem = pol.get(0); + assertEquals("empCode", poItem.getName()); + assertEquals("number", poItem.getType()); + List fol = coItem.getFuncList(); + assertEquals(2, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("constructor", foItem.getName()); + assertEquals("void", foItem.getRetValue()); + pol = foItem.getParamList(); + assertEquals(2, pol.size()); + poItem = pol.get(0); + assertEquals("name", poItem.getName()); + assertEquals("string", poItem.getType()); + poItem = pol.get(1); + assertEquals("code", poItem.getName()); + assertEquals("number", poItem.getType()); + foItem = fol.get(1); + assertEquals("find", foItem.getName()); + assertEquals("Person", foItem.getRetValue()); + pol = foItem.getParamList(); + assertEquals(1, pol.size()); + poItem = pol.get(0); + assertEquals("name", poItem.getName()); + assertEquals("string", poItem.getType()); + } + + @Test + void parseCStreamClass_6() { + String testClass = testClass6; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(1, col.size()); + ClassObj coItem = col.get(0); + assertEquals("Person", coItem.getName()); + List htl = coItem.getHeritageTypeList(); + List hnl = coItem.getHeritageNameList(); + assertEquals("implements", htl.get(0)); + assertEquals("IPerson", hnl.get(0)); + List pol = coItem.getParamList(); + assertEquals(5, pol.size()); + ParamObj poItem = pol.get(0); + assertEquals("string", poItem.getType()); + assertEquals("publicString", poItem.getName()); + assertEquals("public", poItem.getQualifier()); + poItem = pol.get(1); + assertEquals("string", poItem.getType()); + assertEquals("privateString", poItem.getName()); + assertEquals("private", poItem.getQualifier()); + poItem = pol.get(2); + assertEquals("string", poItem.getType()); + assertEquals("protectedString", poItem.getName()); + assertEquals("protected", poItem.getQualifier()); + poItem = pol.get(3); + assertEquals("string", poItem.getType()); + assertEquals("readonlyString", poItem.getName()); + assertEquals("readonly", poItem.getQualifier()); + poItem = pol.get(4); + assertEquals("string", poItem.getType()); + assertEquals("name", poItem.getName()); + List fol = coItem.getFuncList(); + assertEquals(1, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("constructor", foItem.getName()); + assertEquals("void", foItem.getRetValue()); + pol = foItem.getParamList(); + assertEquals(1, pol.size()); + poItem = pol.get(0); + assertEquals("name", poItem.getName()); + assertEquals("string", poItem.getType()); + } + + @Test + void parseCStreamClass_7_1() { + String testClass = testClass7; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(2, col.size()); + ClassObj coItem = col.get(0); + assertEquals("Person", coItem.getName()); + List hnl = coItem.getHeritageNameList(); + assertEquals(1, hnl.size()); + assertEquals("IPerson", hnl.get(0)); + List htl = coItem.getHeritageTypeList(); + assertEquals(1, htl.size()); + assertEquals("implements", htl.get(0)); + List pol = coItem.getParamList(); + assertEquals(5, pol.size()); + ParamObj poItem = pol.get(0); + assertEquals("public", poItem.getQualifier()); + assertEquals("publicString", poItem.getName()); + assertEquals("string", poItem.getType()); + poItem = pol.get(1); + assertEquals("private", poItem.getQualifier()); + assertEquals("privateString", poItem.getName()); + assertEquals("string", poItem.getType()); + poItem = pol.get(2); + assertEquals("protected", poItem.getQualifier()); + assertEquals("protectedString", poItem.getName()); + assertEquals("string", poItem.getType()); + poItem = pol.get(3); + assertEquals("readonly", poItem.getQualifier()); + assertEquals("readonlyString", poItem.getName()); + assertEquals("string", poItem.getType()); + poItem = pol.get(4); + assertEquals("name", poItem.getName()); + assertEquals("string", poItem.getType()); + List fol = coItem.getFuncList(); + assertEquals(1, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("constructor", foItem.getName()); + assertEquals("void", foItem.getRetValue()); + } + + @Test + void parseCStreamClass_7_2() { + CodePointCharStream cStream = CharStreams.fromString(testClass7); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(2, col.size()); + + ClassObj coItem = col.get(1); + assertEquals("Employee", coItem.getName()); + List hnl = coItem.getHeritageNameList(); + assertEquals(1, hnl.size()); + assertEquals("Person", hnl.get(0)); + List htl = coItem.getHeritageTypeList(); + assertEquals(1, htl.size()); + assertEquals("extends", htl.get(0)); + List pol = coItem.getParamList(); + assertEquals(3, pol.size()); + ParamObj poItem = pol.get(0); + assertEquals("empCode", poItem.getName()); + assertEquals("number", poItem.getType()); + assertEquals("currentUser", pol.get(1).getName()); + assertEquals("any", pol.get(1).getType()); + assertEquals("pi", pol.get(2).getName()); + assertEquals("number", pol.get(2).getType()); + assertEquals("static", pol.get(2).getQualifier()); + List fol = coItem.getFuncList(); + assertEquals(4, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("constructor", foItem.getName()); + pol = foItem.getParamList(); + assertEquals(2, pol.size()); + poItem = pol.get(0); + assertEquals("empcode", poItem.getName()); + assertEquals("number", poItem.getType()); + poItem = pol.get(1); + assertEquals("name", poItem.getName()); + assertEquals("string", poItem.getType()); + foItem = fol.get(1); + assertEquals("user", foItem.getName()); + assertEquals("get", foItem.getType()); + pol = foItem.getParamList(); + assertEquals(0, pol.size()); + foItem = fol.get(2); + assertEquals("user", foItem.getName()); + assertEquals("set", foItem.getType()); + pol = foItem.getParamList(); + assertEquals(1, pol.size()); + assertEquals("usr", pol.get(0).getName()); + assertEquals("any", pol.get(0).getType()); + assertEquals("displayName", fol.get(3).getName()); + assertEquals(0, fol.get(3).getParamList().size()); + } + + @Test + void parseCStreamClass_8() { + String testClass = testClass8; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(1, col.size()); + ClassObj coItem = col.get(0); + assertEquals("myClass", coItem.getName()); + List fol = coItem.getFuncList(); + assertEquals(1, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("foo", foItem.getName()); + assertEquals("Promise", foItem.getRetValue()); + assertEquals("async", foItem.getType()); + assertEquals("public", foItem.getAccessor()); + } + + @Test + void parseCStreamClass_9() { + String testClass = testClass9; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(1, col.size()); + ClassObj coItem = col.get(0); + assertEquals("NotController", coItem.getName()); + List fol = coItem.getFuncList(); + assertEquals(1, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("notControllerPost", foItem.getName()); + List pol = foItem.getParamList(); + assertEquals(1, pol.size()); + assertEquals("body", pol.get(0).getName()); + } + + @Test + void parseCStreamClass_10() { + String testClass = testClass10; + CodePointCharStream cStream = CharStreams.fromString(testClass); + ParseBase parser = ParseFactory.getParser("ts"); + ParseObj po = parser.parseCStream(cStream); + List col = po.getClassList(); + assertEquals(1, col.size()); + ClassObj coItem = col.get(0); + assertEquals("CustomerModel", coItem.getName()); + List fol = coItem.getFuncList(); + assertEquals(1, fol.size()); + FuncObj foItem = fol.get(0); + assertEquals("constructor", foItem.getName()); + List pol = foItem.getParamList(); + assertEquals(1, pol.size()); + assertEquals("data", pol.get(0).getName()); + } + @Test void parseCStreamFunc() { ParseBase parser = ParseFactory.getParser("ts"); @@ -329,9 +673,7 @@ class ParseTsTest { @Test void parseCStreamInterface() { ParseBase parser = ParseFactory.getParser("ts"); - String testInterface = "export interface CallbackTest {\n" + - "\t(msg: string): void;\n" + - "};"; + String testInterface = testInterface1; CodePointCharStream cStream = CharStreams.fromString(testInterface); ParseObj po = parser.parseCStream(cStream); List iol = po.getInterfaceList();