mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
Error in errors
- Parse error format produced by my intel laptop now. - Fix some off-by-one errors in error reporting.
This commit is contained in:
parent
c5f2361e6b
commit
08d9f789dc
3 changed files with 108 additions and 23 deletions
|
@ -61,7 +61,7 @@ public class Compilation {
|
||||||
}
|
}
|
||||||
|
|
||||||
GL20.glDeleteShader(handle);
|
GL20.glDeleteShader(handle);
|
||||||
return ShaderResult.failure(new FailedCompilation(shaderName, files, generatedSource.toString(), infoLog));
|
return ShaderResult.failure(new FailedCompilation(shaderName, files, generatedSource.toString(), source, infoLog));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableExtension(String ext) {
|
public void enableExtension(String ext) {
|
||||||
|
@ -80,7 +80,7 @@ public class Compilation {
|
||||||
|
|
||||||
private void appendHeader(SourceComponent component, String source) {
|
private void appendHeader(SourceComponent component, String source) {
|
||||||
if (component instanceof SourceFile file) {
|
if (component instanceof SourceFile file) {
|
||||||
int fileID = files.size();
|
int fileID = files.size() + 1;
|
||||||
|
|
||||||
files.add(file);
|
files.add(file);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.compile.core;
|
package com.jozufozu.flywheel.backend.compile.core;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -13,6 +15,7 @@ import com.jozufozu.flywheel.glsl.SourceFile;
|
||||||
import com.jozufozu.flywheel.glsl.SourceLines;
|
import com.jozufozu.flywheel.glsl.SourceLines;
|
||||||
import com.jozufozu.flywheel.glsl.error.ConsoleColors;
|
import com.jozufozu.flywheel.glsl.error.ConsoleColors;
|
||||||
import com.jozufozu.flywheel.glsl.error.ErrorBuilder;
|
import com.jozufozu.flywheel.glsl.error.ErrorBuilder;
|
||||||
|
import com.jozufozu.flywheel.glsl.error.ErrorLevel;
|
||||||
import com.jozufozu.flywheel.glsl.span.Span;
|
import com.jozufozu.flywheel.glsl.span.Span;
|
||||||
import com.jozufozu.flywheel.lib.util.StringUtil;
|
import com.jozufozu.flywheel.lib.util.StringUtil;
|
||||||
|
|
||||||
|
@ -20,16 +23,20 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class FailedCompilation {
|
public class FailedCompilation {
|
||||||
public static final ResourceLocation GENERATED_SOURCE_NAME = Flywheel.rl("generated_source");
|
public static final ResourceLocation GENERATED_SOURCE_NAME = Flywheel.rl("generated_source");
|
||||||
private static final Pattern ERROR_LINE = Pattern.compile("(\\d+)\\((\\d+)\\) : (.*)");
|
private static final Pattern PATTERN_ONE = Pattern.compile("(\\d+)\\((\\d+)\\) : (.*)");
|
||||||
|
private static final Pattern PATTERN_TWO = Pattern.compile("(\\w+): (\\d+):(\\d+):(?: '(.+?)' :)?(.*)");
|
||||||
private final List<SourceFile> files;
|
private final List<SourceFile> files;
|
||||||
private final SourceLines generatedSource;
|
private final SourceLines generatedSource;
|
||||||
private final String errorLog;
|
private final String errorLog;
|
||||||
private final String shaderName;
|
private final String shaderName;
|
||||||
|
// Unused, but handy for debugging.
|
||||||
|
private final String completeSource;
|
||||||
|
|
||||||
public FailedCompilation(String shaderName, List<SourceFile> files, String generatedSource, String errorLog) {
|
public FailedCompilation(String shaderName, List<SourceFile> files, String generatedSource, String completeSource, String errorLog) {
|
||||||
this.shaderName = shaderName;
|
this.shaderName = shaderName;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
this.generatedSource = new SourceLines(GENERATED_SOURCE_NAME, generatedSource);
|
this.generatedSource = new SourceLines(GENERATED_SOURCE_NAME, generatedSource);
|
||||||
|
this.completeSource = completeSource;
|
||||||
this.errorLog = errorLog;
|
this.errorLog = errorLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,26 +52,60 @@ public class FailedCompilation {
|
||||||
@NotNull
|
@NotNull
|
||||||
private Stream<ErrorBuilder> errorStream() {
|
private Stream<ErrorBuilder> errorStream() {
|
||||||
return errorLog.lines()
|
return errorLog.lines()
|
||||||
.map(this::interpretErrorLine);
|
.mapMulti(this::interpretLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ErrorBuilder interpretErrorLine(String s) {
|
private void interpretLine(String s, Consumer<ErrorBuilder> out) {
|
||||||
Matcher matcher = ERROR_LINE.matcher(s);
|
if (s.isEmpty()) {
|
||||||
|
return;
|
||||||
if (matcher.find()) {
|
}
|
||||||
int fileId = Integer.parseInt(matcher.group(1));
|
|
||||||
int lineNo = Integer.parseInt(matcher.group(2));
|
Matcher matcher;
|
||||||
var msg = StringUtil.trimPrefix(matcher.group(3), "error")
|
|
||||||
.stripLeading();
|
matcher = PATTERN_ONE.matcher(s);
|
||||||
|
if (matcher.find()) {
|
||||||
if (fileId == 0) {
|
out.accept(interpretPattern1(matcher));
|
||||||
return interpretGeneratedError(lineNo, msg);
|
return;
|
||||||
} else {
|
}
|
||||||
return interpretSourceError(fileId, lineNo, msg);
|
|
||||||
}
|
matcher = PATTERN_TWO.matcher(s);
|
||||||
|
if (matcher.find()) {
|
||||||
|
out.accept(interpretPattern2(matcher));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.accept(ErrorBuilder.create()
|
||||||
|
.error(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ErrorBuilder interpretPattern1(Matcher matcher) {
|
||||||
|
int fileId = Integer.parseInt(matcher.group(1));
|
||||||
|
int lineNo = Integer.parseInt(matcher.group(2));
|
||||||
|
var msg = StringUtil.trimPrefix(matcher.group(3), "error")
|
||||||
|
.stripLeading();
|
||||||
|
|
||||||
|
if (fileId == 0) {
|
||||||
|
return interpretGeneratedError(ErrorLevel.ERROR, lineNo, msg);
|
||||||
|
} else {
|
||||||
|
return interpretSourceError(fileId, lineNo, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ErrorBuilder interpretPattern2(Matcher matcher) {
|
||||||
|
var errorLevel = parseErrorLevel(matcher.group(1));
|
||||||
|
|
||||||
|
int fileId = Integer.parseInt(matcher.group(2));
|
||||||
|
int lineNo = Integer.parseInt(matcher.group(3)) - 1;
|
||||||
|
|
||||||
|
String span = matcher.group(4);
|
||||||
|
|
||||||
|
var msg = matcher.group(5).trim();
|
||||||
|
|
||||||
|
if (fileId == 0) {
|
||||||
|
return interpretGeneratedError(errorLevel, lineNo, msg);
|
||||||
|
} else {
|
||||||
|
return interpretWithSpan(errorLevel, fileId, lineNo, span, msg);
|
||||||
}
|
}
|
||||||
return ErrorBuilder.create()
|
|
||||||
.error(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ErrorBuilder interpretSourceError(int fileId, int lineNo, String msg) {
|
private ErrorBuilder interpretSourceError(int fileId, int lineNo, String msg) {
|
||||||
|
@ -77,11 +118,36 @@ public class FailedCompilation {
|
||||||
.pointAt(span, 1);
|
.pointAt(span, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ErrorBuilder interpretGeneratedError(int lineNo, String msg) {
|
private ErrorBuilder interpretWithSpan(ErrorLevel errorLevel, int fileId, int lineNo, String span, String msg) {
|
||||||
|
var sourceFile = files.get(fileId - 1);
|
||||||
|
|
||||||
|
Span errorSpan;
|
||||||
|
if (span != null) {
|
||||||
|
errorSpan = sourceFile.getLineSpanMatching(lineNo, span);
|
||||||
|
} else {
|
||||||
|
errorSpan = sourceFile.getLineSpanNoWhitespace(lineNo);
|
||||||
|
}
|
||||||
|
|
||||||
return ErrorBuilder.create()
|
return ErrorBuilder.create()
|
||||||
.error(msg)
|
.header(errorLevel, msg)
|
||||||
|
.pointAtFile(sourceFile)
|
||||||
|
.pointAt(errorSpan, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ErrorBuilder interpretGeneratedError(ErrorLevel errorLevel, int lineNo, String msg) {
|
||||||
|
return ErrorBuilder.create()
|
||||||
|
.header(errorLevel, msg)
|
||||||
.pointAtFile("[in generated source]")
|
.pointAtFile("[in generated source]")
|
||||||
.pointAtLine(generatedSource, lineNo, 1)
|
.pointAtLine(generatedSource, lineNo, 1)
|
||||||
.note("This generally indicates a bug in Flywheel, not your shader code.");
|
.note("This generally indicates a bug in Flywheel, not your shader code.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static ErrorLevel parseErrorLevel(String level) {
|
||||||
|
return switch (level.toLowerCase(Locale.ROOT)) {
|
||||||
|
case "error" -> ErrorLevel.ERROR;
|
||||||
|
case "warning", "warn" -> ErrorLevel.WARN;
|
||||||
|
default -> ErrorLevel.NOTE;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -144,6 +145,24 @@ public class SourceFile implements SourceComponent {
|
||||||
return new StringSpan(source, begin, end);
|
return new StringSpan(source, begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Span getLineSpanMatching(int line, @Nullable String match) {
|
||||||
|
if (match == null) {
|
||||||
|
return getLineSpanNoWhitespace(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
var spanBegin = source.lineString(line)
|
||||||
|
.indexOf(match);
|
||||||
|
|
||||||
|
if (spanBegin == -1) {
|
||||||
|
return getLineSpanNoWhitespace(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
int begin = source.lineStartIndex(line) + spanBegin;
|
||||||
|
int end = begin + match.length();
|
||||||
|
|
||||||
|
return new StringSpan(source, begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search this file and recursively search all imports to find a struct definition matching the given name.
|
* Search this file and recursively search all imports to find a struct definition matching the given name.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue