Skip to content

Commit

Permalink
Merge branch 'experiments' of https://github.com/Moderocky/Skript int…
Browse files Browse the repository at this point in the history
…o experiments
  • Loading branch information
Moderocky committed Apr 12, 2024
2 parents 6aec06e + aad6901 commit 705f6a6
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/main/java/ch/njol/skript/expressions/ExprValueWithin.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.UnparsedLiteral;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.ClassInfoReference;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
Expand Down Expand Up @@ -69,9 +70,8 @@ public class ExprValueWithin extends WrapperExpression<Object> {
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
boolean plural;
if (exprs[0] != null) {
UnparsedLiteral unparsedLiteral = (UnparsedLiteral) exprs[0].getSource();
String input = unparsedLiteral.getData();
plural = Utils.getEnglishPlural(input).getSecond();
Literal<ClassInfoReference> classInfoReference = (Literal<ClassInfoReference>) ClassInfoReference.wrap((Expression<ClassInfo<?>>) exprs[0]);
plural = classInfoReference.getSingle().isPlural().isTrue();
} else {
plural = parseResult.hasTag("s");
}
Expand Down
159 changes: 159 additions & 0 deletions src/main/java/ch/njol/skript/util/ClassInfoReference.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/**
* 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.util;

import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionList;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.UnparsedLiteral;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.lang.util.SimpleLiteral;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import java.util.Arrays;

/**
* A ClassInfoReference represents a specific reference to a classinfo including any derivable context
*/
public final class ClassInfoReference {

@Nullable
private static UnparsedLiteral getSourceUnparsedLiteral(Expression<?> expression) {
while (!(expression instanceof UnparsedLiteral)) {
Expression<?> nextEarliestExpression = expression.getSource();
if (nextEarliestExpression == expression) {
return null;
}
expression = nextEarliestExpression;
}
return (UnparsedLiteral) expression;
}

private static Kleenean determineIfPlural(Expression<ClassInfo<?>> classInfoExpression) {
UnparsedLiteral sourceUnparsedLiteral = getSourceUnparsedLiteral(classInfoExpression);
if (sourceUnparsedLiteral == null) {
return Kleenean.UNKNOWN;
}
String originalExpr = sourceUnparsedLiteral.getData();
boolean isPlural = Utils.getEnglishPlural(originalExpr).getSecond();
return Kleenean.get(isPlural);
}

/**
* Wraps a ClassInfo expression as a ClassInfoReference expression which will return ClassInfoReferences
* with as much derivable context as possible
* @param classInfoExpression the ClassInfo expression to wrap
* @return a wrapper ClassInfoReference expression
*/
@NonNull
public static Expression<ClassInfoReference> wrap(@NonNull Expression<ClassInfo<?>> classInfoExpression) {
if (classInfoExpression instanceof ExpressionList) {
ExpressionList<?> classInfoExpressionList = (ExpressionList<?>) classInfoExpression;
Expression<ClassInfoReference>[] wrappedExpressions = Arrays.stream(classInfoExpressionList.getExpressions())
.map(expression -> wrap((Expression<ClassInfo<?>>) expression))
.toArray(Expression[]::new);
return new ExpressionList<>(wrappedExpressions, ClassInfoReference.class, classInfoExpression.getAnd());
}
Kleenean isPlural = determineIfPlural(classInfoExpression);
if (classInfoExpression instanceof Literal) {
Literal<ClassInfo<?>> classInfoLiteral = (Literal<ClassInfo<?>>) classInfoExpression;
ClassInfo<?> classInfo = classInfoLiteral.getSingle();
return new SimpleLiteral<>(new ClassInfoReference(classInfo, isPlural), classInfoLiteral.isDefault());
}
return new SimpleExpression<ClassInfoReference>() {

@Override
@Nullable
protected ClassInfoReference[] get(Event event) {
if (classInfoExpression.isSingle()) {
ClassInfo<?> classInfo = classInfoExpression.getSingle(event);
if (classInfo == null) {
return new ClassInfoReference[0];
}
return new ClassInfoReference[] { new ClassInfoReference(classInfo, isPlural) };
}
return classInfoExpression.stream(event)
.map(ClassInfoReference::new)
.toArray(ClassInfoReference[]::new);
}

@Override
public boolean isSingle() {
return classInfoExpression.isSingle();
}

@Override
public Class<? extends ClassInfoReference> getReturnType() {
return ClassInfoReference.class;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
if (debug) {
return classInfoExpression.toString(event, true) + "(wrapped by " + getClass().getSimpleName() + ")";
}
return classInfoExpression.toString(event, false);
}

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
return classInfoExpression.init(expressions, matchedPattern, isDelayed, parseResult);
}
};
}

private Kleenean plural;
private ClassInfo<?> classInfo;

public ClassInfoReference(ClassInfo<?> classInfo) {
this(classInfo, Kleenean.UNKNOWN);
}

public ClassInfoReference(ClassInfo<?> classInfo, Kleenean plural) {
this.classInfo = classInfo;
this.plural = plural;
}

/**
* @return A Kleenean representing whether this classinfo reference was plural. Kleeanan.UNKNOWN represents
* a reference which did not have appropriate context available.
*/
public Kleenean isPlural() {
return plural;
}

public void setPlural(Kleenean plural) {
this.plural = plural;
}

public ClassInfo<?> getClassInfo() {
return classInfo;
}

public void setClassInfo(ClassInfo<?> classInfo) {
this.classInfo = classInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* 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 org.skriptlang.skript.test.tests.utils;

import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionList;
import ch.njol.skript.lang.ParseContext;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.ContextlessEvent;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.ClassInfoReference;
import ch.njol.skript.variables.Variables;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.NonNull;
import org.junit.Assert;
import org.junit.Test;


public class ClassInfoReferenceTest {

@NonNull
private Expression<ClassInfoReference> parseAndWrap(String expr) {
ParseResult parseResult = SkriptParser.parse(expr, "%classinfos%", SkriptParser.ALL_FLAGS, ParseContext.DEFAULT);
if (parseResult == null)
throw new IllegalStateException("Parsed expression " + expr + " is null");
return ClassInfoReference.wrap((Expression<ClassInfo<?>>) parseResult.exprs[0]);
}

@Test
public void testWrapper() {
ClassInfoReference reference = parseAndWrap("object").getSingle(null);
Assert.assertEquals(Object.class, reference.getClassInfo().getC());
Assert.assertTrue(reference.isPlural().isFalse());

reference = parseAndWrap("string").getSingle(null);
Assert.assertEquals(String.class, reference.getClassInfo().getC());
Assert.assertTrue(reference.isPlural().isFalse());

reference = parseAndWrap("players").getSingle(null);
Assert.assertEquals(Player.class, reference.getClassInfo().getC());
Assert.assertTrue(reference.isPlural().isTrue());

Event event = ContextlessEvent.get();
Variables.setVariable("classinfo", Classes.getExactClassInfo(Block.class), event, true);
reference = parseAndWrap("{_classinfo}").getSingle(event);
Assert.assertEquals(Block.class, reference.getClassInfo().getC());
Assert.assertTrue(reference.isPlural().isUnknown());

ExpressionList<ClassInfoReference> referenceList = (ExpressionList<ClassInfoReference>) parseAndWrap("blocks, player or entities");
Assert.assertFalse(referenceList.getAnd());
Expression<? extends ClassInfoReference>[] childExpressions = referenceList.getExpressions();

ClassInfoReference firstReference = childExpressions[0].getSingle(null);
Assert.assertEquals(Block.class, firstReference.getClassInfo().getC());
Assert.assertTrue(firstReference.isPlural().isTrue());

ClassInfoReference secondReference = childExpressions[1].getSingle(null);
Assert.assertEquals(Player.class, secondReference.getClassInfo().getC());
Assert.assertTrue(secondReference.isPlural().isFalse());

ClassInfoReference thirdReference = childExpressions[2].getSingle(null);
Assert.assertEquals(Entity.class, thirdReference.getClassInfo().getC());
Assert.assertTrue(thirdReference.isPlural().isTrue());

referenceList = (ExpressionList<ClassInfoReference>) parseAndWrap("{_block} and {_player}");
Assert.assertTrue(referenceList.getAnd());
childExpressions = referenceList.getExpressions();

event = ContextlessEvent.get();
Variables.setVariable("block", Classes.getExactClassInfo(Block.class), event, true);
Variables.setVariable("player", Classes.getExactClassInfo(Player.class), event, true);
firstReference = childExpressions[0].getSingle(event);
Assert.assertEquals(Block.class, firstReference.getClassInfo().getC());
Assert.assertTrue(firstReference.isPlural().isUnknown());

secondReference = childExpressions[1].getSingle(event);
Assert.assertEquals(Player.class, secondReference.getClassInfo().getC());
Assert.assertTrue(secondReference.isPlural().isUnknown());

}

}

0 comments on commit 705f6a6

Please sign in to comment.