Repository navigation
Simplify MapToolLineParser and related code - #6071
Open
kwvanderlinde wants to merge 10 commits into
Open
kwvanderlinde wants to merge 10 commits into
kwvanderlinde wants to merge 10 commits into
Conversation
kwvanderlinde
force-pushed
the
refactor/6070-MapToolLineParser
branch
2 times, most recently
from
October 18, 2026 07:12
e0eaddc to
5cca691
Compare
kwvanderlinde
force-pushed
the
refactor/6070-MapToolLineParser
branch
from
November 7, 2026 17:13
5cca691 to
ccd951d
Compare
These were simply unused and thus have been removed: - `#UNKNOWN_LIB_MACRO` - `#getTokenMacroLib(String)` - `#getTokenMacroLibZone(String)` - `InlineRollMatch(int, int, String)` (previously suppressed) - `InlineRollMatch#getOptEnd()` (previously suppressed) Additionally, the `#runMacroBlock()` overloads have been removed since they are either unused or don't do anything meaningful. There is only one surviving `#runMacroBlock()` method, and it is `private` now.
Static fields are now all at the top of the class, separated by services and constants. In general, avoid writing things that don't need to exist (generics, initializers, non-zero length checks, etc). Some improvements as well to how the context stack is interacted with (no more `#contextStackEmpty()`, and `#getContext()` is explicitly nullable now).
For most of the methods, this just removes the uninteresting overloads that tack on a `null` or `true` to the argument list. This applies to: - `#runMacro()` - `#rollString()` - `#expandRoll()` - `#parseExpression()` - `#enterContext()` (overload only used in tests) The `#parseLine()` change is similar, but with a bit more going on. It now requires the variable resolver to be provided by the caller (`null` is no longer allowed). It is the caller's responsibility to ensure the variable resolver and `tokenInContext` agree as needed. Otherwise, like the other methods, the other overloads have been removed.
Many methods that accepted a `Token tokenInContext` parameter did not ultimately use it. Others only used when creating a new `MapToolVariableResolver` in case a `null` was passed, but this was avoided by requiring callers to always pass a real `MapToolVariableResolver`. Once the above was done, it became clear that there was no need to pass around `tokenInContext` separately from `MapToolVariableResolver` at all. Overloads of methods like `MapToolLineParser#parseLine()` are now more focused on providing the option to provide a `MapToolVariableResolver` directly, or for convenience a `Token` that should be wrapped in a `MapToolVariableResolver`.
This also means we don't need to "initialize" or "flush" the resolver anymore.
This avoids any possibility of callers providing a resolver for a different token, and just better separates responsibilities. It also means `Token` isn't responsible for evaluating arbitrary objects either, as it had to with `evaluateProperty()`. In contrast with the old methods from `Token`, the new methods on `MapToolVariableResolver` only allows evaluating a named property's value or default value. There is no exposed way to evaluate an arbitrary object.
`#enterContext()` no longer handles the `context == null` case, instead requiring the caller to always provide a real context to use. This case was only ever used by `parseLine()` anyway, and is much clearer when done there. This fixes a bug where entering a new **trusted** top-level context on an empty context stack would set `macroPathTrusted` to `false`, whereas in every other case (including calls through `#enterTrustedContext())` this would result in `true`. The surrounding comments also clarify that this is the intent. Now that `#enterContext()` no longer creates a context, it also has no reason to return one. Similarly, `#exitContext()` no longer returns a context either.
`#enterContext()`, `#enterTrustedContext()`, and `#enterUntrustedContext()` now all return an `AutoCloseable` that can
be used to exit the context. All callers now use this, and so `#exitContext()` has been removed as unnecessary.
All callers now use try-with-resources to guarantee proper exiting of the context. Most sites were already well-behaved,
but a couple had issues:
- `ExecFunction#runExecFunction()` has not wrapped `#exitContext()` in a `finally {...}` block, though it did at least
catch `ParseException` first. So this was unlikely to be seen in a reproducible way.
- `EventMacroUtil#callEventHandlerOld()` wrapped `#exitContext()` in the wrong `finally {...}` block. If an error were
throw while setting up the variables (including a handled `ParserException`), it would end up exiting a context it
never entered. In practice, however, this case could not be hit since the function is only used for `onCampaignLoad`
which sets no variables.
kwvanderlinde
force-pushed
the
refactor/6070-MapToolLineParser
branch
from
November 7, 2026 17:14
ccd951d to
211feeb
Compare
cwisniew
approved these changes
Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Identify the Bug or Feature request
Resolves #6070
Description of the Change
There's a few semi-independent things going on. Mostly, it's that cleanup in
MapToolLineParsermotivated clean up elsewhere. The bulk of the changes outside ofMapToolLineParser,MapToolVariableResolver, andTokenare just callers being updated to reflect the method changes.MapToolLineParser
The bulk of the change is in here. Most method overloads have been removed since they did not do anything interesting beyond saving callers a few characters here and there. This applies to:
#runMacro()#rollString()#expandRoll()#parseExpression()#enterContext()(overload that was only used in tests)#parseLine()#parseLine()also has a couple other simplifications:MapToolVariableResolver. Passingnullis no longer an option.tokenInContextparameter would always be the same asresolver.getTokenInContext(). So the parameter (which had to be plumbed around in many places) has been removed.The class was generally cleaned up as well:
privateif they aren't needed outsideMapToolLineParser.While updating dependent code, some other unnecessary or unused code was identified and removed as well.
Token
The
Tokenclass no longer has anything to do with property evaluation. It only does property lookup. The evaluation portions were moved intoMapToolVariableResolverthat only knows how to evaluate properties of itstokenInContext. Additionaly,MapToolVariableResolverdoes not permit arbitrary evaluations (asToken#evaluateProperty()did), instead only permitted properties to be looked up and evaluated by the property name.The main thrust of this change is to avoid any possibility of one token being asked to evaluate its own properties with a resolver that was set up for a different token. And many callers already have their resolver + token available, and so it's simpler for them with the new approach.
MapToolVariableResolver
A quality of life change in
MapToolVariableResolveris the new#spawn()method that creates a newMapToolVariableResolverwith the sametokenInContext. This simplifies a handful of places that create resolvers, and allows these call sites to continue to be correct into the future if we ever add to what can be "in context".Also, the delayed actions were never used, so they have been removed. That also means we no longer need to call
MapToolVariableResolver#initialize()orMapToolVariableResolver#flush().MapToolLineParser contexts
#enterContext()has been simplified so it no longer handles thecontext == nullcase. This case was only ever hit insideparseLine(), and it is clearer to create the new context there. All other callers provided a non-null context.Since
#enterContext()no longer has to return aMapToolMacroContext, it (and related methods) instead returns anAutoCloseablethat can be used to exit the context. Most callers were already usingtry/finally(or at leasttry/catch) to consistently exit their contexts, and this allows to avoid the explicitfinallylogic. It also fixes some "bugs", though these aren't hit in practice:EventMacroUtil#callEventHandlerOld()could exit the wrong context if an error was thrown while setting variables. Not actually hit since it is only used foronCampaignLoadwhich does not set variables.ExecFunction#runExecFunction()would not exit its context if an unhandled exception was thrown, though it did at least catchParserException.Possible Drawbacks
The change to
MapToolLineParser#enterContext()had one change of behaviour, but I'm not sure right now how to expose it. I'm 99% sure the original behaviour is unintended.If
#enterContext()received anullparameter with an empty context stack, it would always set#macroPathTrustedtofalse, even if the generated context would have been trusted (i.e., if the player is a GM). This is specific to being called the first time from#parseLine()as calls from#enterTrustedContext()and#enterUntrustedContext()do not hit this case even if they are run on an empty stack and would add an identical context to the stack. This had resulted in an inconsistency where entering a top-level trusted context on an empty stack might set#macroPathTrustedtotrue, but it might not. Along with the comment in#enterContext(), I'm pretty confident the new behaviour is the intended behaviour:Documentation Notes
N/A
Release Notes
This change is