Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unreachable Code #6960

Merged
merged 25 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
816e29e
Add a warning for unreachable code
UnderscoreTud Aug 4, 2024
ff6c45b
Clean up EffSuppressWarnings and add the ability to disable the unrea…
UnderscoreTud Aug 7, 2024
a091a6c
Add comments
UnderscoreTud Aug 11, 2024
21bca9b
Requested Changes
UnderscoreTud Aug 14, 2024
e38462f
Merge branch 'dev/feature' into feature/unreachable-code-warning
sovdeeth Aug 14, 2024
849cbd7
Generify compareTo method
UnderscoreTud Aug 15, 2024
1562983
Add docs to ExecutionIntent
UnderscoreTud Aug 31, 2024
18591ad
Fix lines using spaces instead of tabs for indentation (unsure how th…
UnderscoreTud Aug 31, 2024
fc14b86
Add ExecutionIntent to EffContinue, and fix its toString
UnderscoreTud Sep 3, 2024
065c5c8
Improve SecLoop's intent detection
UnderscoreTud Sep 3, 2024
c1bf355
Merge branch 'dev/feature' into feature/unreachable-code-warning
UnderscoreTud Sep 3, 2024
8a51732
Use instanceof pattern matching
UnderscoreTud Sep 3, 2024
cd80a39
Use MoreObject.toStringHelper
UnderscoreTud Sep 4, 2024
0ab6a00
Replace all space indentations with tabs
UnderscoreTud Sep 4, 2024
ce79b11
Add simple helper methods for getting relative sections
UnderscoreTud Sep 4, 2024
501253d
Add comments to SecLoop#guaranteedToLoop
UnderscoreTud Sep 4, 2024
3afdbb6
Capitalize the 'C' in EffExit's errors
UnderscoreTud Sep 4, 2024
b6e7f01
Return a copy of the sections list rather than a view in the section …
UnderscoreTud Sep 5, 2024
245d1e5
Make EffContinue's and EffExit's patterns stricter
UnderscoreTud Sep 5, 2024
666f94c
Fix ArrayOutOfBoundsException when using Section.getSections of a typ…
UnderscoreTud Sep 5, 2024
79fcc25
Update javadocs
UnderscoreTud Sep 10, 2024
e6e6000
Merge branch 'dev/feature' into feature/unreachable-code-warning
UnderscoreTud Sep 17, 2024
3fea368
Requested Changes
UnderscoreTud Sep 17, 2024
79074af
Update src/main/java/ch/njol/skript/sections/SecConditional.java
UnderscoreTud Sep 22, 2024
fd3d93d
Merge branch 'dev/feature' into feature/unreachable-code-warning
sovdeeth Oct 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions src/main/java/ch/njol/skript/ScriptLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.util.event.EventRegistry;
import org.skriptlang.skript.lang.script.Script;
import org.skriptlang.skript.lang.script.ScriptWarning;
import org.skriptlang.skript.lang.structure.Structure;

import java.io.File;
Expand Down Expand Up @@ -978,9 +979,10 @@ public static ArrayList<TriggerItem> loadItems(SectionNode node) {

if (Skript.debug())
parser.setIndentation(parser.getIndentation() + " ");

ArrayList<TriggerItem> items = new ArrayList<>();

boolean executionStops = false;
for (Node subNode : node) {
parser.setNode(subNode);

Expand All @@ -991,10 +993,11 @@ public static ArrayList<TriggerItem> loadItems(SectionNode node) {
if (!SkriptParser.validateLine(expr))
continue;

TriggerItem item;
if (subNode instanceof SimpleNode) {
long start = System.currentTimeMillis();
Statement stmt = Statement.parse(expr, items, "Can't understand this condition/effect: " + expr);
if (stmt == null)
item = Statement.parse(expr, items, "Can't understand this condition/effect: " + expr);
if (item == null)
continue;
long requiredTime = SkriptConfig.longParseTimeWarningThreshold.value().getMilliSeconds();
if (requiredTime > 0) {
Expand All @@ -1007,34 +1010,44 @@ public static ArrayList<TriggerItem> loadItems(SectionNode node) {
}

if (Skript.debug() || subNode.debug())
Skript.debug(SkriptColor.replaceColorChar(parser.getIndentation() + stmt.toString(null, true)));
Skript.debug(SkriptColor.replaceColorChar(parser.getIndentation() + item.toString(null, true)));

items.add(stmt);
items.add(item);
} else if (subNode instanceof SectionNode) {
TypeHints.enterScope(); // Begin conditional type hints

Section section = Section.parse(expr, "Can't understand this section: " + expr, (SectionNode) subNode, items);
if (section == null)
item = Section.parse(expr, "Can't understand this section: " + expr, (SectionNode) subNode, items);
if (item == null)
continue;

if (Skript.debug() || subNode.debug())
Skript.debug(SkriptColor.replaceColorChar(parser.getIndentation() + section.toString(null, true)));
Skript.debug(SkriptColor.replaceColorChar(parser.getIndentation() + item.toString(null, true)));

items.add(section);
items.add(item);

// Destroy these conditional type hints
TypeHints.exitScope();
} else {
continue;
}

if (executionStops
&& !SkriptConfig.disableUnreachableCodeWarnings.value()
&& parser.isActive()
&& !parser.getCurrentScript().suppressesWarning(ScriptWarning.UNREACHABLE_CODE)) {
Skript.warning("Unreachable code. The previous statement stops further execution.");
}
executionStops = item.executionIntent() != null;
}

for (int i = 0; i < items.size() - 1; i++)
items.get(i).setNext(items.get(i + 1));

parser.setNode(node);

if (Skript.debug())
parser.setIndentation(parser.getIndentation().substring(0, parser.getIndentation().length() - 4));

return items;
}

Expand Down
1 change: 1 addition & 0 deletions src/main/java/ch/njol/skript/SkriptConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ public static String formatDate(final long timestamp) {
public static final Option<Boolean> disableMissingAndOrWarnings = new Option<>("disable variable missing and/or warnings", false);
public static final Option<Boolean> disableVariableStartingWithExpressionWarnings =
new Option<>("disable starting a variable's name with an expression warnings", false);
public static final Option<Boolean> disableUnreachableCodeWarnings = new Option<>("disable unreachable code warnings", false);

@Deprecated
public static final Option<Boolean> enableScriptCaching = new Option<>("enable script caching", false)
Expand Down
68 changes: 39 additions & 29 deletions src/main/java/ch/njol/skript/effects/EffContinue.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,19 @@
package ch.njol.skript.effects;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.data.JavaClasses;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.LoopSection;
import ch.njol.skript.lang.*;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.parser.ParserInstance;
import ch.njol.util.Kleenean;
import ch.njol.util.StringUtils;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;

import java.util.List;

Expand Down Expand Up @@ -61,39 +60,45 @@ public class EffContinue extends Effect {
static {
Skript.registerEffect(EffContinue.class,
"continue [this loop|[the] [current] loop]",
"continue [the] %*integer%(st|nd|rd|th) loop"
"continue [the] <" + JavaClasses.INTEGER_PATTERN + ">(st|nd|rd|th) loop"
);
}

@SuppressWarnings("NotNullFieldNotInitialized")
private LoopSection loop;
@SuppressWarnings("NotNullFieldNotInitialized")
private List<LoopSection> innerLoops;
// Used for toString
private int level;

private @UnknownNullability LoopSection loop;
private @UnknownNullability List<SectionExitHandler> sectionsToExit;
private int breakLevels;

@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
List<LoopSection> currentLoops = getParser().getCurrentSections(LoopSection.class);
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
level = matchedPattern == 0 ? 1 : Integer.parseInt(parseResult.regexes.get(0).group());
if (level < 1)
return false;

int size = currentLoops.size();
if (size == 0) {
ParserInstance parser = getParser();
int loops = parser.getCurrentSections(LoopSection.class).size();
if (loops == 0) {
Skript.error("The 'continue' effect may only be used in loops");
return false;
}

int level = matchedPattern == 0 ? size : ((Literal<Integer>) exprs[0]).getSingle();
if (level < 1) {
Skript.error("Can't continue the " + StringUtils.fancyOrderNumber(level) + " loop");
return false;
}
if (level > size) {
// Section.getSections counts from the innermost section, so we need to invert the level
int levels = level == -1 ? 1 : loops - level + 1;
if (levels <= 0) {
Skript.error("Can't continue the " + StringUtils.fancyOrderNumber(level) + " loop as there " +
(size == 1 ? "is only 1 loop" : "are only " + size + " loops") + " present");
(loops == 1 ? "is only 1 loop" : "are only " + loops + " loops") + " present");
return false;
}

loop = currentLoops.get(level - 1);
innerLoops = currentLoops.subList(level, size);
List<TriggerSection> innerSections = parser.getSections(levels, LoopSection.class);
breakLevels = innerSections.size();
loop = (LoopSection) innerSections.remove(0);
sectionsToExit = innerSections.stream()
.filter(SectionExitHandler.class::isInstance)
.map(SectionExitHandler.class::cast)
.toList();
return true;
}

Expand All @@ -103,16 +108,21 @@ protected void execute(Event event) {
}

@Override
@Nullable
protected TriggerItem walk(Event event) {
for (LoopSection loop : innerLoops)
loop.exit(event);
protected @Nullable TriggerItem walk(Event event) {
debug(event, false);
for (SectionExitHandler section : sectionsToExit)
section.exit(event);
return loop;
}

@Override
public ExecutionIntent executionIntent() {
return ExecutionIntent.stopSections(breakLevels);
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "continue";
return "continue" + (level == -1 ? "" : " the " + StringUtils.fancyOrderNumber(level) + " loop");
}

}
Loading
Loading