All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
personthecat.catlib.linting.JelHighlighter Maven / Gradle / Ivy
Go to download
Utilities for serialization, commands, noise generation, IO, and some new data types.
package personthecat.catlib.linting;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.Nullable;
import xjs.comments.CommentStyle;
import xjs.jel.exception.JelException;
import xjs.jel.sequence.JelType;
import xjs.jel.sequence.Sequence;
import xjs.jel.serialization.sequence.Sequencer;
import xjs.serialization.Span;
import xjs.serialization.token.CommentToken;
import xjs.serialization.token.ContainerToken;
import xjs.serialization.token.ParsedToken;
import xjs.serialization.token.TokenType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
import net.minecraft.class_124;
import net.minecraft.class_2561;
import net.minecraft.class_2583;
import net.minecraft.class_2585;
import static personthecat.catlib.linting.SyntaxLinter.color;
import static personthecat.catlib.linting.SyntaxLinter.error;
import static personthecat.catlib.linting.SyntaxLinter.stc;
public class JelHighlighter implements SyntaxLinter.Highlighter {
public static final Object TODO_MARKER = new Object();
public static final Pattern TODO_PATTERN =
Pattern.compile("^\\s*todo\\s*:.*", Pattern.CASE_INSENSITIVE);
public static final Map DEFAULT_STYLE_MAP =
ImmutableMap.builder()
.put(JelType.KEY, color(class_124.field_1076))
.put(JelType.CALL, color(class_124.field_1054).method_10978(true))
.put(JelType.REFERENCE, color(class_124.field_1076))
.put(JelType.REFERENCE_EXPANSION, color(class_124.field_1076))
.put(JelType.FLAG, color(class_124.field_1065))
.put(JelType.IMPORT, color(class_124.field_1065))
.put(JelType.MATCH, color(class_124.field_1065))
.put(JelType.DELEGATE, color(class_124.field_1054))
.put(JelType.BOOLEAN, color(class_124.field_1065))
.put(JelType.INDEX, color(class_124.field_1075))
.put(JelType.NUMBER, color(class_124.field_1075))
.put(TokenType.NUMBER, color(class_124.field_1075))
.put(JelType.NULL, color(class_124.field_1061))
.put(TokenType.STRING, color(class_124.field_1060))
.put(JelType.STRING, color(class_124.field_1060))
.put(CommentStyle.BLOCK, color(class_124.field_1080).method_10978(true))
.put(CommentStyle.LINE, color(class_124.field_1080).method_10978(true))
.put(CommentStyle.HASH, color(class_124.field_1080).method_10978(true))
.put(CommentStyle.LINE_DOC, color(class_124.field_1060).method_10978(true))
.put(CommentStyle.MULTILINE_DOC, color(class_124.field_1060).method_10978(true))
.put(TODO_MARKER, color(class_124.field_1054).method_10978(true))
.build();
protected final Map styleMap;
public JelHighlighter() {
this(DEFAULT_STYLE_MAP);
}
public JelHighlighter(final Map styleMap) {
this.styleMap = styleMap;
}
@Override
public Instance get(final String text) {
try {
final Sequence> sequence = Sequencer.JEL.parse(text);
final List> spans = new ArrayList<>();
trueFlatten(spans, sequence);
return new JelHighlighterInstance(this.styleMap, spans, text);
} catch (final JelException e) {
return new ExceptionHighlighterInstance(e, text);
}
}
protected static void trueFlatten(final List> spans, final Sequence> sequence) {
for (final Span> flat : sequence.flatten()) {
if (flat instanceof ContainerToken container) {
trueFlatten(spans, container);
} else if (flat.type() != TokenType.BREAK && flat.length() > 0) {
spans.add(flat);
}
}
}
protected static void trueFlatten(final List> spans, final ContainerToken container) {
for (final Span> s : container.viewTokens()) {
if (s instanceof ContainerToken inner) {
trueFlatten(spans, inner);
} else if (s.type() != TokenType.BREAK && s.length() > 0) {
spans.add(s);
}
}
}
protected static Object trueType(final Span> span) {
if (span instanceof CommentToken c) {
if (TODO_PATTERN.matcher(c.parsed()).matches()) {
return TODO_MARKER;
}
return c.commentStyle();
} else if (span.type() == TokenType.WORD && span instanceof ParsedToken p) {
return switch (p.parsed()) {
case "true", "false" -> JelType.BOOLEAN;
case "null" -> JelType.NULL;
default -> TokenType.WORD;
};
}
return span.type();
}
public static class ExceptionHighlighterInstance implements Instance {
protected final JelException ex;
protected final List> spans;
protected final String text;
protected final String msg;
protected @Nullable Span> current;
protected int index;
protected ExceptionHighlighterInstance(final JelException ex, final String text) {
this.ex = ex;
this.spans = ex.getSpans().computeIfAbsent(null, k -> Collections.emptyList());
this.text = text;
this.msg = ex.getMessage() + "\n" + ex.getDetails();
this.next();
}
@Override
public void next() {
if (this.index < this.spans.size()) {
this.current = this.spans.get(this.index++);
} else {
this.current = null;
}
}
@Override
public boolean found() {
return this.current != null;
}
@Override
public int start() {
return Objects.requireNonNull(this.current).start();
}
@Override
public int end() {
return Objects.requireNonNull(this.current).end();
}
@Override
public class_2561 replacement() {
final Span> s = Objects.requireNonNull(this.current);
return stc(s.textOf(this.text)).method_27696(error(this.msg));
}
}
public static class JelHighlighterInstance implements Instance {
protected final Map styleMap;
protected final List> spans;
protected final String text;
protected @Nullable Span> current;
protected int index;
protected JelHighlighterInstance(
final Map styleMap,
final List> spans,
final String text) {
this.styleMap = styleMap;
this.spans = spans;
this.text = text;
this.next();
}
@Override
public void next() {
if (this.index < this.spans.size()) {
this.current = this.spans.get(this.index++);
} else {
this.current = null;
}
}
@Override
public boolean found() {
return this.current != null;
}
@Override
public int start() {
return Objects.requireNonNull(this.current).start();
}
@Override
public int end() {
return Objects.requireNonNull(this.current).end();
}
@Override
public class_2561 replacement() {
final Span> s = Objects.requireNonNull(this.current);
final class_2583 style = this.styleMap.get(trueType(s));
final class_2585 replacement = stc(s.textOf(this.text));
return style != null ? replacement.method_27696(style) : replacement;
}
}
}