From 6329d9a8d5cf69cec80e3aefe0c74f9f3204c133 Mon Sep 17 00:00:00 2001 From: Arnaud Roques Date: Thu, 22 Feb 2024 19:32:38 +0100 Subject: [PATCH] refactor: prepare preprocessor error improvement (in progress) https://github.com/plantuml/plantuml/pull/1668 --- gradle.properties | 2 +- src/net/sourceforge/plantuml/BlockUml.java | 2 +- .../sourceforge/plantuml/preproc/Defines.java | 43 ++++++----- .../sourceforge/plantuml/preproc/Truth.java | 1 + .../plantuml/preproc2/PreprocessorUtils.java | 10 +-- src/net/sourceforge/plantuml/tim/Eater.java | 28 ++++---- .../plantuml/tim/EaterAffectation.java | 4 +- .../plantuml/tim/EaterAffectationDefine.java | 2 +- .../sourceforge/plantuml/tim/EaterAssert.java | 4 +- .../plantuml/tim/EaterDeclareProcedure.java | 5 +- .../tim/EaterDeclareReturnFunction.java | 5 +- .../plantuml/tim/EaterException.java | 10 +-- .../plantuml/tim/EaterFunctionCall.java | 8 +-- .../plantuml/tim/EaterInclude.java | 8 +-- .../plantuml/tim/EaterIncludesub.java | 8 +-- .../plantuml/tim/EaterLegacyDefine.java | 2 +- .../plantuml/tim/EaterLegacyDefineLong.java | 2 +- .../plantuml/tim/EaterStartsub.java | 6 +- .../sourceforge/plantuml/tim/EaterTheme.java | 14 ++-- .../plantuml/tim/FunctionsSet.java | 72 +++++++++---------- .../sourceforge/plantuml/tim/TContext.java | 54 +++++++------- .../plantuml/tim/TFunctionImpl.java | 4 +- src/net/sourceforge/plantuml/tim/TMemory.java | 4 +- .../plantuml/tim/TMemoryGlobal.java | 18 +++-- .../plantuml/tim/TMemoryLocal.java | 43 ++++++----- .../sourceforge/plantuml/tim/TimLoader.java | 4 +- .../plantuml/tim/VariableManager.java | 44 ++++++------ .../expression/ReversePolishInterpretor.java | 44 +++++------- .../plantuml/tim/expression/ShuntingYard.java | 6 +- .../plantuml/tim/expression/TokenStack.java | 23 +++--- .../tim/iterator/AbstractCodeIterator.java | 8 ++- .../plantuml/tim/iterator/CodeIterator.java | 4 +- .../tim/iterator/CodeIteratorAffectation.java | 7 +- .../tim/iterator/CodeIteratorForeach.java | 19 +++-- .../plantuml/tim/iterator/CodeIteratorIf.java | 21 +++--- .../tim/iterator/CodeIteratorImpl.java | 24 ++++--- .../tim/iterator/CodeIteratorSub.java | 18 ++--- .../tim/iterator/CodeIteratorWhile.java | 13 ++-- .../plantuml/tim/stdlib/CallUserFunction.java | 6 +- .../plantuml/tim/stdlib/Darken.java | 2 +- .../plantuml/tim/stdlib/DateFunction.java | 3 +- .../plantuml/tim/stdlib/GetAllStdlib.java | 3 +- .../plantuml/tim/stdlib/GetJsonKey.java | 5 +- .../plantuml/tim/stdlib/InvokeProcedure.java | 2 +- .../plantuml/tim/stdlib/IsDark.java | 2 +- .../plantuml/tim/stdlib/IsLight.java | 2 +- .../plantuml/tim/stdlib/Lighten.java | 2 +- .../plantuml/tim/stdlib/LoadJson.java | 5 +- .../plantuml/tim/stdlib/RandomFunction.java | 3 +- .../plantuml/tim/stdlib/ReverseColor.java | 2 +- .../tim/stdlib/ReverseHsluvColor.java | 2 +- .../plantuml/tim/stdlib/SetVariableValue.java | 2 +- .../sourceforge/plantuml/version/Version.java | 2 +- 53 files changed, 331 insertions(+), 306 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4336095e9..acb37ac5e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ # Warning, "version" should be the same in gradle.properties and Version.java # Any idea anyone how to magically synchronize those :-) ? -version = 1.2024.4beta2 +version = 1.2024.4beta3 org.gradle.workers.max = 3 \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index 9a4229bad..b5c6b76c7 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -143,7 +143,7 @@ public class BlockUml { this.data = new ArrayList<>(strings); } else { final TimLoader timLoader = new TimLoader(mode.getImportedFiles(), defines, charset, - (DefinitionsContainer) mode); + (DefinitionsContainer) mode, strings.get(0)); this.included.addAll(timLoader.load(strings)); this.data = timLoader.getResultList(); this.debug = timLoader.getDebug(); diff --git a/src/net/sourceforge/plantuml/preproc/Defines.java b/src/net/sourceforge/plantuml/preproc/Defines.java index ed1478741..14ec49a0e 100644 --- a/src/net/sourceforge/plantuml/preproc/Defines.java +++ b/src/net/sourceforge/plantuml/preproc/Defines.java @@ -55,6 +55,7 @@ import net.sourceforge.plantuml.file.AParentFolder; import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.security.SecurityProfile; import net.sourceforge.plantuml.security.SecurityUtils; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.TVariableScope; @@ -81,11 +82,11 @@ public class Defines implements Truth { return new Defines(); } - public void copyTo(TMemory memory) throws EaterException { + public void copyTo(TMemory memory, StringLocated location) throws EaterException { for (Entry ent : values.entrySet()) { final String name = ent.getKey(); final Define def = ent.getValue(); - memory.putVariable(name, def.asTVariable(), TVariableScope.GLOBAL); + memory.putVariable(name, def.asTVariable(), TVariableScope.GLOBAL, location); } } @@ -114,10 +115,10 @@ public class Defines implements Truth { final Defines result = createEmpty(); result.overrideFilename(file.getName()); result.environment.put("filedate", new Date(file.lastModified()).toString()); - if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) { + if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) result.environment.put("dirpath", file.getAbsoluteFile().getParentFile().getAbsolutePath().replace('\\', '/')); - } + return result; } @@ -126,10 +127,10 @@ public class Defines implements Truth { final Defines result = createEmpty(); result.overrideFilename(file.getName()); result.environment.put("filedate", new Date(file.lastModified()).toString()); - if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) { + if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) result.environment.put("dirpath", file.getAbsoluteFile().getParentFile().getAbsolutePath().replace('\\', '/')); - } + return result; } @@ -147,9 +148,9 @@ public class Defines implements Truth { private static String nameNoExtension(String name) { final int x = name.lastIndexOf('.'); - if (x == -1) { + if (x == -1) return name; - } + return name.substring(0, x); } @@ -169,11 +170,10 @@ public class Defines implements Truth { } public boolean isTrue(String name) { - for (String key : values.keySet()) { - if (key.equals(name) || key.startsWith(name + "(")) { + for (String key : values.keySet()) + if (key.equals(name) || key.startsWith(name + "(")) return true; - } - } + return false; } @@ -192,9 +192,9 @@ public class Defines implements Truth { } private String method1(String line) { - for (Define def : values.values()) { + for (Define def : values.values()) line = def.apply(line); - } + return line; } @@ -215,18 +215,17 @@ public class Defines implements Truth { private String method2(String line) { final Set words = words(line); - if (magic == null) { + if (magic == null) magic = getAll(); - } for (String w : words) { Collection tmp = magic.get(w); - if (tmp == null) { + if (tmp == null) continue; - } - for (Define def : tmp) { + + for (Define def : tmp) line = def.apply(line); - } + } return line; } @@ -236,9 +235,9 @@ public class Defines implements Truth { Pattern p = Pattern.compile(ID); Matcher m = p.matcher(line); final Set words = new HashSet<>(); - while (m.find()) { + while (m.find()) words.add(m.group(0)); - } + return words; } diff --git a/src/net/sourceforge/plantuml/preproc/Truth.java b/src/net/sourceforge/plantuml/preproc/Truth.java index 7a33da793..1ec283d02 100644 --- a/src/net/sourceforge/plantuml/preproc/Truth.java +++ b/src/net/sourceforge/plantuml/preproc/Truth.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.preproc; public interface Truth { + public boolean isTrue(String name); } diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java index ee238c99c..4ed855154 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java @@ -139,21 +139,21 @@ public class PreprocessorUtils { if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) return StartDiagramExtractReader.build(url, s, suf, charset); - return getReaderInclude(url, s.getLocation(), charset); + return getReaderInclude(url, s, charset); } catch (IOException e) { Logme.error(e); - throw EaterException.located("Cannot open URL " + e.getMessage()); + throw EaterException.located("Cannot open URL " + e.getMessage(), s); } } - public static ReadLine getReaderInclude(SURL url, LineLocation lineLocation, Charset charset) + public static ReadLine getReaderInclude(SURL url, StringLocated s, Charset charset) throws EaterException, UnsupportedEncodingException { final InputStream is = url.openStream(); if (is == null) - throw EaterException.located("Cannot open URL"); + throw EaterException.located("Cannot open URL", s); - return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), lineLocation); + return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); } } diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java index 193a62c5f..3ccc10440 100644 --- a/src/net/sourceforge/plantuml/tim/Eater.java +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -93,7 +93,7 @@ public abstract class Eater { final TokenStack tokenStack = new TokenStack(); addIntoTokenStack(tokenStack, false); if (tokenStack.size() == 0) - throw EaterException.located("Missing expression"); + throw EaterException.located("Missing expression", stringLocated); return tokenStack; } @@ -121,7 +121,7 @@ public abstract class Eater { final public String eatAndGetQuotedString() throws EaterException { final char separator = peekChar(); if (TLineType.isQuote(separator) == false) - throw EaterException.located("quote10"); + throw EaterException.located("quote10", stringLocated); checkAndEatChar(separator); final StringBuilder value = new StringBuilder(); @@ -142,7 +142,7 @@ public abstract class Eater { while (true) { char ch = peekChar(); if (ch == 0) - throw EaterException.located("until001"); + throw EaterException.located("until001", stringLocated); if (level == 0 && (ch == ',' || ch == ')')) return value.toString().trim(); @@ -190,7 +190,7 @@ public abstract class Eater { final protected String eatAndGetVarname() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) - throw EaterException.located("a002"); + throw EaterException.located("a002", stringLocated); addUpToLastLetterOrUnderscoreOrDigit(varname); return varname.toString(); @@ -199,7 +199,7 @@ public abstract class Eater { final protected String eatAndGetFunctionName() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) - throw EaterException.located("a003"); + throw EaterException.located("a003", stringLocated); addUpToLastLetterOrUnderscoreOrDigit(varname); return varname.toString(); @@ -249,7 +249,7 @@ public abstract class Eater { final protected void checkAndEatChar(char ch) throws EaterException { if (i >= stringLocated.length() || stringLocated.charAt(i) != ch) - throw EaterException.located("a001"); + throw EaterException.located("a001", stringLocated); i++; } @@ -299,7 +299,7 @@ public abstract class Eater { } final protected TFunctionImpl eatDeclareFunction(TContext context, TMemory memory, boolean unquoted, - LineLocation location, boolean allowNoParenthesis, TFunctionType type) + StringLocated location, boolean allowNoParenthesis, TFunctionType type) throws EaterException, EaterExceptionLocated { final List args = new ArrayList<>(); final String functionName = eatAndGetFunctionName(); @@ -308,7 +308,7 @@ public abstract class Eater { if (allowNoParenthesis) return new TFunctionImpl(functionName, args, unquoted, type); - throw EaterException.located("Missing opening parenthesis"); + throw EaterException.located("Missing opening parenthesis", stringLocated); } while (true) { skipSpaces(); @@ -320,7 +320,7 @@ public abstract class Eater { if (peekChar() == '=') { eatOneChar(); final TokenStack def = TokenStack.eatUntilCloseParenthesisOrComma(this); - def.guessFunctions(); + def.guessFunctions(location); defValue = def.getResult(getStringLocated(), context, memory); // System.err.println("result=" + defValue); } else { @@ -333,7 +333,7 @@ public abstract class Eater { checkAndEatChar(")"); break; } else { - throw EaterException.located("Error in function definition"); + throw EaterException.located("Error in function definition", stringLocated); } } skipSpaces(); @@ -341,25 +341,25 @@ public abstract class Eater { } final protected TFunctionImpl eatDeclareReturnFunctionWithOptionalReturn(TContext context, TMemory memory, - boolean unquoted, LineLocation location) throws EaterException, EaterExceptionLocated { + boolean unquoted, StringLocated location) throws EaterException, EaterExceptionLocated { final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, TFunctionType.RETURN_FUNCTION); if (peekChar() == 'r') { checkAndEatChar("return"); skipSpaces(); final String line = "!return " + eatAllToEnd(); - result.addBody(new StringLocated(line, location)); + result.addBody(new StringLocated(line, location.getLocation())); } else if (peekChar() == '!') { checkAndEatChar("!return"); skipSpaces(); final String line = "!return " + eatAllToEnd(); - result.addBody(new StringLocated(line, location)); + result.addBody(new StringLocated(line, location.getLocation())); } return result; } final protected TFunctionImpl eatDeclareProcedure(TContext context, TMemory memory, boolean unquoted, - LineLocation location) throws EaterException, EaterExceptionLocated { + StringLocated location) throws EaterException, EaterExceptionLocated { final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, TFunctionType.PROCEDURE); return result; diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectation.java b/src/net/sourceforge/plantuml/tim/EaterAffectation.java index 99d25e20f..726ef28f8 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAffectation.java +++ b/src/net/sourceforge/plantuml/tim/EaterAffectation.java @@ -53,7 +53,7 @@ public class EaterAffectation extends Eater { if (scope != null) { skipSpaces(); if (peekChar() == '?' || peekChar() == '=') { - // The variable itself is "local" or "glocal", which is not a good idea by the + // The variable itself is "local" or "global", which is not a good idea by the // way scope = null; } else @@ -72,7 +72,7 @@ public class EaterAffectation extends Eater { skipSpaces(); final TValue value = eatExpression(context, memory); - memory.putVariable(varname, value, scope); + memory.putVariable(varname, value, scope, getStringLocated()); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java index c6cb3fbd2..aa689aeab 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java +++ b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java @@ -56,7 +56,7 @@ public class EaterAffectationDefine extends Eater { // if (memory instanceof TMemoryLocal) { // memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly(); // } - memory.putVariable(varname, value, TVariableScope.GLOBAL); + memory.putVariable(varname, value, TVariableScope.GLOBAL, getStringLocated()); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterAssert.java b/src/net/sourceforge/plantuml/tim/EaterAssert.java index 1858579ee..e854c06ad 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAssert.java +++ b/src/net/sourceforge/plantuml/tim/EaterAssert.java @@ -55,9 +55,9 @@ public class EaterAssert extends Eater { if (ch == ':') { checkAndEatChar(':'); final TValue message = eatExpression(context, memory); - throw EaterException.located("Assertion error : " + message.toString()); + throw EaterException.located("Assertion error : " + message.toString(), getStringLocated()); } - throw EaterException.located("Assertion error"); + throw EaterException.located("Assertion error", getStringLocated()); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterDeclareProcedure.java b/src/net/sourceforge/plantuml/tim/EaterDeclareProcedure.java index 43dc732c3..9c155df18 100644 --- a/src/net/sourceforge/plantuml/tim/EaterDeclareProcedure.java +++ b/src/net/sourceforge/plantuml/tim/EaterDeclareProcedure.java @@ -35,17 +35,16 @@ package net.sourceforge.plantuml.tim; import net.sourceforge.plantuml.text.StringLocated; -import net.sourceforge.plantuml.utils.LineLocation; public class EaterDeclareProcedure extends Eater { private TFunctionImpl function; - private final LineLocation location; + private final StringLocated location; private boolean finalFlag; public EaterDeclareProcedure(StringLocated s) { super(s.getTrimmed()); - this.location = s.getLocation(); + this.location = s; } @Override diff --git a/src/net/sourceforge/plantuml/tim/EaterDeclareReturnFunction.java b/src/net/sourceforge/plantuml/tim/EaterDeclareReturnFunction.java index e02ad1e30..8c6415d1a 100644 --- a/src/net/sourceforge/plantuml/tim/EaterDeclareReturnFunction.java +++ b/src/net/sourceforge/plantuml/tim/EaterDeclareReturnFunction.java @@ -35,17 +35,16 @@ package net.sourceforge.plantuml.tim; import net.sourceforge.plantuml.text.StringLocated; -import net.sourceforge.plantuml.utils.LineLocation; public class EaterDeclareReturnFunction extends Eater { private TFunctionImpl function; - private final LineLocation location; + private final StringLocated location; private boolean finalFlag; public EaterDeclareReturnFunction(StringLocated s) { super(s.getTrimmed()); - this.location = s.getLocation(); + this.location = s; } @Override diff --git a/src/net/sourceforge/plantuml/tim/EaterException.java b/src/net/sourceforge/plantuml/tim/EaterException.java index 94cf2a604..ee3439e13 100644 --- a/src/net/sourceforge/plantuml/tim/EaterException.java +++ b/src/net/sourceforge/plantuml/tim/EaterException.java @@ -40,16 +40,16 @@ public class EaterException extends Exception { private final String message; - private EaterException(String message) { + private EaterException(String message, StringLocated location) { this.message = message; } - public static EaterException unlocated(String message) { - return new EaterException(message); + public static EaterException unlocated(String message, StringLocated location) { + return new EaterException(message, location); } - public static EaterException located(String message) { - return unlocated(message); + public static EaterException located(String message, StringLocated location) { + return unlocated(message, location); } public final String getMessage() { diff --git a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java index 1c116eab0..8e703fde8 100644 --- a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java +++ b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java @@ -100,12 +100,12 @@ public class EaterFunctionCall extends Eater { checkAndEatChar('='); skipSpaces(); final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace(); - tokens.guessFunctions(); + tokens.guessFunctions(getStringLocated()); final TValue result = tokens.getResult(getStringLocated(), context, memory); namedArguments.put(varname, result); } else { final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace(); - tokens.guessFunctions(); + tokens.guessFunctions(getStringLocated()); final TValue result = tokens.getResult(getStringLocated(), context, memory); values.add(result); } @@ -119,9 +119,9 @@ public class EaterFunctionCall extends Eater { break; } if (unquoted) { - throw EaterException.located("unquoted function/procedure cannot use expression."); + throw EaterException.located("unquoted function/procedure cannot use expression.", getStringLocated()); } - throw EaterException.located("call001"); + throw EaterException.located("call001", getStringLocated()); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterInclude.java b/src/net/sourceforge/plantuml/tim/EaterInclude.java index dd16097f9..5366d8a4a 100644 --- a/src/net/sourceforge/plantuml/tim/EaterInclude.java +++ b/src/net/sourceforge/plantuml/tim/EaterInclude.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.text.StringLocated; public class EaterInclude extends Eater { - private String location; + private String what; private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.DEFAULT; public EaterInclude(StringLocated s) { @@ -65,15 +65,15 @@ public class EaterInclude extends Eater { } } skipSpaces(); - this.location = context.applyFunctionsAndVariables(memory, + this.what = context.applyFunctionsAndVariables(memory, new StringLocated(this.eatAllToEnd(), getLineLocation())); // final TValue value = eatExpression(context, memory); // this.location = value.toString(); } - public final String getLocation() { - return location; + public final String getWhat() { + return what; } public final PreprocessorIncludeStrategy getPreprocessorIncludeStrategy() { diff --git a/src/net/sourceforge/plantuml/tim/EaterIncludesub.java b/src/net/sourceforge/plantuml/tim/EaterIncludesub.java index cfd9da7dc..bd93e2e1e 100644 --- a/src/net/sourceforge/plantuml/tim/EaterIncludesub.java +++ b/src/net/sourceforge/plantuml/tim/EaterIncludesub.java @@ -38,7 +38,7 @@ import net.sourceforge.plantuml.text.StringLocated; public class EaterIncludesub extends Eater { - private String location; + private String what; public EaterIncludesub(StringLocated s) { super(s); @@ -49,13 +49,13 @@ public class EaterIncludesub extends Eater { skipSpaces(); checkAndEatChar("!includesub"); skipSpaces(); - this.location = context.applyFunctionsAndVariables(memory, + this.what = context.applyFunctionsAndVariables(memory, new StringLocated(this.eatAllToEnd(), getLineLocation())); } - public final String getLocation() { - return location; + public final String getWhat() { + return what; } } diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java index bd82decbe..532470560 100644 --- a/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java @@ -49,7 +49,7 @@ public class EaterLegacyDefine extends Eater { skipSpaces(); checkAndEatChar("!define"); skipSpaces(); - function = eatDeclareFunction(context, memory, true, getLineLocation(), false, TFunctionType.LEGACY_DEFINE); + function = eatDeclareFunction(context, memory, true, getStringLocated(), false, TFunctionType.LEGACY_DEFINE); final String def = this.eatAllToEnd(); // function.setFunctionType(TFunctionType.LEGACY_DEFINE); function.setLegacyDefinition(def); diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java index 56a10e488..54a782553 100644 --- a/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java @@ -49,7 +49,7 @@ public class EaterLegacyDefineLong extends Eater { skipSpaces(); checkAndEatChar("!definelong"); skipSpaces(); - function = eatDeclareFunction(context, memory, true, getLineLocation(), true, TFunctionType.LEGACY_DEFINELONG); + function = eatDeclareFunction(context, memory, true, getStringLocated(), true, TFunctionType.LEGACY_DEFINELONG); // function.setFunctionType(TFunctionType.LEGACY_DEFINELONG); } diff --git a/src/net/sourceforge/plantuml/tim/EaterStartsub.java b/src/net/sourceforge/plantuml/tim/EaterStartsub.java index 44a1ba175..9bb1a02c9 100644 --- a/src/net/sourceforge/plantuml/tim/EaterStartsub.java +++ b/src/net/sourceforge/plantuml/tim/EaterStartsub.java @@ -50,9 +50,9 @@ public class EaterStartsub extends Eater { checkAndEatChar("!startsub"); skipSpaces(); this.subname = eatAllToEnd(); - if (this.subname.matches("\\w+") == false) { - throw EaterException.located("Bad sub name"); - } + if (this.subname.matches("\\w+") == false) + throw EaterException.located("Bad sub name", getStringLocated()); + } public final String getSubname() { diff --git a/src/net/sourceforge/plantuml/tim/EaterTheme.java b/src/net/sourceforge/plantuml/tim/EaterTheme.java index 09e292785..c43fdc33f 100644 --- a/src/net/sourceforge/plantuml/tim/EaterTheme.java +++ b/src/net/sourceforge/plantuml/tim/EaterTheme.java @@ -101,24 +101,24 @@ public class EaterTheme extends Eater { } catch (IOException e) { Logme.error(e); } - throw EaterException.located("Cannot load " + realName); + throw EaterException.located("Cannot load " + realName, getStringLocated()); } if (from.startsWith("<") && from.endsWith(">")) { final ReadLine reader = ThemeUtils.getReaderTheme(realName, from); if (reader == null) - throw EaterException.located("No such theme " + realName + " in " + from); + throw EaterException.located("No such theme " + realName + " in " + from, getStringLocated()); return reader; } else if (from.startsWith("http://") || from.startsWith("https://")) { final SURL url = SURL.create(ThemeUtils.getFullPath(from, realName)); if (url == null) - throw EaterException.located("Cannot open URL"); + throw EaterException.located("Cannot open URL", getStringLocated()); try { - return PreprocessorUtils.getReaderInclude(url, getLineLocation(), UTF_8); + return PreprocessorUtils.getReaderInclude(url, getStringLocated(), UTF_8); } catch (UnsupportedEncodingException e) { Logme.error(e); - throw EaterException.located("Cannot decode charset"); + throw EaterException.located("Cannot decode charset", getStringLocated()); } } @@ -126,12 +126,12 @@ public class EaterTheme extends Eater { final FileWithSuffix file = context.getFileWithSuffix(from, realName); final Reader tmp = file.getReader(UTF_8); if (tmp == null) - throw EaterException.located("No such theme " + realName); + throw EaterException.located("No such theme " + realName, getStringLocated()); return ReadLineReader.create(tmp, "theme " + realName); } catch (IOException e) { Logme.error(e); - throw EaterException.located("Cannot load " + realName); + throw EaterException.located("Cannot load " + realName, getStringLocated()); } } diff --git a/src/net/sourceforge/plantuml/tim/FunctionsSet.java b/src/net/sourceforge/plantuml/tim/FunctionsSet.java index ee9d21019..0f910fb66 100644 --- a/src/net/sourceforge/plantuml/tim/FunctionsSet.java +++ b/src/net/sourceforge/plantuml/tim/FunctionsSet.java @@ -51,16 +51,16 @@ public class FunctionsSet { public TFunction getFunctionSmart(TFunctionSignature searched) { final TFunction func = this.functions.get(searched); - if (func != null) { + if (func != null) return func; - } + for (TFunction candidate : this.functions.values()) { - if (candidate.getSignature().sameFunctionNameAs(searched) == false) { + if (candidate.getSignature().sameFunctionNameAs(searched) == false) continue; - } - if (candidate.canCover(searched.getNbArg(), searched.getNamedArguments())) { + + if (candidate.canCover(searched.getNbArg(), searched.getNamedArguments())) return candidate; - } + } return null; } @@ -82,9 +82,9 @@ public class FunctionsSet { } public void addFunction(TFunction func) { - if (func.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) { + if (func.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) ((TFunctionImpl) func).finalizeEnddefinelong(); - } + this.functions.put(func.getSignature(), func); this.functions3.add(func.getSignature().getFunctionName() + "("); } @@ -96,9 +96,9 @@ public class FunctionsSet { public void executeLegacyDefine(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { - if (this.pendingFunction != null) { - throw EaterException.located("already0048"); - } + if (this.pendingFunction != null) + throw EaterException.located("already0048", s); + final EaterLegacyDefine legacyDefine = new EaterLegacyDefine(s); legacyDefine.analyze(context, memory); final TFunction function = legacyDefine.getFunction(); @@ -108,9 +108,9 @@ public class FunctionsSet { public void executeLegacyDefineLong(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { - if (this.pendingFunction != null) { - throw EaterException.located("already0068"); - } + if (this.pendingFunction != null) + throw EaterException.located("already0068", s); + final EaterLegacyDefineLong legacyDefineLong = new EaterLegacyDefineLong(s); legacyDefineLong.analyze(context, memory); this.pendingFunction = legacyDefineLong.getFunction(); @@ -118,48 +118,48 @@ public class FunctionsSet { public void executeDeclareReturnFunction(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { - if (this.pendingFunction != null) { - throw EaterException.located("already0068"); - } + if (this.pendingFunction != null) + throw EaterException.located("already0068", s); + final EaterDeclareReturnFunction declareFunction = new EaterDeclareReturnFunction(s); declareFunction.analyze(context, memory); final boolean finalFlag = declareFunction.getFinalFlag(); final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature(); final TFunction previous = this.functions.get(declaredSignature); - if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) { - throw EaterException.located("This function is already defined"); - } - if (finalFlag) { + if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) + throw EaterException.located("This function is already defined", s); + + if (finalFlag) this.functionsFinal.add(declaredSignature); - } - if (declareFunction.getFunction().hasBody()) { + + if (declareFunction.getFunction().hasBody()) this.addFunction(declareFunction.getFunction()); - } else { + else this.pendingFunction = declareFunction.getFunction(); - } + } public void executeDeclareProcedure(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { - if (this.pendingFunction != null) { - throw EaterException.located("already0068"); - } + if (this.pendingFunction != null) + throw EaterException.located("already0068", s); + final EaterDeclareProcedure declareFunction = new EaterDeclareProcedure(s); declareFunction.analyze(context, memory); final boolean finalFlag = declareFunction.getFinalFlag(); final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature(); final TFunction previous = this.functions.get(declaredSignature); - if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) { - throw EaterException.located("This function is already defined"); - } - if (finalFlag) { + if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) + throw EaterException.located("This function is already defined", s); + + if (finalFlag) this.functionsFinal.add(declaredSignature); - } - if (declareFunction.getFunction().hasBody()) { + + if (declareFunction.getFunction().hasBody()) this.addFunction(declareFunction.getFunction()); - } else { + else this.pendingFunction = declareFunction.getFunction(); - } + } } diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 6a79011f4..547313c90 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -322,7 +322,7 @@ public class TContext { if (e instanceof EaterExceptionLocated) throw (EaterExceptionLocated) e; Logme.error(e); - throw EaterException.located("Fatal parsing error"); + throw EaterException.located("Fatal parsing error", s); } } @@ -382,7 +382,7 @@ public class TContext { } else if (s.getString().matches("^\\s+$")) { return null; } else { - throw EaterException.located("Compile Error " + ftype + " " + type); + throw EaterException.located("Compile Error " + ftype + " " + type, s); } } @@ -465,7 +465,7 @@ public class TContext { call.getNamedArguments().keySet()); final TFunction function = functionsSet.getFunctionSmart(signature); if (function == null) - throw EaterException.located("Function not found " + presentFunction); + throw EaterException.located("Function not found " + presentFunction, str); if (function.getFunctionType() == TFunctionType.PROCEDURE) { this.pendingAdd = result.toString(); @@ -488,8 +488,8 @@ public class TContext { call.getNamedArguments()); result.append(functionReturn.toString()); i += call.getCurrentPosition() - 1; - } else if (new VariableManager(this, memory, str.getLocation()).getVarnameAt(str.getString(), i) != null) { - i = new VariableManager(this, memory, str.getLocation()).replaceVariables(str.getString(), i, result); + } else if (new VariableManager(this, memory, str).getVarnameAt(str.getString(), i) != null) { + i = new VariableManager(this, memory, str).replaceVariables(str.getString(), i, result); } else { result.append(c); } @@ -512,18 +512,18 @@ public class TContext { _import.analyze(this, memory); try { - final SFile file = FileSystem.getInstance().getFile( - applyFunctionsAndVariables(memory, new StringLocated(_import.getWhat(), s.getLocation()))); + final SFile file = FileSystem.getInstance() + .getFile(applyFunctionsAndVariables(memory, new StringLocated(_import.getWhat(), s.getLocation()))); if (file.exists() && file.isDirectory() == false) { importedFiles.add(file); return; } } catch (IOException e) { Logme.error(e); - throw EaterException.located("Cannot import " + e.getMessage()); + throw EaterException.located("Cannot import " + e.getMessage(), s); } - throw EaterException.located("Cannot import"); + throw EaterException.located("Cannot import", s); } private void executeLog(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { @@ -543,12 +543,12 @@ public class TContext { try { final EaterIncludesub include = new EaterIncludesub(s.getTrimmed()); include.analyze(this, memory); - final String location = include.getLocation(); - final int idx = location.indexOf('!'); + final String what = include.getWhat(); + final int idx = what.indexOf('!'); Sub sub = null; if (idx != -1) { - final String filename = location.substring(0, idx); - final String blocname = location.substring(idx + 1); + final String filename = what.substring(0, idx); + final String blocname = what.substring(idx + 1); try { final FileWithSuffix f2 = importedFiles.getFile(filename, null); if (f2.fileOk()) { @@ -556,10 +556,10 @@ public class TContext { this.importedFiles = this.importedFiles.withCurrentDir(f2.getParentFile()); final Reader reader = f2.getReader(charset); if (reader == null) - throw EaterException.located("cannot include " + location); + throw EaterException.located("cannot include " + what, s); try { - ReadLine readerline = ReadLineReader.create(reader, location, s.getLocation()); + ReadLine readerline = ReadLineReader.create(reader, what, s.getLocation()); readerline = new UncommentReadLine(readerline); sub = Sub.fromFile(readerline, blocname, this, memory); } finally { @@ -568,14 +568,14 @@ public class TContext { } } catch (IOException e) { Logme.error(e); - throw EaterException.located("cannot include " + location); + throw EaterException.located("cannot include " + what, s); } } if (sub == null) - sub = subs.get(location); + sub = subs.get(what); if (sub == null) - throw EaterException.located("cannot include " + location); + throw EaterException.located("cannot include " + what, s); executeLinesInternal(memory, sub.lines(), null); } finally { @@ -604,7 +604,7 @@ public class TContext { } while (true); } catch (IOException e) { Logme.error(e); - throw EaterException.located("" + e); + throw EaterException.located("" + e, s); } finally { try { reader2.close(); @@ -619,7 +619,7 @@ public class TContext { eater.analyze(this, memory); final ReadLine reader = eater.getTheme(); if (reader == null) - throw EaterException.located("No such theme " + eater.getName()); + throw EaterException.located("No such theme " + eater.getName(), s); try { final List body = new ArrayList<>(); @@ -633,7 +633,7 @@ public class TContext { } while (true); } catch (IOException e) { Logme.error(e); - throw EaterException.located("Error reading theme " + e); + throw EaterException.located("Error reading theme " + e, s); } finally { try { reader.close(); @@ -646,7 +646,7 @@ public class TContext { private void executeInclude(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { final EaterInclude include = new EaterInclude(s.getTrimmed()); include.analyze(this, memory); - String location = include.getLocation(); + String location = include.getWhat(); final PreprocessorIncludeStrategy strategy = include.getPreprocessorIncludeStrategy(); final int idx = location.lastIndexOf('!'); String suf = null; @@ -661,7 +661,7 @@ public class TContext { if (location.startsWith("http://") || location.startsWith("https://")) { final SURL url = SURL.create(location); if (url == null) - throw EaterException.located("Cannot open URL"); + throw EaterException.located("Cannot open URL", s); reader = PreprocessorUtils.getReaderIncludeUrl(url, s, suf, charset); } else if (location.startsWith("<") && location.endsWith(">")) { @@ -677,14 +677,14 @@ public class TContext { return; if (strategy == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) - throw EaterException.located("This file has already been included"); + throw EaterException.located("This file has already been included", s); if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) { reader = StartDiagramExtractReader.build(f2, s, charset); } else { final Reader tmp = f2.getReader(charset); if (tmp == null) - throw EaterException.located("Cannot include file"); + throw EaterException.located("Cannot include file", s); reader = ReadLineReader.create(tmp, location, s.getLocation()); } @@ -713,7 +713,7 @@ public class TContext { } } catch (IOException e) { Logme.error(e); - throw EaterException.located("cannot include " + e); + throw EaterException.located("cannot include " + e, s); } finally { if (reader != null) { try { @@ -724,7 +724,7 @@ public class TContext { } } - throw EaterException.located("cannot include " + location); + throw EaterException.located("cannot include " + location, s); } public boolean isLegacyDefine(String functionName) { diff --git a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java index 4d1237feb..506dc465d 100644 --- a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java +++ b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java @@ -148,12 +148,12 @@ public class TFunctionImpl implements TFunction { return executeReturnLegacyDefine(location.getLocation(), context, memory, args); if (functionType != TFunctionType.RETURN_FUNCTION) - throw EaterException.unlocated("Illegal call here. Is there a return directive in your function?"); + throw EaterException.unlocated("Illegal call here. Is there a return directive in your function?", location); final TMemory copy = getNewMemory(memory, args, named); final TValue result = context.executeLines(copy, body, TFunctionType.RETURN_FUNCTION, true); if (result == null) - throw EaterException.unlocated("No return directive found in your function"); + throw EaterException.unlocated("No return directive found in your function", location); return result; } diff --git a/src/net/sourceforge/plantuml/tim/TMemory.java b/src/net/sourceforge/plantuml/tim/TMemory.java index a1f830e79..466b5951b 100644 --- a/src/net/sourceforge/plantuml/tim/TMemory.java +++ b/src/net/sourceforge/plantuml/tim/TMemory.java @@ -37,13 +37,15 @@ package net.sourceforge.plantuml.tim; import java.util.Map; import java.util.Set; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.expression.TValue; public interface TMemory { public TValue getVariable(String varname); - public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException; + public void putVariable(String varname, TValue value, TVariableScope scope, StringLocated location) + throws EaterException; public void removeVariable(String varname); diff --git a/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java index 9b10805a4..f5587df1b 100644 --- a/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java +++ b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java @@ -41,6 +41,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.expression.TValue; import net.sourceforge.plantuml.utils.Log; @@ -49,10 +50,12 @@ public class TMemoryGlobal extends ExecutionContexts implements TMemory { private final Map globalVariables = new HashMap(); private final TrieImpl variables = new TrieImpl(); + @Override public TValue getVariable(String varname) { return this.globalVariables.get(varname); } + @Override public void dumpDebug(String message) { Log.error("[MemGlobal] Start of memory_dump " + message); dumpMemoryInternal(); @@ -68,32 +71,39 @@ public class TMemoryGlobal extends ExecutionContexts implements TMemory { } } - public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException { + @Override + public void putVariable(String varname, TValue value, TVariableScope scope, StringLocated location) + throws EaterException { Log.info("[MemGlobal] Setting " + varname); - if (scope == TVariableScope.LOCAL) { - throw EaterException.unlocated("Cannot use local variable here"); - } + if (scope == TVariableScope.LOCAL) + throw EaterException.unlocated("Cannot use local variable here", location); + this.globalVariables.put(varname, value); this.variables.add(varname); } + @Override public void removeVariable(String varname) { this.globalVariables.remove(varname); this.variables.remove(varname); } + @Override public boolean isEmpty() { return globalVariables.isEmpty(); } + @Override public Set variablesNames() { return Collections.unmodifiableSet(globalVariables.keySet()); } + @Override public Trie variablesNames3() { return variables; } + @Override public TMemory forkFromGlobal(Map input) { return new TMemoryLocal(this, input); } diff --git a/src/net/sourceforge/plantuml/tim/TMemoryLocal.java b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java index 4d9b7da33..2603e1d0d 100644 --- a/src/net/sourceforge/plantuml/tim/TMemoryLocal.java +++ b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java @@ -40,6 +40,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.expression.TValue; import net.sourceforge.plantuml.utils.Log; @@ -76,19 +77,21 @@ public class TMemoryLocal extends ExecutionContexts implements TMemory { Log.error("[MemGlobal] End of memory_dump"); } - public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException { + @Override + public void putVariable(String varname, TValue value, TVariableScope scope, StringLocated location) + throws EaterException { if (scope == TVariableScope.GLOBAL) { - memoryGlobal.putVariable(varname, value, scope); + memoryGlobal.putVariable(varname, value, scope, location); return; } if (scope == TVariableScope.LOCAL || overridenVariables01.containsKey(varname)) { this.overridenVariables01.put(varname, value); - if (this.overridenVariables00 != null) { + if (this.overridenVariables00 != null) this.overridenVariables00.add(varname); - } + Log.info("[MemLocal/overrriden] Setting " + varname); } else if (memoryGlobal.getVariable(varname) != null) { - memoryGlobal.putVariable(varname, value, scope); + memoryGlobal.putVariable(varname, value, scope, location); } else { this.localVariables01.put(varname, value); this.localVariables00.add(varname); @@ -96,12 +99,13 @@ public class TMemoryLocal extends ExecutionContexts implements TMemory { } } + @Override public void removeVariable(String varname) { if (overridenVariables01.containsKey(varname)) { this.overridenVariables01.remove(varname); - if (this.overridenVariables00 != null) { + if (this.overridenVariables00 != null) this.overridenVariables00.remove(varname); - } + } else if (memoryGlobal.getVariable(varname) != null) { memoryGlobal.removeVariable(varname); } else { @@ -110,25 +114,27 @@ public class TMemoryLocal extends ExecutionContexts implements TMemory { } } + @Override public TValue getVariable(String varname) { TValue result = overridenVariables01.get(varname); - if (result != null) { + if (result != null) return result; - } + result = memoryGlobal.getVariable(varname); - if (result != null) { + if (result != null) return result; - } + result = localVariables01.get(varname); return result; } + @Override public Trie variablesNames3() { if (overridenVariables00 == null) { overridenVariables00 = new TrieImpl(); - for (String name : overridenVariables01.keySet()) { + for (String name : overridenVariables01.keySet()) overridenVariables00.add(name); - } + } return new Trie() { public void add(String s) { @@ -140,12 +146,12 @@ public class TMemoryLocal extends ExecutionContexts implements TMemory { final String s2 = overridenVariables00.getLonguestMatchStartingIn(s); final String s3 = localVariables00.getLonguestMatchStartingIn(s); - if (s1.length() >= s2.length() && s1.length() >= s3.length()) { + if (s1.length() >= s2.length() && s1.length() >= s3.length()) return s1; - } - if (s2.length() >= s3.length() && s2.length() >= s1.length()) { + + if (s2.length() >= s3.length() && s2.length() >= s1.length()) return s2; - } + return s3; } }; @@ -162,14 +168,17 @@ public class TMemoryLocal extends ExecutionContexts implements TMemory { // return result; } + @Override public boolean isEmpty() { return memoryGlobal.isEmpty() && localVariables01.isEmpty() && overridenVariables01.isEmpty(); } + @Override public Set variablesNames() { throw new UnsupportedOperationException(); } + @Override public TMemory forkFromGlobal(Map input) { return new TMemoryLocal(memoryGlobal, input); } diff --git a/src/net/sourceforge/plantuml/tim/TimLoader.java b/src/net/sourceforge/plantuml/tim/TimLoader.java index de15c55f9..7d8bd5c93 100644 --- a/src/net/sourceforge/plantuml/tim/TimLoader.java +++ b/src/net/sourceforge/plantuml/tim/TimLoader.java @@ -53,10 +53,10 @@ public class TimLoader { private List resultList; public TimLoader(ImportedFiles importedFiles, Defines defines, Charset charset, - DefinitionsContainer definitionsContainer) { + DefinitionsContainer definitionsContainer, StringLocated location) { this.context = new TContext(importedFiles, defines, charset, definitionsContainer); try { - defines.copyTo(global); + defines.copyTo(global, location); } catch (EaterException e) { Logme.error(e); } diff --git a/src/net/sourceforge/plantuml/tim/VariableManager.java b/src/net/sourceforge/plantuml/tim/VariableManager.java index 88332ac3d..1f9a66dc4 100644 --- a/src/net/sourceforge/plantuml/tim/VariableManager.java +++ b/src/net/sourceforge/plantuml/tim/VariableManager.java @@ -46,9 +46,9 @@ public class VariableManager { private final TMemory memory; private final TContext context; - private final LineLocation location; + private final StringLocated location; - public VariableManager(TContext context, TMemory memory, LineLocation location) { + public VariableManager(TContext context, TMemory memory, StringLocated location) { this.memory = memory; this.context = context; this.location = location; @@ -56,9 +56,9 @@ public class VariableManager { public int replaceVariables(String str, int i, StringBuilder result) throws EaterException, EaterExceptionLocated { final String presentVariable = getVarnameAt(str, i); - if (result.toString().endsWith("##")) { + if (result.toString().endsWith("##")) result.setLength(result.length() - 2); - } + final TValue value = memory.getVariable(presentVariable); i += presentVariable.length() - 1; if (value.isJson()) { @@ -75,9 +75,9 @@ public class VariableManager { } else { result.append(value.toString()); } - if (i + 2 < str.length() && str.charAt(i + 1) == '#' && str.charAt(i + 2) == '#') { + if (i + 2 < str.length() && str.charAt(i + 1) == '#' && str.charAt(i + 2) == '#') i += 2; - } + return i; } @@ -89,9 +89,9 @@ public class VariableManager { i++; final StringBuilder fieldName = new StringBuilder(); while (i < str.length()) { - if (Character.isJavaIdentifierPart(str.charAt(i)) == false) { + if (Character.isJavaIdentifierPart(str.charAt(i)) == false) break; - } + fieldName.append(str.charAt(i)); i++; } @@ -101,9 +101,9 @@ public class VariableManager { final StringBuilder inBracket = new StringBuilder(); int level = 0; while (true) { - if (str.charAt(i) == '[') { + if (str.charAt(i) == '[') level++; - } + if (str.charAt(i) == ']') { if (level == 0) break; @@ -113,29 +113,29 @@ public class VariableManager { i++; } final String nbString = context.applyFunctionsAndVariables(memory, - new StringLocated(inBracket.toString(), location)); + new StringLocated(inBracket.toString(), location.getLocation())); if (jsonValue instanceof JsonArray) { final int nb = Integer.parseInt(nbString); jsonValue = ((JsonArray) jsonValue).get(nb); } else if (jsonValue instanceof JsonObject) { jsonValue = ((JsonObject) jsonValue).get(nbString); } else { - throw EaterException.unlocated("Major parsing error"); - } - if (jsonValue == null) { - throw EaterException.unlocated("Data parsing error"); + throw EaterException.unlocated("Major parsing error", location); } + + if (jsonValue == null) + throw EaterException.unlocated("Data parsing error", location); + i++; } else { break; } } if (jsonValue != null) { - if (jsonValue.isString()) { + if (jsonValue.isString()) result.append(jsonValue.asString()); - } else { + else result.append(jsonValue.toString()); - } } return i; } @@ -146,13 +146,13 @@ public class VariableManager { return null; } final String varname = memory.variablesNames3().getLonguestMatchStartingIn(s.substring(pos)); - if (varname.length() == 0) { + if (varname.length() == 0) return null; - } + if (pos + varname.length() == s.length() - || TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos + varname.length())) == false) { + || TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos + varname.length())) == false) return varname; - } + return null; } diff --git a/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java index 4d19e7642..5ef785efd 100644 --- a/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java +++ b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java @@ -47,18 +47,12 @@ import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunction; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; -import net.sourceforge.plantuml.utils.LineLocation; public class ReversePolishInterpretor { private final TValue result; private final boolean trace = false; - public ReversePolishInterpretor(TokenStack queue, Knowledge knowledge, TMemory memory, TContext context) - throws EaterException, EaterExceptionLocated { - this(null, queue, knowledge, memory, context); - } - public ReversePolishInterpretor(StringLocated location, TokenStack queue, Knowledge knowledge, TMemory memory, TContext context) throws EaterException, EaterExceptionLocated { @@ -79,45 +73,45 @@ public class ReversePolishInterpretor { final TValue v2 = stack.removeFirst(); final TValue v1 = stack.removeFirst(); final TokenOperator op = token.getTokenOperator(); - if (op == null) { - throw EaterException.unlocated("bad op"); - } + if (op == null) + throw EaterException.unlocated("bad op", location); + final TValue tmp = op.operate(v1, v2); stack.addFirst(tmp); } else if (token.getTokenType() == TokenType.OPEN_PAREN_FUNC) { final int nb = Integer.parseInt(token.getSurface()); final Token token2 = it.nextToken(); - if (token2.getTokenType() != TokenType.FUNCTION_NAME) { - throw EaterException.unlocated("rpn43"); - } + if (token2.getTokenType() != TokenType.FUNCTION_NAME) + throw EaterException.unlocated("rpn43", location); + if (trace) System.err.println("token2=" + token2); final TFunction function = knowledge.getFunction(new TFunctionSignature(token2.getSurface(), nb)); if (trace) System.err.println("function=" + function); - if (function == null) { - throw EaterException.unlocated("Unknown built-in function " + token2.getSurface()); - } - if (function.canCover(nb, Collections.emptySet()) == false) { - throw EaterException - .unlocated("Bad number of arguments for " + function.getSignature().getFunctionName()); - } + if (function == null) + throw EaterException.unlocated("Unknown built-in function " + token2.getSurface(), location); + + if (function.canCover(nb, Collections.emptySet()) == false) + throw EaterException.unlocated( + "Bad number of arguments for " + function.getSignature().getFunctionName(), location); + final List args = new ArrayList<>(); - for (int i = 0; i < nb; i++) { + for (int i = 0; i < nb; i++) args.add(0, stack.removeFirst()); - } + if (trace) System.err.println("args=" + args); - if (location == null) { - throw EaterException.unlocated("rpn44"); - } + if (location == null) + throw EaterException.unlocated("rpn44", location); + final TValue r = function.executeReturnFunction(context, memory, location, args, Collections.emptyMap()); if (trace) System.err.println("r=" + r); stack.addFirst(r); } else { - throw EaterException.unlocated("rpn41"); + throw EaterException.unlocated("rpn41", location); } } result = stack.removeFirst(); diff --git a/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java index c6366f6bd..4b40aab8f 100644 --- a/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java +++ b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.tim.expression; import java.util.ArrayDeque; import java.util.Deque; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; @@ -58,7 +59,8 @@ public class ShuntingYard { System.err.println(""); } - public ShuntingYard(TokenIterator it, Knowledge knowledge) throws EaterException, EaterExceptionLocated { + public ShuntingYard(TokenIterator it, Knowledge knowledge, StringLocated location) + throws EaterException, EaterExceptionLocated { while (it.hasMoreTokens()) { final Token token = it.nextToken(); @@ -74,7 +76,7 @@ public class ShuntingYard { final TValue variable = knowledge.getVariable(name); if (variable == null) { if (isVariableName(name) == false) - throw EaterException.unlocated("Parsing syntax error about " + name); + throw EaterException.unlocated("Parsing syntax error about " + name, location); ouputQueue.add(new Token(name, TokenType.QUOTED_STRING, null)); } else { diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java index 61eeebae6..b25c96f6c 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java +++ b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java @@ -48,7 +48,6 @@ import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TMemory; -import net.sourceforge.plantuml.utils.LineLocation; public class TokenStack { @@ -96,7 +95,7 @@ public class TokenStack { eater.skipSpaces(); final char ch = eater.peekChar(); if (ch == 0) - throw EaterException.unlocated("until001"); + throw EaterException.unlocated("until001", eater.getStringLocated()); if (level == 0 && (ch == ',' || ch == ')')) return result; @@ -114,12 +113,12 @@ public class TokenStack { } } - static public void eatUntilCloseParenthesisOrComma(TokenIterator it) throws EaterException { + static public void eatUntilCloseParenthesisOrComma(TokenIterator it, StringLocated location) throws EaterException { int level = 0; while (true) { final Token ch = it.peekToken(); if (ch == null) - throw EaterException.unlocated("until002"); + throw EaterException.unlocated("until002", location); final TokenType typech = ch.getTokenType(); if (level == 0 && (typech == TokenType.COMMA || typech == TokenType.CLOSE_PAREN_MATH) @@ -136,7 +135,7 @@ public class TokenStack { } } - private int countFunctionArg(TokenIterator it) throws EaterException { + private int countFunctionArg(TokenIterator it, StringLocated location) throws EaterException { // return 42; final TokenType type1 = it.peekToken().getTokenType(); if (type1 == TokenType.CLOSE_PAREN_MATH || type1 == TokenType.CLOSE_PAREN_FUNC) @@ -144,7 +143,7 @@ public class TokenStack { int result = 1; while (it.hasMoreTokens()) { - eatUntilCloseParenthesisOrComma(it); + eatUntilCloseParenthesisOrComma(it, location); final Token token = it.nextToken(); final TokenType type = token.getTokenType(); if (type == TokenType.CLOSE_PAREN_MATH || type == TokenType.CLOSE_PAREN_FUNC) @@ -152,13 +151,13 @@ public class TokenStack { else if (type == TokenType.COMMA) result++; else - throw EaterException.unlocated("count13"); + throw EaterException.unlocated("count13", location); } - throw EaterException.unlocated("count12"); + throw EaterException.unlocated("count12", location); } - public void guessFunctions() throws EaterException { + public void guessFunctions(StringLocated location) throws EaterException { final Deque open = new ArrayDeque<>(); final Map parens = new HashMap(); for (int i = 0; i < tokens.size(); i++) { @@ -178,7 +177,7 @@ public class TokenStack { assert tokens.get(iclose).getTokenType() == TokenType.CLOSE_PAREN_MATH; if (iopen > 0 && tokens.get(iopen - 1).getTokenType() == TokenType.PLAIN_TEXT) { tokens.set(iopen - 1, new Token(tokens.get(iopen - 1).getSurface(), TokenType.FUNCTION_NAME, null)); - final int nbArg = countFunctionArg(subTokenStack(iopen + 1).tokenIterator()); + final int nbArg = countFunctionArg(subTokenStack(iopen + 1).tokenIterator(), location); tokens.set(iopen, new Token("" + nbArg, TokenType.OPEN_PAREN_FUNC, null)); tokens.set(iclose, new Token(")", TokenType.CLOSE_PAREN_FUNC, null)); } @@ -215,9 +214,9 @@ public class TokenStack { throws EaterException, EaterExceptionLocated { final Knowledge knowledge = context.asKnowledge(memory, location.getLocation()); final TokenStack tmp = withoutSpace(); - tmp.guessFunctions(); + tmp.guessFunctions(location); final TokenIterator it = tmp.tokenIterator(); - final ShuntingYard shuntingYard = new ShuntingYard(it, knowledge); + final ShuntingYard shuntingYard = new ShuntingYard(it, knowledge, location); final ReversePolishInterpretor rpn = new ReversePolishInterpretor(location, shuntingYard.getQueue(), knowledge, memory, context); return rpn.getResult(); diff --git a/src/net/sourceforge/plantuml/tim/iterator/AbstractCodeIterator.java b/src/net/sourceforge/plantuml/tim/iterator/AbstractCodeIterator.java index 83165b8ee..a4e9a62aa 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/AbstractCodeIterator.java +++ b/src/net/sourceforge/plantuml/tim/iterator/AbstractCodeIterator.java @@ -34,6 +34,7 @@ */ package net.sourceforge.plantuml.tim.iterator; +import net.sourceforge.plantuml.text.StringLocated; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; @@ -45,16 +46,19 @@ public abstract class AbstractCodeIterator implements CodeIterator { this.source = source; } + @Override public void next() throws EaterException, EaterExceptionLocated { source.next(); } + @Override final public CodePosition getCodePosition() { return source.getCodePosition(); } - final public void jumpToCodePosition(CodePosition newPosition) throws EaterException { - source.jumpToCodePosition(newPosition); + @Override + final public void jumpToCodePosition(CodePosition newPosition, StringLocated location) throws EaterException { + source.jumpToCodePosition(newPosition, location); } } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java index c0b59f04d..48698ab5c 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; public interface CodeIterator { - // ::remove folder when __HAXE__ + // ::remove folder when __HAXE__ public StringLocated peek() throws EaterException, EaterExceptionLocated; @@ -47,6 +47,6 @@ public interface CodeIterator { public CodePosition getCodePosition(); - public void jumpToCodePosition(CodePosition newPosition) throws EaterException; + public void jumpToCodePosition(CodePosition newPosition, StringLocated location) throws EaterException; } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java index e2a5fc5e9..0d380a436 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java @@ -58,6 +58,7 @@ public class CodeIteratorAffectation extends AbstractCodeIterator { this.logs = log; } + @Override public StringLocated peek() throws EaterException, EaterExceptionLocated { while (true) { final StringLocated result = source.peek(); @@ -81,9 +82,9 @@ public class CodeIteratorAffectation extends AbstractCodeIterator { this.executeAffectation(context, memory, result); return; } catch (ParseException e) { - if (e.getColumn() <= lastLocation) { - throw EaterException.located("Error in JSON format"); - } + if (e.getColumn() <= lastLocation) + throw EaterException.located("Error in JSON format", result); + lastLocation = e.getColumn(); next(); final StringLocated forward = source.peek(); diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java index 540b1e1be..87a783882 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java @@ -65,9 +65,8 @@ public class CodeIteratorForeach extends AbstractCodeIterator { int level = 0; while (true) { final StringLocated result = source.peek(); - if (result == null) { + if (result == null) return null; - } final ExecutionContextForeach foreach = memory.peekForeach(); if (foreach != null && foreach.isSkipMe()) { @@ -91,15 +90,15 @@ public class CodeIteratorForeach extends AbstractCodeIterator { continue; } else if (result.getType() == TLineType.ENDFOREACH) { logs.add(result); - if (foreach == null) { - throw EaterException.located("No foreach related to this endforeach"); - } + if (foreach == null) + throw EaterException.located("No foreach related to this endforeach", result); + foreach.inc(); if (foreach.isSkipMe()) { memory.pollForeach(); } else { setLoopVariable(memory, foreach, result); - source.jumpToCodePosition(foreach.getStartForeach()); + source.jumpToCodePosition(foreach.getStartForeach(), result); } next(); continue; @@ -114,18 +113,18 @@ public class CodeIteratorForeach extends AbstractCodeIterator { condition.analyze(context, memory); final ExecutionContextForeach foreach = ExecutionContextForeach.fromValue(condition.getVarname(), condition.getJsonArray(), source.getCodePosition()); - if (condition.isSkip()) { + if (condition.isSkip()) foreach.skipMeNow(); - } else { + else setLoopVariable(memory, foreach, s); - } + memory.addForeach(foreach); } private void setLoopVariable(TMemory memory, ExecutionContextForeach foreach, StringLocated position) throws EaterException { final JsonValue first = foreach.getJsonArray().get(foreach.currentIndex()); - memory.putVariable(foreach.getVarname(), TValue.fromJson(first), TVariableScope.GLOBAL); + memory.putVariable(foreach.getVarname(), TValue.fromJson(first), TVariableScope.GLOBAL, position); } } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java index 8ee1d08a1..43ae09658 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java @@ -118,18 +118,17 @@ public class CodeIteratorIf extends AbstractCodeIterator { private void executeElseIf(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf(); - if (poll == null) { - throw EaterException.located("No if related to this else"); - } + if (poll == null) + throw EaterException.located("No if related to this else", s); poll.enteringElseIf(); if (poll.hasBeenBurn() == false) { final EaterElseIf condition = new EaterElseIf(s); condition.analyze(context, memory); final boolean isTrue = condition.isTrue(); - if (isTrue) { + if (isTrue) poll.nowInSomeElseIf(); - } + } } @@ -149,17 +148,17 @@ public class CodeIteratorIf extends AbstractCodeIterator { private void executeElse(TContext context, TMemory memory, StringLocated s) throws EaterException { final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf(); - if (poll == null) { - throw EaterException.located("No if related to this else"); - } + if (poll == null) + throw EaterException.located("No if related to this else", s); + poll.nowInElse(); } private void executeEndif(TContext context, TMemory memory, StringLocated s) throws EaterException { final ExecutionContextIf poll = (ExecutionContextIf) memory.pollIf(); - if (poll == null) { - throw EaterException.located("No if related to this endif"); - } + if (poll == null) + throw EaterException.located("No if related to this endif", s); + } } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorImpl.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorImpl.java index e00986810..985fcd398 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorImpl.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorImpl.java @@ -62,34 +62,38 @@ public class CodeIteratorImpl implements CodeIterator { this.list = list; } + @Override public StringLocated peek() { - if (current == list.size()) { + if (current == list.size()) return null; - } - if (current > list.size()) { + + if (current > list.size()) throw new IllegalStateException(); - } + return list.get(current); } + @Override public void next() { - if (current >= list.size()) { + if (current >= list.size()) throw new IllegalStateException(); - } + assert current < list.size(); current++; assert current <= list.size(); } + @Override public CodePosition getCodePosition() { return new Position(current); } - public void jumpToCodePosition(CodePosition newPosition) throws EaterException { + @Override + public void jumpToCodePosition(CodePosition newPosition, StringLocated location) throws EaterException { this.countJump++; - if (this.countJump > 999) { - throw EaterException.unlocated("Infinite loop?"); - } + if (this.countJump > 999) + throw EaterException.unlocated("Infinite loop?", location); + final Position pos = (Position) newPosition; this.current = pos.pos; diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java index 6a7aaa876..2c15a7b3e 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java @@ -67,13 +67,13 @@ public class CodeIteratorSub extends AbstractCodeIterator { } public StringLocated peek() throws EaterException, EaterExceptionLocated { - if (readingInProgress != null) { + if (readingInProgress != null) return readingInProgress.peek(); - } + StringLocated result = source.peek(); - if (result == null) { + if (result == null) return null; - } + if (result.getType() == TLineType.STARTSUB) { final EaterStartsub eater = new EaterStartsub(result.getTrimmed()); eater.analyze(context, memory); @@ -83,7 +83,7 @@ public class CodeIteratorSub extends AbstractCodeIterator { StringLocated s = null; while ((s = source.peek()) != null) { if (s.getType() == TLineType.STARTSUB) { - throw EaterException.located("Cannot nest sub"); + throw EaterException.located("Cannot nest sub", result); } else if (s.getType() == TLineType.ENDSUB) { source.next(); readingInProgress = new CodeIteratorImpl(created.lines()); @@ -94,9 +94,9 @@ public class CodeIteratorSub extends AbstractCodeIterator { } } } - if (readingInProgress != null) { + if (readingInProgress != null) return readingInProgress.peek(); - } + return result; } @@ -107,9 +107,9 @@ public class CodeIteratorSub extends AbstractCodeIterator { return; } readingInProgress.next(); - if (readingInProgress.peek() == null) { + if (readingInProgress.peek() == null) readingInProgress = null; - } + } } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java index 84f201e6a..01b445898 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java @@ -64,9 +64,8 @@ public class CodeIteratorWhile extends AbstractCodeIterator { int level = 0; while (true) { final StringLocated result = source.peek(); - if (result == null) { + if (result == null) return null; - } final ExecutionContextWhile currentWhile = memory.peekWhile(); if (currentWhile != null && currentWhile.isSkipMe()) { @@ -91,14 +90,14 @@ public class CodeIteratorWhile extends AbstractCodeIterator { } else if (result.getType() == TLineType.ENDWHILE) { logs.add(result); if (currentWhile == null) - throw EaterException.located("No while related to this endwhile"); + throw EaterException.located("No while related to this endwhile", result); final TValue value = currentWhile.conditionValue(result, context, memory); - if (value.toBoolean()) { - source.jumpToCodePosition(currentWhile.getStartWhile()); - } else { + if (value.toBoolean()) + source.jumpToCodePosition(currentWhile.getStartWhile(), result); + else memory.pollWhile(); - } + next(); continue; } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java index 0bc47532a..830f5bf25 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java @@ -65,9 +65,9 @@ public class CallUserFunction extends SimpleReturnFunction { final List args = values.subList(1, values.size()); final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); final TFunction func = context.getFunctionSmart(signature); - if (func == null) { - throw EaterException.unlocated("Cannot find void function " + fname); - } + if (func == null) + throw EaterException.unlocated("Cannot find void function " + fname, location); + return func.executeReturnFunction(context, memory, location, args, named); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Darken.java b/src/net/sourceforge/plantuml/tim/stdlib/Darken.java index 4a282d150..1365c7614 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Darken.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Darken.java @@ -71,7 +71,7 @@ public class Darken extends SimpleReturnFunction { color = color.darken(ratio); return TValue.fromString(color.asString()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java index e596ef4b7..0db1db510 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java @@ -71,10 +71,11 @@ public class DateFunction extends SimpleReturnFunction { now = 1000L * values.get(1).toInt(); else now = System.currentTimeMillis(); + try { return TValue.fromString(new SimpleDateFormat(format).format(now)); } catch (Exception e) { - throw EaterException.unlocated("Bad date pattern"); + throw EaterException.unlocated("Bad date pattern", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetAllStdlib.java b/src/net/sourceforge/plantuml/tim/stdlib/GetAllStdlib.java index 4bac0865e..2bc32f045 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetAllStdlib.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetAllStdlib.java @@ -99,7 +99,8 @@ public class GetAllStdlib extends SimpleReturnFunction { } default: - throw EaterException.located("Error on get_all_stdlib: Too many arguments"); + assert false; // Should not append because of canCover() + throw EaterException.located("Error on get_all_stdlib: Too many arguments", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java index 0bd617053..5b48e27c4 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java @@ -65,7 +65,8 @@ public class GetJsonKey extends SimpleReturnFunction { Map named) throws EaterException, EaterExceptionLocated { final TValue data = values.get(0); if (data.isJson() == false) - throw EaterException.unlocated("Not JSON data"); + throw EaterException.unlocated("Not JSON data", location); + final JsonValue json = data.toJson(); if (json.isObject()) { final JsonObject object = (JsonObject) json; @@ -87,7 +88,7 @@ public class GetJsonKey extends SimpleReturnFunction { return TValue.fromJson(result); } - throw EaterException.unlocated("Bad JSON type"); + throw EaterException.unlocated("Bad JSON type", location); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java index 64503ed11..01e4f2036 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java @@ -71,7 +71,7 @@ public class InvokeProcedure implements TFunction { final TFunctionSignature signature = new TFunctionSignature(fname, sublist.size()); final TFunction func = context.getFunctionSmart(signature); if (func == null) - throw EaterException.located("Cannot find void function " + fname); + throw EaterException.located("Cannot find void function " + fname, location); func.executeProcedureInternal(context, memory, location, sublist, named); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java b/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java index d8f337bf5..f8fa6c394 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java @@ -69,7 +69,7 @@ public class IsDark extends SimpleReturnFunction { final HColor color = HColorSet.instance().getColorLEGACY(colorString); return TValue.fromBoolean(color.isDark()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java b/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java index e298e1baa..771425750 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java @@ -69,7 +69,7 @@ public class IsLight extends SimpleReturnFunction { final HColor color = HColorSet.instance().getColorLEGACY(colorString); return TValue.fromBoolean(!color.isDark()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java b/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java index ac69bf9e4..1ec5b593b 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java @@ -71,7 +71,7 @@ public class Lighten extends SimpleReturnFunction { color = color.lighten(ratio); return TValue.fromString(color.asString()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java b/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java index 58e6a74bf..a03972239 100755 --- a/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java @@ -120,10 +120,11 @@ public class LoadJson extends SimpleReturnFunction { return TValue.fromJson(jsonValue); } catch (ParseException pe) { Logme.error(pe); - throw EaterException.unlocated("JSON parse issue in source " + path + " on location " + pe.getLocation()); + throw EaterException.unlocated("JSON parse issue in source " + path + " on location " + pe.getLocation(), + location); } catch (UnsupportedEncodingException e) { Logme.error(e); - throw EaterException.unlocated("JSON encoding issue in source " + path + ": " + e.getMessage()); + throw EaterException.unlocated("JSON encoding issue in source " + path + ": " + e.getMessage(), location); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java index bf7786f5c..d284045a6 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java @@ -77,7 +77,8 @@ public class RandomFunction extends SimpleReturnFunction { return TValue.fromInt(random.nextInt(max - min) + min); default: - throw EaterException.located("Error on Random: Too many argument"); + assert false; // Should not append because of canCover() + throw EaterException.located("Error on Random: Too many argument", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java b/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java index 43521f070..ef1d94ff3 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java @@ -69,7 +69,7 @@ public class ReverseColor extends SimpleReturnFunction { color = color.reverse(); return TValue.fromString(color.asString()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java b/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java index bcfaa72b9..041fe5cab 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java @@ -69,7 +69,7 @@ public class ReverseHsluvColor extends SimpleReturnFunction { color = color.reverseHsluv(); return TValue.fromString(color.asString()); } catch (NoSuchColorException e) { - throw EaterException.located("No such color"); + throw EaterException.located("No such color", location); } } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java index 1dd202157..18123b644 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java @@ -66,7 +66,7 @@ public class SetVariableValue extends SimpleReturnFunction { // } final String name = values.get(0).toString(); final TValue value = values.get(1); - memory.putVariable(name, value, TVariableScope.GLOBAL); + memory.putVariable(name, value, TVariableScope.GLOBAL, location); return TValue.fromString(""); } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 77f7aa10b..80dec5df6 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -46,7 +46,7 @@ public class Version { // Warning, "version" should be the same in gradle.properties and Version.java // Any idea anyone how to magically synchronize those :-) ? - private static final String version = "1.2024.4beta2"; + private static final String version = "1.2024.4beta3"; public static String versionString() { return version;