Skip to content
Merged
Changes from all commits
Commits
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
67 changes: 56 additions & 11 deletions src/main/java/ch/njol/skript/lang/ExpressionList.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.function.Predicate;

/**
Expand Down Expand Up @@ -184,20 +185,50 @@ public void invertAnd() {

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
Class<?>[] exprClasses = expressions[0].acceptChange(mode);
if (exprClasses == null)
return null;
ArrayList<Class<?>> acceptedClasses = new ArrayList<>(Arrays.asList(exprClasses));
for (int i = 1; i < expressions.length; i++) {
exprClasses = expressions[i].acceptChange(mode);
if (exprClasses == null)
return null;

acceptedClasses.retainAll(Arrays.asList(exprClasses));
if (acceptedClasses.isEmpty())
// given X: Object.class, Y: Vector.class, Number.class, Z: Integer.class
// output should be Integer.class.

// get all accepted type arrays.
List<Class<?>[]> expressionTypes = new ArrayList<>();
for (Expression<?> expr : expressions) {
Class<?>[] exprTypes = expr.acceptChange(mode);
if (exprTypes == null)
return null;
expressionTypes.add(exprTypes);
}

// shortcut
if (expressionTypes.size() == 1)
return expressionTypes.get(0);

// iterate over types and keep what works
Set<Class<?>> acceptable = new LinkedHashSet<>(Arrays.asList(expressionTypes.get(0)));
for (int i = 1; i < expressionTypes.size(); i++) {
Set<Class<?>> newAcceptable = new LinkedHashSet<>();

// Check if each existing acceptable types can be matched to this expr's accepted types
for (Class<?> candidate : acceptable) {
for (Class<?> accepted : expressionTypes.get(i)) {
// keep the more specific version
if (accepted.isAssignableFrom(candidate)) {
newAcceptable.add(candidate);
break;
} else if (candidate.isAssignableFrom(accepted)) {
newAcceptable.add(accepted);
break;
}
}
}

acceptable = newAcceptable;

if (acceptable.isEmpty()) {
return new Class<?>[0]; // Early exit if no common types
}
}
return acceptedClasses.toArray(new Class[0]);

return acceptable.toArray(new Class<?>[0]);
}

@Override
Expand All @@ -212,6 +243,20 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) thro
}
}

@Override
public <R> void changeInPlace(Event event, Function<T, R> changeFunction, boolean getAll) {
if (and || getAll) {
for (Expression<?> expr : expressions) {
//noinspection unchecked,rawtypes
expr.changeInPlace(event, (Function) changeFunction, getAll);
}
} else {
int i = ThreadLocalRandom.current().nextInt(expressions.length);
//noinspection unchecked,rawtypes
expressions[i].changeInPlace(event, (Function) changeFunction, false);
}
}

private int time = 0;

@Override
Expand Down