-
-
Notifications
You must be signed in to change notification settings - Fork 352
/
EffReturn.java
139 lines (121 loc) · 4.23 KB
/
EffReturn.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.effects;
import ch.njol.skript.Skript;
import ch.njol.skript.classes.ClassInfo;
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.LoopSection;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.TriggerSection;
import ch.njol.skript.lang.function.FunctionEvent;
import ch.njol.skript.lang.function.Functions;
import ch.njol.skript.lang.function.ScriptFunction;
import ch.njol.skript.log.RetainingLogHandler;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;
@Name("Return")
@Description("Makes a function return a value")
@Examples({
"function double(i: number) :: number:",
"\treturn 2 * {_i}",
"",
"function divide(i: number) returns number:",
"\treturn {_i} / 2"
})
@Since("2.2, 2.8.0 (returns aliases)")
public class EffReturn extends Effect {
static {
Skript.registerEffect(EffReturn.class, "return %objects%");
}
@SuppressWarnings("NotNullFieldNotInitialized")
private ScriptFunction<?> function;
@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<?> value;
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
ScriptFunction<?> f = Functions.currentFunction;
if (f == null) {
Skript.error("The return statement can only be used in a function");
return false;
}
if (!isDelayed.isFalse()) {
Skript.error("A return statement after a delay is useless, as the calling trigger will resume when the delay starts (and won't get any returned value)");
return false;
}
function = f;
ClassInfo<?> returnType = function.getReturnType();
if (returnType == null) {
Skript.error("This function doesn't return any value. Please use 'stop' or 'exit' if you want to stop the function.");
return false;
}
RetainingLogHandler log = SkriptLogger.startRetainingLog();
Expression<?> convertedExpr;
try {
convertedExpr = exprs[0].getConvertedExpression(returnType.getC());
if (convertedExpr == null) {
log.printErrors("This function is declared to return " + returnType.getName().withIndefiniteArticle() + ", but " + exprs[0].toString(null, false) + " is not of that type.");
return false;
}
log.printLog();
} finally {
log.stop();
}
if (f.isSingle() && !convertedExpr.isSingle()) {
Skript.error("This function is defined to only return a single " + returnType.toString() + ", but this return statement can return multiple values.");
return false;
}
value = convertedExpr;
return true;
}
@Override
@Nullable
@SuppressWarnings({"unchecked", "rawtypes"})
protected TriggerItem walk(Event event) {
debug(event, false);
if (event instanceof FunctionEvent) {
((ScriptFunction) function).setReturnValue(value.getArray(event));
} else {
assert false : event;
}
TriggerSection parent = getParent();
while (parent != null) {
if (parent instanceof LoopSection)
((LoopSection) parent).exit(event);
parent = parent.getParent();
}
return null;
}
@Override
protected void execute(Event event) {
assert false;
}
@Override
public String toString(@Nullable Event event, boolean debug) {
return "return " + value.toString(event, debug);
}
}