diff --git a/src/main/java/com/ql/util/express/ExpressRunner.java b/src/main/java/com/ql/util/express/ExpressRunner.java index 71119fbcc..368b07b3c 100644 --- a/src/main/java/com/ql/util/express/ExpressRunner.java +++ b/src/main/java/com/ql/util/express/ExpressRunner.java @@ -756,6 +756,18 @@ public String[] getOutVarNames(String express) throws Exception { return this.parseInstructionSet(express).getOutAttrNames(); } + /** + * 获取一个表达式需要的外部变量全属性名称列表 + * 例如:返回外部字段全名 a.b.c + * @param express + * @return + * @throws Exception + */ + public String[] getFullOutVarNames(String express) throws Exception { + return this.parseInstructionSet(express).getFullOutAttrNames(); + } + + public String[] getOutFunctionNames(String express) throws Exception { return this.parseInstructionSet(express).getOutFunctionNames(); } diff --git a/src/main/java/com/ql/util/express/InstructionSet.java b/src/main/java/com/ql/util/express/InstructionSet.java index 942b3c736..ed300df80 100644 --- a/src/main/java/com/ql/util/express/InstructionSet.java +++ b/src/main/java/com/ql/util/express/InstructionSet.java @@ -6,7 +6,6 @@ import java.util.Map; import java.util.TreeMap; -import com.ql.util.express.config.QLExpressTimer; import com.ql.util.express.exception.QLException; import com.ql.util.express.exception.QLTimeoutException; import com.ql.util.express.instruction.FunctionInstructionSet; @@ -17,6 +16,8 @@ import com.ql.util.express.instruction.detail.InstructionLoadAttr; import com.ql.util.express.instruction.detail.InstructionNewVirClass; import com.ql.util.express.instruction.detail.InstructionOperator; +import com.ql.util.express.instruction.op.OperatorBase; +import com.ql.util.express.instruction.op.OperatorField; import com.ql.util.express.instruction.opdata.OperateDataLocalVar; /** @@ -81,6 +82,54 @@ public String[] getVirClasses() { return result.keySet().toArray(new String[0]); } + public String[] getFullOutAttrNames() throws Exception { + Map result = new TreeMap<>(); + StringBuilder tempFullName = new StringBuilder(); + for (int i = 0; i < instructionList.length; i++) { + Instruction instruction = instructionList[i]; + // 代表找到属性值的起点位置 + if (instruction instanceof InstructionLoadAttr && !"null".equals(((InstructionLoadAttr)instruction).getAttrName())) { + tempFullName.append(((InstructionLoadAttr)instruction).getAttrName()); + // 判断后续相邻是否有字段属性 + for (int j = i + 1; j < instructionList.length; j++) { + Instruction fieldInstruction = instructionList[j]; + if (fieldInstruction instanceof InstructionOperator + && ((InstructionOperator) fieldInstruction).getOperator() instanceof OperatorField) { + OperatorBase operator = ((InstructionOperator) fieldInstruction).getOperator(); + tempFullName.append(".").append(((OperatorField)operator).getFiledName()); + } else { + result.put(tempFullName.toString(), null); + tempFullName.setLength(0); + i = j; + break; + } + } + } + } + + //剔除本地变量定义和别名定义 + for (int i = 0; i < instructionList.length; i++) { + Instruction instruction = instructionList[i]; + if (instruction instanceof InstructionOperator) { + String opName = ((InstructionOperator)instruction).getOperator().getName(); + //addOperator(op)中op.name有可能为空 + if (opName != null) { + if ("def".equalsIgnoreCase(opName) || "exportDef".equalsIgnoreCase(opName)) { + String varLocalName = (String)((InstructionConstData)instructionList[i - 1]).getOperateData() + .getObject(null); + result.remove(varLocalName); + } else if ("alias".equalsIgnoreCase(opName) || "exportAlias".equalsIgnoreCase(opName)) { + String varLocalName = (String)((InstructionConstData)instructionList[i - 2]).getOperateData() + .getObject(null); + result.remove(varLocalName); + } + } + } + } + return result.keySet().toArray(new String[0]); + + } + public String[] getOutAttrNames() throws Exception { Map result = new TreeMap<>(); for (Instruction instruction : instructionList) { diff --git a/src/main/java/com/ql/util/express/instruction/op/OperatorField.java b/src/main/java/com/ql/util/express/instruction/op/OperatorField.java index e481cc8f1..ee5bc93a7 100644 --- a/src/main/java/com/ql/util/express/instruction/op/OperatorField.java +++ b/src/main/java/com/ql/util/express/instruction/op/OperatorField.java @@ -18,6 +18,10 @@ public OperatorField(String fieldName) { this.filedName = fieldName; } + public String getFiledName() { + return this.filedName; + } + @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { OperateData operateData = list.get(0); diff --git a/src/test/java/com/ql/util/express/test/GetExpressAttrNamesTest.java b/src/test/java/com/ql/util/express/test/GetExpressAttrNamesTest.java index 720aab80d..4cac933d1 100644 --- a/src/test/java/com/ql/util/express/test/GetExpressAttrNamesTest.java +++ b/src/test/java/com/ql/util/express/test/GetExpressAttrNamesTest.java @@ -39,4 +39,43 @@ public void testABCD() throws Exception { Assert.assertEquals("获取外部属性错误", 1, names.length); Assert.assertTrue("获取外部属性错误", names[0].equalsIgnoreCase("a")); } + + @Test + public void testFullA() throws Exception { + String express = "if(a!=null) return a;"; + ExpressRunner runner = new ExpressRunner(true, true); + String[] names = runner.getFullOutVarNames(express); + runner.execute(express, new DefaultContext<>(), null, false, false); + for (String s : names) { + System.out.println("var : " + s); + } + Assert.assertEquals("获取外部属性错误", 1, names.length); + Assert.assertTrue("获取外部属性错误", names[0].equalsIgnoreCase("a")); + } + + @Test + public void testFullABCD() throws Exception { + String express = "if(a.b.c.d!=null) return a.b.c.d;"; + ExpressRunner runner = new ExpressRunner(true, true); + String[] names = runner.getFullOutVarNames(express); + // runner.execute(express, new DefaultContext<>(), null, false, false); + for (String s : names) { + System.out.println("var : " + s); + } + Assert.assertEquals("获取外部属性错误", 1, names.length); + Assert.assertTrue("获取外部属性错误", names[0].equalsIgnoreCase("a.b.c.d")); + } + + @Test + public void testFunctionFullABCD() throws Exception { + String express = "if(func(a.b.c.d)!=null) return a.b.c.d;"; + ExpressRunner runner = new ExpressRunner(true, true); + String[] names = runner.getFullOutVarNames(express); + // runner.execute(express, new DefaultContext<>(), null, false, false); + for (String s : names) { + System.out.println("var : " + s); + } + Assert.assertEquals("获取外部属性错误", 1, names.length); + Assert.assertTrue("获取外部属性错误", names[0].equalsIgnoreCase("a.b.c.d")); + } }