forked from fanruan/design
Browse Source
Merge in DESIGN/design from ~HOKY.HE/design-hoky:feature/x to feature/x * commit '105d7308ecbd76798bdaf4c5de8f67b6ff39b55f': REPORT-60163 公式编辑器优化2.0 1.修改了国际化的位置 REPORT-60163 公式编辑器优化2.0 1.修改一下键入值 REPORT-60163 公式编辑器优化2.0 1.添加了输入提示; 2.优化了搜索框; 3.优化了出错提示以及添加了关闭前检测。feature/x
Hoky.He
3 years ago
18 changed files with 3120 additions and 170 deletions
@ -1,91 +1,43 @@ |
|||||||
package com.fr.design.formula; |
package com.fr.design.formula; |
||||||
|
|
||||||
|
import com.fr.design.formula.exception.FormulaExceptionTipsProcessor; |
||||||
import com.fr.design.i18n.Toolkit; |
import com.fr.design.i18n.Toolkit; |
||||||
import com.fr.log.FineLoggerFactory; |
|
||||||
import com.fr.parser.FRLexer; |
import com.fr.parser.FRLexer; |
||||||
import com.fr.parser.FRParser; |
import com.fr.parser.FRParser; |
||||||
import com.fr.script.checker.FunctionCheckerDispatcher; |
import com.fr.script.checker.FunctionCheckerDispatcher; |
||||||
import com.fr.script.checker.exception.ConditionCheckWrongException; |
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
import com.fr.script.checker.exception.FunctionCheckWrongException; |
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
import com.fr.script.rules.FunctionParameterType; |
|
||||||
import com.fr.script.rules.FunctionRule; |
|
||||||
import com.fr.stable.StringUtils; |
|
||||||
import com.fr.stable.script.Expression; |
import com.fr.stable.script.Expression; |
||||||
import com.fr.stable.script.Node; |
import com.fr.stable.script.Node; |
||||||
|
import com.fr.third.antlr.TokenStreamRecognitionException; |
||||||
|
|
||||||
import java.io.StringReader; |
import java.io.StringReader; |
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
/** |
||||||
* @author Hoky |
* @author Hoky |
||||||
* @date 2021/9/28 |
* @date 2021/9/28 |
||||||
*/ |
*/ |
||||||
public class FormulaChecker { |
public class FormulaChecker { |
||||||
private static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); |
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); |
||||||
private static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); |
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); |
||||||
public static final String COLON = ":"; |
private static FormulaExceptionTipsProcessor processor = FormulaExceptionTipsProcessor.getProcessor(); |
||||||
|
|
||||||
public static String check(String formulaText) throws FormulaCheckerException { |
public static FormulaCheckResult check(String formulaText) { |
||||||
|
//过滤一些空格等符号
|
||||||
StringReader in = new StringReader(formulaText); |
StringReader in = new StringReader(formulaText); |
||||||
|
|
||||||
FRLexer lexer = new FRLexer(in); |
FRLexer lexer = new FRLexer(in); |
||||||
FRParser parser = new FRParser(lexer); |
FRParser parser = new FRParser(lexer); |
||||||
|
|
||||||
try { |
try { |
||||||
Expression expression = parser.parse(); |
Expression expression = parser.parse(); |
||||||
Node node = expression.getConditionalExpression(); |
Node node = expression.getConditionalExpression(); |
||||||
boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(node); |
boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(formulaText, node); |
||||||
if (valid) { |
return new FormulaCheckResult(valid, valid ? VALID_FORMULA : INVALID_FORMULA, FormulaCoordinates.INVALID); |
||||||
return VALID_FORMULA; |
|
||||||
} else { |
|
||||||
throw new FormulaCheckerException(INVALID_FORMULA); |
|
||||||
} |
|
||||||
} catch (ConditionCheckWrongException cce) { |
|
||||||
String functionName = cce.getFunctionName(); |
|
||||||
throw new FormulaCheckerException(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + COLON); |
|
||||||
} catch (FunctionCheckWrongException ce) { |
|
||||||
List<FunctionRule> rules = ce.getRules(); |
|
||||||
String functionName = ce.getFunctionName(); |
|
||||||
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + COLON); |
|
||||||
for (int i = 0; i < rules.size(); i++) { |
|
||||||
errorMsg.append("("); |
|
||||||
if (rules.get(i).getParameterList().isEmpty()) { |
|
||||||
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); |
|
||||||
} |
|
||||||
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { |
|
||||||
errorMsg.append(getTypeString(functionParameterType)).append(","); |
|
||||||
} |
|
||||||
if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) { |
|
||||||
errorMsg.deleteCharAt(errorMsg.length() - 1); |
|
||||||
} |
|
||||||
errorMsg.append(")"); |
|
||||||
if (i != rules.size() - 1) { |
|
||||||
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); |
|
||||||
} |
|
||||||
} |
|
||||||
throw new FormulaCheckerException(errorMsg.toString()); |
|
||||||
} catch (Exception e) { |
} catch (Exception e) { |
||||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
if (e instanceof TokenStreamRecognitionException) { |
||||||
throw new FormulaCheckerException(INVALID_FORMULA); |
return processor.getExceptionTips(((TokenStreamRecognitionException) e).recog); |
||||||
// alex:继续往下面走,expression为null时告知不合法公式
|
} |
||||||
} |
return processor.getExceptionTips(e); |
||||||
} |
|
||||||
|
|
||||||
private static String getTypeString(FunctionParameterType type) { |
|
||||||
switch (type) { |
|
||||||
case NUMBER: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); |
|
||||||
case STRING: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); |
|
||||||
case ANY: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); |
|
||||||
case DATE: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); |
|
||||||
case BOOLEAN: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); |
|
||||||
case ARRAY: |
|
||||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); |
|
||||||
} |
} |
||||||
return StringUtils.EMPTY; |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,48 @@ |
|||||||
|
package com.fr.design.formula.exception; |
||||||
|
|
||||||
|
import com.fr.design.formula.FormulaChecker; |
||||||
|
import com.fr.design.formula.exception.function.FormulaCheckWrongFunction; |
||||||
|
import com.fr.design.formula.exception.function.MismatchedCharFunction; |
||||||
|
import com.fr.design.formula.exception.function.MismatchedTokenFunction; |
||||||
|
import com.fr.design.formula.exception.function.NoViableAltForCharFunction; |
||||||
|
import com.fr.design.formula.exception.function.NoViableAltFunction; |
||||||
|
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.third.antlr.MismatchedCharException; |
||||||
|
import com.fr.third.antlr.MismatchedTokenException; |
||||||
|
import com.fr.third.antlr.NoViableAltException; |
||||||
|
import com.fr.third.antlr.NoViableAltForCharException; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/26 |
||||||
|
*/ |
||||||
|
public class FormulaExceptionTipsProcessor { |
||||||
|
private static final Map<Class, Function<Exception, FormulaCheckResult>> EXCEPTION_TIPS = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
private static final FormulaExceptionTipsProcessor PROCESSOR = new FormulaExceptionTipsProcessor(); |
||||||
|
|
||||||
|
static { |
||||||
|
EXCEPTION_TIPS.put(FunctionCheckWrongException.class, FormulaCheckWrongFunction.getFunction()); |
||||||
|
EXCEPTION_TIPS.put(MismatchedCharException.class, MismatchedCharFunction.getFunction()); |
||||||
|
EXCEPTION_TIPS.put(MismatchedTokenException.class, MismatchedTokenFunction.getFunction()); |
||||||
|
EXCEPTION_TIPS.put(NoViableAltException.class, NoViableAltFunction.getFunction()); |
||||||
|
EXCEPTION_TIPS.put(NoViableAltForCharException.class, NoViableAltForCharFunction.getFunction()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public FormulaCheckResult getExceptionTips(Exception e) { |
||||||
|
return EXCEPTION_TIPS.getOrDefault(e.getClass(), |
||||||
|
e1 -> new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID)) |
||||||
|
.apply(e); |
||||||
|
} |
||||||
|
|
||||||
|
public static FormulaExceptionTipsProcessor getProcessor() { |
||||||
|
return PROCESSOR; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/28 |
||||||
|
*/ |
||||||
|
public class FormulaCheckConstants { |
||||||
|
public static final String COLON = ":"; |
||||||
|
public static final String LEFT = "("; |
||||||
|
public static final String COMMON = ","; |
||||||
|
public static final String RIGHT = ")"; |
||||||
|
public static final String BLANK = " "; |
||||||
|
public static final String SINGLE_QUOTES = "'"; |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.script.rules.FunctionParameterType; |
||||||
|
import com.fr.script.rules.FunctionRule; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/26 |
||||||
|
*/ |
||||||
|
public class FormulaCheckWrongFunction implements Function<Exception, FormulaCheckResult> { |
||||||
|
private final static FormulaCheckWrongFunction FUNCTION = new FormulaCheckWrongFunction(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaCheckResult apply(Exception e) { |
||||||
|
if (e instanceof FunctionCheckWrongException) { |
||||||
|
FunctionCheckWrongException ce = (FunctionCheckWrongException) e; |
||||||
|
List<FunctionRule> rules = ce.getRules(); |
||||||
|
String functionName = ce.getFunctionName(); |
||||||
|
StringBuilder errorMsg = new StringBuilder(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + FormulaCheckConstants.COLON); |
||||||
|
for (int i = 0; i < rules.size(); i++) { |
||||||
|
errorMsg.append(FormulaCheckConstants.LEFT); |
||||||
|
if (rules.get(i).getParameterList().isEmpty()) { |
||||||
|
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); |
||||||
|
} |
||||||
|
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { |
||||||
|
errorMsg.append(getTypeString(functionParameterType)).append(FormulaCheckConstants.COMMON); |
||||||
|
} |
||||||
|
if (FormulaCheckConstants.COMMON.equals(errorMsg.charAt(errorMsg.length() - 1) + StringUtils.EMPTY)) { |
||||||
|
errorMsg.deleteCharAt(errorMsg.length() - 1); |
||||||
|
} |
||||||
|
errorMsg.append(FormulaCheckConstants.RIGHT); |
||||||
|
if (i != rules.size() - 1) { |
||||||
|
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); |
||||||
|
} |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, errorMsg.toString(), new FormulaCoordinates(1, indexPosition(ce.getFormulaText(), ce.getNode().toString()))); |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, StringUtils.EMPTY, new FormulaCoordinates(-1, -1)); |
||||||
|
} |
||||||
|
|
||||||
|
private static String getTypeString(FunctionParameterType type) { |
||||||
|
switch (type) { |
||||||
|
case NUMBER: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); |
||||||
|
case STRING: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); |
||||||
|
case ANY: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); |
||||||
|
case DATE: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); |
||||||
|
case BOOLEAN: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); |
||||||
|
case ARRAY: |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); |
||||||
|
} |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||||
|
return FUNCTION; |
||||||
|
} |
||||||
|
|
||||||
|
private int indexPosition(String formulaText, String invalidFormula) { |
||||||
|
return formulaText.indexOf(invalidFormula); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
import com.fr.design.formula.FormulaChecker; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.third.antlr.MismatchedCharException; |
||||||
|
|
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/28 |
||||||
|
*/ |
||||||
|
public class MismatchedCharFunction implements Function<Exception, FormulaCheckResult> { |
||||||
|
private final static MismatchedCharFunction FUNCTION = new MismatchedCharFunction(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaCheckResult apply(Exception e) { |
||||||
|
if (e instanceof MismatchedCharException) { |
||||||
|
MismatchedCharException charException = (MismatchedCharException) e; |
||||||
|
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||||
|
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates); |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID); |
||||||
|
} |
||||||
|
|
||||||
|
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||||
|
return FUNCTION; |
||||||
|
} |
||||||
|
|
||||||
|
private String getMessage(MismatchedCharException charException) { |
||||||
|
StringBuffer sb = new StringBuffer(); |
||||||
|
switch (charException.mismatchType) { |
||||||
|
case 1: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": "); |
||||||
|
appendCharName(sb, charException.expecting); |
||||||
|
sb.append(FormulaCheckConstants.COMMON) |
||||||
|
.append(FormulaCheckConstants.BLANK) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")); |
||||||
|
appendCharName(sb, charException.foundChar); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||||
|
.append(FormulaCheckConstants.BLANK) |
||||||
|
.append(FormulaCheckConstants.SINGLE_QUOTES); |
||||||
|
appendCharName(sb, charException.expecting); |
||||||
|
sb.append("';").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
case 4: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")); |
||||||
|
if (charException.mismatchType == 4) { |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")); |
||||||
|
} |
||||||
|
|
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")).append(": "); |
||||||
|
appendCharName(sb, charException.expecting); |
||||||
|
sb.append(".."); |
||||||
|
appendCharName(sb, charException.upper); |
||||||
|
sb.append(", ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")); |
||||||
|
appendCharName(sb, charException.foundChar); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
case 6: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||||
|
.append(charException.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append(" ("); |
||||||
|
int[] elems = charException.set.toArray(); |
||||||
|
|
||||||
|
for (int i = 0; i < elems.length; ++i) { |
||||||
|
appendCharName(sb, elems[i]); |
||||||
|
} |
||||||
|
|
||||||
|
sb.append("), ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")); |
||||||
|
appendCharName(sb, charException.foundChar); |
||||||
|
break; |
||||||
|
default: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Char")); |
||||||
|
} |
||||||
|
|
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private void appendCharName(StringBuffer sb, int c) { |
||||||
|
switch (c) { |
||||||
|
case 9: |
||||||
|
sb.append("'\\t'"); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
sb.append("'\\n'"); |
||||||
|
break; |
||||||
|
case 13: |
||||||
|
sb.append("'\\r'"); |
||||||
|
break; |
||||||
|
case 65535: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF")); |
||||||
|
break; |
||||||
|
default: |
||||||
|
sb.append((char) c); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,140 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
import com.fr.design.formula.FormulaChecker; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.antlr.MismatchedTokenException; |
||||||
|
|
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/28 |
||||||
|
*/ |
||||||
|
public class MismatchedTokenFunction implements Function<Exception, FormulaCheckResult> { |
||||||
|
private final static MismatchedTokenFunction FUNCTION = new MismatchedTokenFunction(); |
||||||
|
public static final String NULL_STRING = "null"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaCheckResult apply(Exception e) { |
||||||
|
if (e instanceof MismatchedTokenException) { |
||||||
|
MismatchedTokenException charException = (MismatchedTokenException) e; |
||||||
|
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||||
|
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates); |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID); |
||||||
|
} |
||||||
|
|
||||||
|
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||||
|
return FUNCTION; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMessage(MismatchedTokenException exception) { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
Object fieldValue = getFieldValue(exception, "tokenText"); |
||||||
|
String tokenText = fieldValue == null ? NULL_STRING : fieldValue.toString(); |
||||||
|
switch (exception.mismatchType) { |
||||||
|
case 1: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||||
|
.append(tokenName(exception.expecting, exception)) |
||||||
|
.append(", ") |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")) |
||||||
|
.append(FormulaCheckConstants.BLANK + FormulaCheckConstants.SINGLE_QUOTES) |
||||||
|
.append(tokenText).append("'"); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||||
|
.append(tokenName(exception.expecting, exception)) |
||||||
|
.append("; ") |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||||
|
.append(": ") |
||||||
|
.append(tokenName(exception.expecting, exception)) |
||||||
|
.append("..") |
||||||
|
.append(tokenName(exception.upper, exception)) |
||||||
|
.append(", ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")) |
||||||
|
.append("'").append(tokenText).append("'"); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||||
|
.append(": ") |
||||||
|
.append(tokenName(exception.expecting, exception)) |
||||||
|
.append("..") |
||||||
|
.append(tokenName(exception.upper, exception)) |
||||||
|
.append(","). |
||||||
|
append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")) |
||||||
|
.append(" '") |
||||||
|
.append(tokenText) |
||||||
|
.append("'"); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
case 6: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||||
|
.append(exception.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append("("); |
||||||
|
int[] elms = exception.set.toArray(); |
||||||
|
|
||||||
|
for (int i = 0; i < elms.length; ++i) { |
||||||
|
sb.append(' '); |
||||||
|
sb.append(tokenName(elms[i], exception)); |
||||||
|
} |
||||||
|
|
||||||
|
sb.append("),") |
||||||
|
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Found")) |
||||||
|
.append("'") |
||||||
|
.append(tokenText) |
||||||
|
.append("'"); |
||||||
|
break; |
||||||
|
default: |
||||||
|
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Token")); |
||||||
|
} |
||||||
|
|
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private String tokenName(int tokenType, MismatchedTokenException exception) { |
||||||
|
if (tokenType == 0) { |
||||||
|
return "<Set of tokens>"; |
||||||
|
} else { |
||||||
|
String[] tokenNames = (String[]) getFieldValue(exception, "tokenNames"); |
||||||
|
return tokenType >= 0 && tokenType < tokenNames.length ? translateToken(tokenNames[tokenType]) : "<" + tokenType + ">"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String translateToken(String token) { |
||||||
|
switch (token) { |
||||||
|
case ("RPAREN"): |
||||||
|
return ")"; |
||||||
|
case ("LPAREN"): |
||||||
|
return "("; |
||||||
|
case ("COMMA"): |
||||||
|
return ","; |
||||||
|
case ("COLON"): |
||||||
|
return ":"; |
||||||
|
default: |
||||||
|
return token; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Object getFieldValue(Object object, String fieldName) { |
||||||
|
try { |
||||||
|
Field field = object.getClass().getDeclaredField(fieldName); |
||||||
|
field.setAccessible(true); |
||||||
|
return field.get(object); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().warn(e.getMessage(), e); |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
import com.fr.design.formula.FormulaChecker; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.third.antlr.NoViableAltForCharException; |
||||||
|
|
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/28 |
||||||
|
*/ |
||||||
|
public class NoViableAltForCharFunction implements Function<Exception, FormulaCheckResult> { |
||||||
|
private final static NoViableAltForCharFunction FUNCTION = new NoViableAltForCharFunction(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaCheckResult apply(Exception e) { |
||||||
|
if (e instanceof NoViableAltForCharException) { |
||||||
|
NoViableAltForCharException charException = (NoViableAltForCharException) e; |
||||||
|
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||||
|
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates); |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID); |
||||||
|
} |
||||||
|
|
||||||
|
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||||
|
return FUNCTION; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMessage(NoViableAltForCharException exception) { |
||||||
|
String mesg = Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Char") + ": "; |
||||||
|
if (exception.foundChar >= ' ' && exception.foundChar <= '~') { |
||||||
|
mesg = mesg + '\''; |
||||||
|
mesg = mesg + exception.foundChar; |
||||||
|
mesg = mesg + '\''; |
||||||
|
} else { |
||||||
|
mesg = mesg + exception.foundChar + "(0x" + Integer.toHexString(exception.foundChar).toUpperCase() + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
return mesg; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
package com.fr.design.formula.exception.function; |
||||||
|
|
||||||
|
import com.fr.design.formula.FormulaChecker; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.script.checker.result.FormulaCheckResult; |
||||||
|
import com.fr.script.checker.result.FormulaCoordinates; |
||||||
|
import com.fr.third.antlr.NoViableAltException; |
||||||
|
import com.fr.third.antlr.TreeParser; |
||||||
|
|
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/10/28 |
||||||
|
*/ |
||||||
|
public class NoViableAltFunction implements Function<Exception, FormulaCheckResult> { |
||||||
|
private final static NoViableAltFunction FUNCTION = new NoViableAltFunction(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public FormulaCheckResult apply(Exception e) { |
||||||
|
if (e instanceof NoViableAltException) { |
||||||
|
NoViableAltException altException = (NoViableAltException) e; |
||||||
|
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(altException.line, altException.column - 1); |
||||||
|
return new FormulaCheckResult(false, getMessage(altException), formulaCoordinates); |
||||||
|
} |
||||||
|
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID); |
||||||
|
} |
||||||
|
|
||||||
|
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||||
|
return FUNCTION; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMessage(NoViableAltException exception) { |
||||||
|
if (exception.token != null) { |
||||||
|
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Token") + ": " + exception.token.getText(); |
||||||
|
} else { |
||||||
|
return exception.node == TreeParser.ASTNULL ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_End_Of_Subtree") : |
||||||
|
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_AST_Node") + ": " + exception.node.toString(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@ |
|||||||
|
package com.fr.design.gui.autocomplete; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Hoky |
||||||
|
* @date 2021/11/5 |
||||||
|
*/ |
||||||
|
public class FormulaCompletion extends BasicCompletion { |
||||||
|
private Icon icon; |
||||||
|
|
||||||
|
public FormulaCompletion(CompletionProvider provider, String replacementText, Icon icon) { |
||||||
|
super(provider, replacementText); |
||||||
|
this.icon = icon; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Icon getIcon() { |
||||||
|
return icon; |
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 279 B |
After Width: | Height: | Size: 383 B |
Loading…
Reference in new issue