mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-09 05:46:26 +01:00
1f484da50b
- Make ShaderSources return a LoadResult - Refactor SourceFile loading to do all parsing outside the ctor - Don't immediately swallow import errors, instead forward them - Change Span to reference SourceLines instead of SourceFile - Still WIP, but functional at this stage
156 lines
3.3 KiB
Java
156 lines
3.3 KiB
Java
package com.jozufozu.flywheel.glsl;
|
|
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.jozufozu.flywheel.glsl.span.CharPos;
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
import it.unimi.dsi.fastutil.ints.IntList;
|
|
import it.unimi.dsi.fastutil.ints.IntLists;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
|
|
public class SourceLines implements CharSequence {
|
|
|
|
private static final Pattern newLine = Pattern.compile("(\\r\\n|\\r|\\n)");
|
|
|
|
public final ResourceLocation name;
|
|
/**
|
|
* 0-indexed line to char pos mapping.
|
|
*/
|
|
private final IntList lineStarts;
|
|
|
|
/**
|
|
* 0-indexed line lookup
|
|
*/
|
|
private final ImmutableList<String> lines;
|
|
public final String raw;
|
|
|
|
public SourceLines(ResourceLocation name, String raw) {
|
|
this.name = name;
|
|
this.raw = raw;
|
|
this.lineStarts = createLineLookup(raw);
|
|
this.lines = getLines(raw, lineStarts);
|
|
}
|
|
|
|
public int count() {
|
|
return lines.size();
|
|
}
|
|
|
|
public String lineString(int lineNo) {
|
|
return lines.get(lineNo);
|
|
}
|
|
|
|
public int lineStartIndex(int lineNo) {
|
|
return lineStarts.getInt(lineNo);
|
|
}
|
|
|
|
public CharPos getCharPos(int charPos) {
|
|
int lineNo = 0;
|
|
for (; lineNo < lineStarts.size(); lineNo++) {
|
|
int ls = lineStarts.getInt(lineNo);
|
|
|
|
if (charPos < ls) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
lineNo -= 1;
|
|
|
|
int lineStart = lineStarts.getInt(lineNo);
|
|
|
|
return new CharPos(charPos, lineNo, charPos - lineStart);
|
|
}
|
|
|
|
public String printLinesWithNumbers() {
|
|
StringBuilder builder = new StringBuilder();
|
|
|
|
for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
|
|
builder.append(String.format("%1$4s: ", i + 1))
|
|
.append(lines.get(i))
|
|
.append('\n');
|
|
}
|
|
|
|
return builder.toString();
|
|
}
|
|
|
|
/**
|
|
* Scan the source for line breaks, recording the position of the first character of each line.
|
|
*/
|
|
private static IntList createLineLookup(String source) {
|
|
if (source.isEmpty()) {
|
|
return IntLists.emptyList();
|
|
}
|
|
|
|
IntList l = new IntArrayList();
|
|
l.add(0); // first line is always at position 0
|
|
|
|
Matcher matcher = newLine.matcher(source);
|
|
|
|
while (matcher.find()) {
|
|
l.add(matcher.end());
|
|
}
|
|
|
|
return l;
|
|
}
|
|
|
|
private static ImmutableList<String> getLines(String source, IntList lines) {
|
|
ImmutableList.Builder<String> builder = ImmutableList.builder();
|
|
|
|
for (int i = 1; i < lines.size(); i++) {
|
|
int start = lines.getInt(i - 1);
|
|
int end = lines.getInt(i);
|
|
|
|
builder.add(source.substring(start, end)
|
|
.stripTrailing());
|
|
}
|
|
|
|
return builder.build();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return raw;
|
|
}
|
|
|
|
@NotNull
|
|
@Override
|
|
public CharSequence subSequence(int start, int end) {
|
|
return raw.subSequence(start, end);
|
|
}
|
|
|
|
public char charAt(int i) {
|
|
return raw.charAt(i);
|
|
}
|
|
|
|
public int length() {
|
|
return raw.length();
|
|
}
|
|
|
|
public int lineStartCol(int spanLine) {
|
|
return 0;
|
|
}
|
|
|
|
public int lineWidth(int spanLine) {
|
|
return lines.get(spanLine)
|
|
.length();
|
|
}
|
|
|
|
public int lineStartColTrimmed(final int line) {
|
|
final var lineString = lineString(line);
|
|
final int end = lineString.length();
|
|
|
|
int col = 0;
|
|
while (col < end && Character.isWhitespace(charAt(col))) {
|
|
col++;
|
|
}
|
|
return col;
|
|
}
|
|
|
|
public int lineStartPosTrimmed(final int line) {
|
|
return lineStartIndex(line) + lineStartColTrimmed(line);
|
|
}
|
|
}
|