Skip to content

Commit

Permalink
✨ Add advanced parsing and validation for data structures
Browse files Browse the repository at this point in the history
Introduce enhanced parsing and validation mechanisms for data structures, including support for nested structures and improved error handling. This refactor significantly simplifies the creation process by modularizing responsibilities into initialization, validation, and creation phases. It also improves debugging with detailed logs and enhances flexibility with better handling of sub-structures and generic types.
  • Loading branch information
ItsTheSky committed Jan 15, 2025
1 parent 5ee0a9d commit 19d5622
Show file tree
Hide file tree
Showing 10 changed files with 488 additions and 133 deletions.
4 changes: 4 additions & 0 deletions src/main/java/info/itsthesky/disky/api/ReflectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,8 @@ public static void removeElement(String clazz, String... fields) throws Exceptio
return null;
}
}

public static Class<?> getGenericType(Field field) {
return (Class<?>) ((java.lang.reflect.ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package info.itsthesky.disky.api.datastruct;

import ch.njol.skript.Skript;
import ch.njol.skript.config.Node;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.expressions.base.SectionExpression;
import ch.njol.skript.lang.Expression;
Expand All @@ -16,48 +17,31 @@

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class BaseDataStructElement<T, D extends DataStruct<T>> extends SectionExpression<T> {

protected EntryContainer container;
protected DataStructureFactory.DataStructureParseResult parseResult;

@Override
public boolean init(Expression<?>[] expressions, int pattern, Kleenean delayed,
public boolean init(Expression<?>[] givenExprs, int pattern, Kleenean delayed,
SkriptParser.ParseResult result, @Nullable SectionNode node,
@Nullable List<TriggerItem> triggerItems) {
final var validator = DataStructureFactory.createValidator(getDataStructClass());
container = validator.validate(node);

final var presentNodes = new ArrayList<String>();
if (container != null) {
for (final var entryData : validator.getEntryData()) {
if (container.hasEntry(entryData.getKey()))
presentNodes.add(entryData.getKey());
}
}

final var errorMessage = DataStructureFactory.preValidate(getDataStructClass(), presentNodes, container);
if (errorMessage != null) {
// DiSky.debug("--- Error while validating data structure: " + errorMessage);
// Skript.error(errorMessage);
// why skript? why don't you want my error message? ;-;
DiSkyRuntimeHandler.error(new IllegalStateException(errorMessage), node);
return false;
}

return container != null;
this.parseResult = DataStructureFactory.initDataStructure(getDataStructClass(), node);
return this.parseResult != null;
}

@Override
protected T @Nullable [] get(Event event) {
if (container == null)
if (parseResult == null)
return null;

try {
final var result = DataStructureFactory.createDataStructure(getDataStructClass(), container, event, null);
final var result = DataStructureFactory.createDataStructure(getDataStructClass(), parseResult, event, null);
return (T[]) new Object[] {result};
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,24 @@
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.entry.EntryContainer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class ChainDataStructElement<F, T, D extends DataStruct<T>>
extends SectionExpression<F> implements IAsyncGettableExpression<F> {

protected EntryContainer container;
protected DataStructureFactory.DataStructureParseResult parseResult;
protected Node node;

@Override
public boolean init(Expression<?>[] expressions,
int pattern,
Kleenean delayed,
SkriptParser.ParseResult result,
@Nullable SectionNode node,
public boolean init(Expression<?>[] givenExprs, int pattern, Kleenean delayed,
SkriptParser.ParseResult result, @Nullable SectionNode node,
@Nullable List<TriggerItem> triggerItems) {
this.node = getParser().getNode();

final var validator = DataStructureFactory.createValidator(getDataStructClass());
container = validator.validate(node);

return container != null;
this.parseResult = DataStructureFactory.initDataStructure(getDataStructClass(), node);
return this.parseResult != null;
}

@Override
Expand All @@ -46,17 +43,15 @@ public boolean init(Expression<?>[] expressions,

@Override
public F[] getAsync(Event event) {
if (container == null)
return null;

final var original = getOriginalInstance(event);
if (original == null)
return null;

try {
final var result = DataStructureFactory.createDataStructure(getDataStructClass(), container, event, original);
return (F[]) new Object[] {applyChanges(event, result)};
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | java.lang.reflect.InvocationTargetException e) {
final var result = DataStructureFactory.createDataStructure(getDataStructClass(), parseResult, event, null);
return (F[]) new Object[] {applyChanges(event, (T) result)};
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package info.itsthesky.disky.api.datastruct;

import info.itsthesky.disky.api.datastruct.base.DataStruct;

import javax.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

Expand All @@ -18,6 +21,14 @@
*/
boolean optional() default true;

/**
* Get the sub structure type, to use when parsing an array
* of structure for this field. Naturally, those structures, once
* built, must return the same type as the field type.
* @return The sub structure type
*/
Class<? extends DataStruct> subStructureType() default DataStruct.class;

//region Documentation

/**
Expand Down
Loading

0 comments on commit 19d5622

Please sign in to comment.