Skip to content

Commit c245095

Browse files
Fix SectionNode claiming edge cases (#8232)
1 parent 51b6bb1 commit c245095

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

src/main/java/ch/njol/skript/lang/EffectSection.java

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
*/
2424
public abstract class EffectSection extends Section {
2525

26+
static {
27+
ParserInstance.registerData(EffectSectionContext.class, EffectSectionContext::new);
28+
}
29+
2630
private boolean hasSection;
2731

2832
public boolean hasSection() {
@@ -34,10 +38,23 @@ public boolean hasSection() {
3438
*/
3539
@Override
3640
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
37-
SectionContext sectionContext = getParser().getData(SectionContext.class);
41+
ParserInstance parser = getParser();
42+
SectionContext sectionContext = parser.getData(SectionContext.class);
43+
EffectSectionContext effectSectionContext = parser.getData(EffectSectionContext.class);
44+
SectionNode sectionNode = sectionContext.sectionNode;
45+
if (!effectSectionContext.isNodeForEffectSection) {
46+
sectionContext.sectionNode = null;
47+
}
48+
3849
//noinspection ConstantConditions - For an EffectSection, it may be null
3950
hasSection = sectionContext.sectionNode != null;
40-
return super.init(expressions, matchedPattern, isDelayed, parseResult);
51+
boolean result = super.init(expressions, matchedPattern, isDelayed, parseResult);
52+
53+
if (!effectSectionContext.isNodeForEffectSection) {
54+
sectionContext.sectionNode = sectionNode;
55+
}
56+
57+
return result;
4158
}
4259

4360
@Override
@@ -52,15 +69,48 @@ public abstract boolean init(Expression<?>[] expressions,
5269
* Similar to {@link Section#parse(String, String, SectionNode, List)}, but will only attempt to parse from other {@link EffectSection}s.
5370
*/
5471
public static @Nullable EffectSection parse(String input, @Nullable String defaultError, @Nullable SectionNode sectionNode, @Nullable List<TriggerItem> triggerItems) {
55-
SectionContext sectionContext = ParserInstance.get().getData(SectionContext.class);
72+
return parse(input, defaultError, sectionNode, true, triggerItems);
73+
}
74+
75+
/**
76+
* Similar to {@link Section#parse(String, String, SectionNode, List)}, but will only attempt to parse from other {@link EffectSection}s.
77+
* @param isNodeForEffectSection Whether {@code sectionNode} can be {@link SectionContext#claim(SyntaxElement)}-ed by the parsed EffectSection.
78+
*/
79+
public static @Nullable EffectSection parse(String input, @Nullable String defaultError, SectionNode sectionNode, boolean isNodeForEffectSection, List<TriggerItem> triggerItems) {
80+
ParserInstance parser = ParserInstance.get();
81+
SectionContext sectionContext = parser.getData(SectionContext.class);
82+
EffectSectionContext effectSectionContext = parser.getData(EffectSectionContext.class);
83+
boolean wasNodeForEffectSection = effectSectionContext.isNodeForEffectSection;
84+
effectSectionContext.isNodeForEffectSection = isNodeForEffectSection;
5685

57-
return sectionContext.modify(sectionNode, triggerItems, () -> {
86+
EffectSection effectSection = sectionContext.modify(sectionNode, triggerItems, () -> {
5887
var iterator = Skript.instance().syntaxRegistry().syntaxes(org.skriptlang.skript.registration.SyntaxRegistry.SECTION).stream()
59-
.filter(info -> EffectSection.class.isAssignableFrom(info.type()))
60-
.iterator();
88+
.filter(info -> EffectSection.class.isAssignableFrom(info.type()))
89+
.iterator();
6190
//noinspection unchecked,rawtypes
62-
return (EffectSection) SkriptParser.parse(input, (Iterator) iterator, defaultError);
91+
EffectSection parsed = (EffectSection) SkriptParser.parse(input, (Iterator) iterator, defaultError);
92+
if (parsed != null && sectionNode != null && !sectionContext.claimed()) {
93+
Skript.error("The line '" + input + "' is a valid statement but cannot function as a section (:) because there is no syntax in the line to manage it.");
94+
return null;
95+
}
96+
return parsed;
6397
});
98+
99+
effectSectionContext.isNodeForEffectSection = wasNodeForEffectSection;
100+
return effectSection;
101+
}
102+
103+
private static class EffectSectionContext extends ParserInstance.Data {
104+
105+
/**
106+
* Whether the {@link SectionContext#sectionNode} can be used by the initializing {@link EffectSection}.
107+
*/
108+
public boolean isNodeForEffectSection = true;
109+
110+
public EffectSectionContext(ParserInstance parserInstance) {
111+
super(parserInstance);
112+
}
113+
64114
}
65115

66116
}

src/main/java/ch/njol/skript/lang/Statement.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ public abstract class Statement extends TriggerItem implements SyntaxElement {
3333
Section.SectionContext sectionContext = ParserInstance.get().getData(Section.SectionContext.class);
3434
EffFunctionCall functionCall;
3535
if (node != null) {
36-
functionCall = sectionContext.modify(node, items, () -> EffFunctionCall.parse(input));
36+
functionCall = sectionContext.modify(node, items, () -> {
37+
EffFunctionCall parsed = EffFunctionCall.parse(input);
38+
if (parsed != null && !sectionContext.claimed()) {
39+
Skript.error("The line '" + input + "' is a valid function call but cannot function as a section (:) because there is no parameter to manage it.");
40+
return null;
41+
}
42+
return parsed;
43+
});
3744
} else {
3845
functionCall = EffFunctionCall.parse(input);
3946
}
@@ -46,7 +53,7 @@ public abstract class Statement extends TriggerItem implements SyntaxElement {
4653
}
4754
log.clear();
4855

49-
EffectSection section = EffectSection.parse(input, null, null, items);
56+
EffectSection section = EffectSection.parse(input, null, node, false, items);
5057
if (section != null) {
5158
log.printLog();
5259
return new EffectSectionEffect(section);

src/test/skript/tests/regressions/8199-parse exprsecs in function args.sk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ local function f(x: worldborder):
44
test "load expr secs in functions":
55
f(a worldborder):
66
set worldborder warning time to 20 ticks
7+
8+
# ensure it fails for unclaimed sections
9+
parse:
10+
f({_null}):
11+
stop
12+
assert first element of last parse logs contains "is a valid function call but cannot function as a section" with "failed to correctly error for unclaimed section"

0 commit comments

Comments
 (0)