forked from Mwexim/skript-parser
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCondExprContains.java
More file actions
106 lines (99 loc) · 4.32 KB
/
CondExprContains.java
File metadata and controls
106 lines (99 loc) · 4.32 KB
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
package io.github.syst3ms.skriptparser.expressions;
import io.github.syst3ms.skriptparser.Parser;
import io.github.syst3ms.skriptparser.lang.Expression;
import io.github.syst3ms.skriptparser.lang.TriggerContext;
import io.github.syst3ms.skriptparser.lang.base.ConditionalExpression;
import io.github.syst3ms.skriptparser.log.ErrorType;
import io.github.syst3ms.skriptparser.parsing.ParseContext;
import io.github.syst3ms.skriptparser.types.comparisons.Comparator;
import io.github.syst3ms.skriptparser.types.comparisons.Comparators;
import io.github.syst3ms.skriptparser.types.comparisons.Relation;
import io.github.syst3ms.skriptparser.util.DoubleOptional;
import org.jetbrains.annotations.Nullable;
/**
* See if a given list of objects contain a given element.
* You can also check if a string contains another string.
*
* @author Mwexim
* @name Contain
* @type CONDITION
* @pattern %string% [does(n't| not)] contain[s] %string%
* @pattern %objects% [do[es](n't| not)] contain[s] %objects%
* @since ALPHA
*/
public class CondExprContains extends ConditionalExpression {
static {
Parser.getMainRegistration().newExpression(
CondExprContains.class, Boolean.class, true,
"%string% [1:does(n't| not)] contain[s] %string%",
"%objects% [1:do[es](n't| not)] contain[s] %objects%"
)
.name("Contains")
.description("Checks if a given list of objects contain a given element. You can also check if a string contains another string.")
.examples("if {_string} contains \"hello\":",
"if {_list::*} contains player:")
.since("1.0.0")
.register();
}
private Expression<Object> first, second;
@Nullable
private Comparator<Object, Object> comparator;
private boolean onlyString;
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, ParseContext parseContext) {
first = (Expression<Object>) expressions[0];
second = (Expression<Object>) expressions[1];
comparator = (Comparator<Object, Object>) Comparators.getComparator(first.getReturnType(), second.getReturnType()).orElse(null);
// If the expressions are variables, their return type is unknown at parse time
if (first.getReturnType() != Object.class
&& second.getReturnType() != Object.class
&& comparator == null) {
var logger = parseContext.getLogger();
logger.error(
"'" +
first.toString(TriggerContext.DUMMY, logger.isDebug()) +
"' can never contain '" +
second.toString(TriggerContext.DUMMY, logger.isDebug()) +
"' because their values cannot be compared",
ErrorType.SEMANTIC_ERROR
);
return false;
}
onlyString = matchedPattern == 0;
setNegated(parseContext.getNumericMark() == 1);
if (!onlyString && !first.isAndList()) {
parseContext.getLogger().error(
"An or-list cannot contain any values",
ErrorType.SEMANTIC_ERROR,
"If you want to check if an or-list 'contains' a value, you should do an equality check instead."
);
return false;
}
return true;
}
@Override
public boolean check(TriggerContext ctx) {
if (onlyString) {
return isNegated() != DoubleOptional.ofOptional(first.getSingle(ctx), second.getSingle(ctx))
.map(toCheck -> (String) toCheck, toMatch -> (String) toMatch)
.mapToOptional(String::contains)
.orElse(false);
} else {
return second.check(
ctx,
toMatch -> Expression.check(
first.getValues(ctx),
toCheck -> (comparator == null ? Comparators.compare(toCheck, toMatch) : comparator.apply(toCheck, toMatch)).is(Relation.EQUAL),
false,
!first.isAndList()
),
isNegated()
);
}
}
@Override
public String toString(TriggerContext ctx, boolean debug) {
return first.toString(ctx, debug) + (isNegated() ? " does not contain " : " contains ") + second.toString(ctx, debug);
}
}