From 639b2185ab3f00e83eeea9c19ad1eaa6b9f1de8f Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 8 May 2023 22:43:55 -0700 Subject: [PATCH] A lot to unwrap - 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 --- .../backend/compile/CullingCompiler.java | 11 +- .../flywheel/backend/compile/FlwPrograms.java | 30 ++- .../backend/compile/IndirectPrograms.java | 5 +- .../backend/compile/InstancingPrograms.java | 5 +- .../backend/compile/PipelineCompiler.java | 53 ++---- .../backend/compile/SourceChecks.java | 111 +++++------ .../compile/component/IndirectComponent.java | 3 +- .../component/MaterialAdapterComponent.java | 4 +- .../compile/component/UniformComponent.java | 3 +- .../compile/core/FailedCompilation.java | 6 +- .../backend/compile/core/ShaderCompiler.java | 25 ++- .../jozufozu/flywheel/glsl/LoadResult.java | 39 ++++ .../jozufozu/flywheel/glsl/ShaderSources.java | 12 +- .../jozufozu/flywheel/glsl/SourceFile.java | 174 ++++++++++-------- .../jozufozu/flywheel/glsl/SourceLines.java | 5 +- .../flywheel/glsl/error/ErrorBuilder.java | 16 +- .../flywheel/glsl/error/ErrorReporter.java | 2 +- .../jozufozu/flywheel/glsl/parse/Import.java | 12 +- .../flywheel/glsl/span/ErrorSpan.java | 8 +- .../com/jozufozu/flywheel/glsl/span/Span.java | 47 ++--- .../flywheel/glsl/span/StringSpan.java | 10 +- 21 files changed, 314 insertions(+), 267 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/glsl/LoadResult.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingCompiler.java index 480da512c..8af57d948 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingCompiler.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.backend.compile; +import java.util.List; + import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; @@ -24,7 +26,8 @@ public class CullingCompiler extends AbstractCompiler> { super(sources, keys); this.uniformComponent = uniformComponent; - pipelineCompute = sources.find(Files.INDIRECT_CULL); + pipelineCompute = sources.find(Files.INDIRECT_CULL) + .unwrap(); } @Nullable @@ -40,9 +43,11 @@ public class CullingCompiler extends AbstractCompiler> { return programLinker.link(compute); } - private ImmutableList getComputeComponents(InstanceType instanceType) { + private List getComputeComponents(InstanceType instanceType) { var instanceAssembly = new IndirectComponent(sources, instanceType); - var instance = sources.find(instanceType.instanceShader()); + ResourceLocation key = instanceType.instanceShader(); + var instance = sources.find(key) + .unwrap(); return ImmutableList.of(uniformComponent, instanceAssembly, instance, pipelineCompute); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java index e69dc803c..72b34e7b3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java @@ -5,9 +5,13 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.uniform.ShaderUniforms; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.glsl.ShaderSources; +import com.jozufozu.flywheel.glsl.generate.FnSignature; +import com.jozufozu.flywheel.glsl.generate.GlslExpr; import com.jozufozu.flywheel.lib.context.Contexts; +import com.jozufozu.flywheel.lib.material.MaterialIndices; import net.minecraft.server.packs.resources.ResourceManager; @@ -25,8 +29,30 @@ public class FlwPrograms { .toList()) .build(sources); - InstancingPrograms.reload(sources, pipelineKeys, uniformComponent); - IndirectPrograms.reload(sources, pipelineKeys, uniformComponent); + var vertexMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("vertex_material_adapter")) + .materialSources(MaterialIndices.getAllVertexShaders()) + .adapt(FnSignature.ofVoid("flw_materialVertex")) + .switchOn(GlslExpr.variable("_flw_materialVertexID")) + .build(sources); + + var fragmentMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("fragment_material_adapter")) + .materialSources(MaterialIndices.getAllFragmentShaders()) + .adapt(FnSignature.ofVoid("flw_materialFragment")) + .adapt(FnSignature.create() + .returnType("bool") + .name("flw_discardPredicate") + .arg("vec4", "color") + .build(), GlslExpr.literal(false)) + .adapt(FnSignature.create() + .returnType("vec4") + .name("flw_fogFilter") + .arg("vec4", "color") + .build(), GlslExpr.variable("color")) + .switchOn(GlslExpr.variable("_flw_materialFragmentID")) + .build(sources); + + InstancingPrograms.reload(sources, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent); + IndirectPrograms.reload(sources, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent); } private static ImmutableList createPipelineKeys() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java index 9030238cf..5921b7a2a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.glsl.ShaderSources; @@ -22,12 +23,12 @@ public class IndirectPrograms { this.culling = culling; } - public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent) { + public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent, MaterialAdapterComponent vertexMaterialComponent, MaterialAdapterComponent fragmentMaterialComponent) { if (instance != null) { instance.delete(); instance = null; } - var pipelineCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INDIRECT, uniformComponent); + var pipelineCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INDIRECT, vertexMaterialComponent, fragmentMaterialComponent, uniformComponent); var cullingCompiler = new CullingCompiler(sources, createCullingKeys(), uniformComponent); var pipelineResult = pipelineCompiler.compileAndReportErrors(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java index 544a031ec..ec4320a2d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.glsl.ShaderSources; @@ -20,12 +21,12 @@ public class InstancingPrograms { this.pipeline = pipeline; } - public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent) { + public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent, MaterialAdapterComponent vertexMaterialComponent, MaterialAdapterComponent fragmentMaterialComponent) { if (instance != null) { instance.delete(); instance = null; } - var instancingCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INSTANCED_ARRAYS, uniformComponent); + var instancingCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INSTANCED_ARRAYS, vertexMaterialComponent, fragmentMaterialComponent, uniformComponent); var result = instancingCompiler.compileAndReportErrors(); if (result != null) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java index bd9bb5c34..f03f399ad 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java @@ -1,9 +1,10 @@ package com.jozufozu.flywheel.backend.compile; +import java.util.List; + import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; -import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.gl.shader.GlProgram; @@ -11,9 +12,6 @@ import com.jozufozu.flywheel.gl.shader.ShaderType; import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.SourceFile; -import com.jozufozu.flywheel.glsl.generate.FnSignature; -import com.jozufozu.flywheel.glsl.generate.GlslExpr; -import com.jozufozu.flywheel.lib.material.MaterialIndices; public class PipelineCompiler extends AbstractCompiler { private final Pipeline pipeline; @@ -23,34 +21,17 @@ public class PipelineCompiler extends AbstractCompiler { private final SourceFile pipelineFragment; private final SourceFile pipelineVertex; - public PipelineCompiler(ShaderSources sources, ImmutableList keys, Pipeline pipeline, UniformComponent uniformComponent) { + public PipelineCompiler(ShaderSources sources, ImmutableList keys, Pipeline pipeline, MaterialAdapterComponent vertexMaterialComponent, MaterialAdapterComponent fragmentMaterialComponent, UniformComponent uniformComponent) { super(sources, keys); this.pipeline = pipeline; + this.vertexMaterialComponent = vertexMaterialComponent; + this.fragmentMaterialComponent = fragmentMaterialComponent; this.uniformComponent = uniformComponent; - vertexMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("vertex_material_adapter")) - .materialSources(MaterialIndices.getAllVertexShaders()) - .adapt(FnSignature.ofVoid("flw_materialVertex")) - .switchOn(GlslExpr.variable("_flw_materialVertexID")) - .build(sources); - fragmentMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("fragment_material_adapter")) - .materialSources(MaterialIndices.getAllFragmentShaders()) - .adapt(FnSignature.ofVoid("flw_materialFragment")) - .adapt(FnSignature.create() - .returnType("bool") - .name("flw_discardPredicate") - .arg("vec4", "color") - .build(), GlslExpr.literal(false)) - .adapt(FnSignature.create() - .returnType("vec4") - .name("flw_fogFilter") - .arg("vec4", "color") - .build(), GlslExpr.variable("color")) - .switchOn(GlslExpr.variable("_flw_materialFragmentID")) - .build(sources); - - pipelineFragment = sources.find(pipeline.fragmentShader()); - pipelineVertex = sources.find(pipeline.vertexShader()); + pipelineFragment = this.sources.find(pipeline.fragmentShader()) + .unwrap(); + pipelineVertex = this.sources.find(pipeline.vertexShader()) + .unwrap(); } @Nullable @@ -71,23 +52,27 @@ public class PipelineCompiler extends AbstractCompiler { return glProgram; } - private ImmutableList getVertexComponents(PipelineProgramKey key) { + private List getVertexComponents(PipelineProgramKey key) { var instanceAssembly = pipeline.assembler() .assemble(new Pipeline.InstanceAssemblerContext(sources, key.vertexType(), key.instanceType())); var layout = sources.find(key.vertexType() - .layoutShader()); + .layoutShader()) + .unwrap(); var instance = sources.find(key.instanceType() - .instanceShader()); + .instanceShader()) + .unwrap(); var context = sources.find(key.contextShader() - .vertexShader()); + .vertexShader()) + .unwrap(); return ImmutableList.of(uniformComponent, vertexMaterialComponent, instanceAssembly, layout, instance, context, pipelineVertex); } - private ImmutableList getFragmentComponents(PipelineProgramKey key) { + private List getFragmentComponents(PipelineProgramKey key) { var context = sources.find(key.contextShader() - .fragmentShader()); + .fragmentShader()) + .unwrap(); return ImmutableList.of(uniformComponent, fragmentMaterialComponent, context, pipelineFragment); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/SourceChecks.java b/src/main/java/com/jozufozu/flywheel/backend/compile/SourceChecks.java index 7d526fb01..25db26d25 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/SourceChecks.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/SourceChecks.java @@ -1,66 +1,55 @@ package com.jozufozu.flywheel.backend.compile; -import java.util.Optional; -import java.util.function.BiConsumer; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.ImmutableList; -import com.jozufozu.flywheel.glsl.SourceFile; -import com.jozufozu.flywheel.glsl.error.ErrorReporter; -import com.jozufozu.flywheel.glsl.parse.ShaderFunction; -import com.jozufozu.flywheel.glsl.parse.ShaderVariable; - // TODO: recycle to be invoked by the shader compiler public class SourceChecks { - public static final BiConsumer LAYOUT_VERTEX = checkFunctionArity("flw_layoutVertex", 0); - public static final BiConsumer INSTANCE_VERTEX = checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0); - public static final BiConsumer MATERIAL_VERTEX = checkFunctionArity("flw_materialVertex", 0); - public static final BiConsumer MATERIAL_FRAGMENT = checkFunctionArity("flw_materialFragment", 0); - public static final BiConsumer CONTEXT_VERTEX = checkFunctionArity("flw_contextVertex", 0); - public static final BiConsumer CONTEXT_FRAGMENT = checkFunctionArity("flw_contextFragment", 0).andThen(checkFunctionArity("flw_initFragment", 0)); - public static final BiConsumer PIPELINE = checkFunctionArity("main", 0); - - public static BiConsumer checkFunctionArity(String name, int arity) { - return (errorReporter, file) -> checkFunctionArity(errorReporter, file, name, arity); - } - - public static BiConsumer checkFunctionParameterTypeExists(String name, int arity, int param) { - return (errorReporter, file) -> { - var func = checkFunctionArity(errorReporter, file, name, arity); - - if (func == null) { - return; - } - - var maybeStruct = func.getParameterType(param) - .findStruct(); - - if (maybeStruct.isEmpty()) { - errorReporter.generateMissingStruct(file, func.getParameterType(param), "struct not defined"); - } - }; - } - - /** - * @return {@code null} if the function doesn't exist, or if the function has the wrong arity. - */ - @Nullable - private static ShaderFunction checkFunctionArity(ErrorReporter errorReporter, SourceFile file, String name, int arity) { - Optional maybeFunc = file.findFunction(name); - - if (maybeFunc.isEmpty()) { - errorReporter.generateMissingFunction(file, name, "\"" + name + "\" function not defined"); - return null; - } - - ShaderFunction func = maybeFunc.get(); - ImmutableList params = func.getParameters(); - if (params.size() != arity) { - errorReporter.generateFunctionArgumentCountError(name, arity, func.getArgs()); - return null; - } - - return func; - } + // public static final BiConsumer LAYOUT_VERTEX = checkFunctionArity("flw_layoutVertex", 0); + // public static final BiConsumer INSTANCE_VERTEX = checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0); + // public static final BiConsumer MATERIAL_VERTEX = checkFunctionArity("flw_materialVertex", 0); + // public static final BiConsumer MATERIAL_FRAGMENT = checkFunctionArity("flw_materialFragment", 0); + // public static final BiConsumer CONTEXT_VERTEX = checkFunctionArity("flw_contextVertex", 0); + // public static final BiConsumer CONTEXT_FRAGMENT = checkFunctionArity("flw_contextFragment", 0).andThen(checkFunctionArity("flw_initFragment", 0)); + // public static final BiConsumer PIPELINE = checkFunctionArity("main", 0); + // + // public static BiConsumer checkFunctionArity(String name, int arity) { + // return (errorReporter, file) -> checkFunctionArity(errorReporter, file, name, arity); + // } + // + // public static BiConsumer checkFunctionParameterTypeExists(String name, int arity, int param) { + // return (errorReporter, file) -> { + // var func = checkFunctionArity(errorReporter, file, name, arity); + // + // if (func == null) { + // return; + // } + // + // var maybeStruct = func.getParameterType(param) + // .findStruct(); + // + // if (maybeStruct.isEmpty()) { + // errorReporter.generateMissingStruct(file, func.getParameterType(param), "struct not defined"); + // } + // }; + // } + // + // /** + // * @return {@code null} if the function doesn't exist, or if the function has the wrong arity. + // */ + // @Nullable + // private static ShaderFunction checkFunctionArity(ErrorReporter errorReporter, SourceFile file, String name, int arity) { + // Optional maybeFunc = file.findFunction(name); + // + // if (maybeFunc.isEmpty()) { + // errorReporter.generateMissingFunction(file, name, "\"" + name + "\" function not defined"); + // return null; + // } + // + // ShaderFunction func = maybeFunc.get(); + // ImmutableList params = func.getParameters(); + // if (params.size() != arity) { + // errorReporter.generateFunctionArgumentCountError(name, arity, func.getArgs()); + // return null; + // } + // + // return func; + // } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java index ffa8cf829..881f22840 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java @@ -35,7 +35,8 @@ public class IndirectComponent implements SourceComponent { public IndirectComponent(ShaderSources sources, InstanceType instanceType) { this.layoutItems = instanceType.getLayout().layoutItems; - included = ImmutableList.of(sources.find(Pipelines.Files.UTIL_TYPES)); + included = ImmutableList.of(sources.find(Pipelines.Files.UTIL_TYPES) + .unwrap()); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/MaterialAdapterComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/MaterialAdapterComponent.java index e1ff329b0..7b9396900 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/MaterialAdapterComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/MaterialAdapterComponent.java @@ -13,6 +13,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.SourceComponent; +import com.jozufozu.flywheel.glsl.SourceFile; import com.jozufozu.flywheel.glsl.generate.FnSignature; import com.jozufozu.flywheel.glsl.generate.GlslBlock; import com.jozufozu.flywheel.glsl.generate.GlslBuilder; @@ -145,7 +146,8 @@ public class MaterialAdapterComponent implements SourceComponent { int index = 0; for (var rl : materialSources) { - var sourceFile = sources.find(rl); + SourceFile sourceFile = sources.find(rl) + .unwrap(); final int finalIndex = index; var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex); transformed.add(new StringSubstitutionSourceComponent(sourceFile, adapterMap)); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java index af945263e..610cd2de6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java @@ -67,7 +67,8 @@ public class UniformComponent implements SourceComponent { var out = ImmutableList.builder(); for (var fileResolution : uniformShaders) { - out.add(sources.find(fileResolution)); + out.add(sources.find(fileResolution) + .unwrap()); } return new UniformComponent(name, out.build()); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/FailedCompilation.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/FailedCompilation.java index 0c42a1c9a..0ada67369 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/FailedCompilation.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/FailedCompilation.java @@ -8,6 +8,7 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; +import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.glsl.SourceFile; import com.jozufozu.flywheel.glsl.SourceLines; import com.jozufozu.flywheel.glsl.error.ErrorBuilder; @@ -15,7 +16,10 @@ import com.jozufozu.flywheel.glsl.span.Span; import com.jozufozu.flywheel.util.ConsoleColors; import com.jozufozu.flywheel.util.StringUtil; +import net.minecraft.resources.ResourceLocation; + public class FailedCompilation { + public static final ResourceLocation GENERATED_SOURCE_NAME = Flywheel.rl("generated_source"); private static final Pattern ERROR_LINE = Pattern.compile("(\\d+)\\((\\d+)\\) : (.*)"); private final List files; private final SourceLines generatedSource; @@ -25,7 +29,7 @@ public class FailedCompilation { public FailedCompilation(String shaderName, List files, String generatedSource, String errorLog) { this.shaderName = shaderName; this.files = files; - this.generatedSource = new SourceLines(generatedSource); + this.generatedSource = new SourceLines(GENERATED_SOURCE_NAME, generatedSource); this.errorLog = errorLog; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/ShaderCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/ShaderCompiler.java index 505f00a75..9cb6d8b45 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/ShaderCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/ShaderCompiler.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.compile.core; import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -10,7 +11,6 @@ import java.util.function.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.gl.shader.GlShader; import com.jozufozu.flywheel.gl.shader.ShaderType; import com.jozufozu.flywheel.glsl.GLSLVersion; @@ -29,7 +29,7 @@ public class ShaderCompiler { } @Nullable - public GlShader compile(GLSLVersion glslVersion, ShaderType shaderType, ImmutableList sourceComponents) { + public GlShader compile(GLSLVersion glslVersion, ShaderType shaderType, List sourceComponents) { var key = new ShaderKey(glslVersion, shaderType, sourceComponents); var cached = shaderCache.get(key); if (cached != null) { @@ -51,7 +51,7 @@ public class ShaderCompiler { } @NotNull - private ShaderResult compileUncached(Compilation ctx, ImmutableList sourceComponents) { + private ShaderResult compileUncached(Compilation ctx, List sourceComponents) { ctx.enableExtension("GL_ARB_explicit_attrib_location"); ctx.enableExtension("GL_ARB_conservative_depth"); @@ -60,14 +60,14 @@ public class ShaderCompiler { return ctx.compile(); } - private static void expand(ImmutableList rootSources, Consumer out) { - var included = new LinkedHashSet(); // use hash set to deduplicate. linked to preserve order - for (var component : rootSources) { - recursiveDepthFirstInclude(included, component); - included.add(component); - } - included.forEach(out); - } + private static void expand(List rootSources, Consumer out) { + var included = new LinkedHashSet(); // use hash set to deduplicate. linked to preserve order + for (var component : rootSources) { + recursiveDepthFirstInclude(included, component); + included.add(component); + } + included.forEach(out); + } private static void recursiveDepthFirstInclude(Set included, SourceComponent component) { for (var include : component.included()) { @@ -76,7 +76,6 @@ public class ShaderCompiler { included.addAll(component.included()); } - private record ShaderKey(GLSLVersion glslVersion, ShaderType shaderType, - ImmutableList sourceComponents) { + private record ShaderKey(GLSLVersion glslVersion, ShaderType shaderType, List sourceComponents) { } } diff --git a/src/main/java/com/jozufozu/flywheel/glsl/LoadResult.java b/src/main/java/com/jozufozu/flywheel/glsl/LoadResult.java new file mode 100644 index 000000000..58a5ae9b3 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/glsl/LoadResult.java @@ -0,0 +1,39 @@ +package com.jozufozu.flywheel.glsl; + +import java.io.IOException; +import java.util.List; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.resources.ResourceLocation; + +public sealed interface LoadResult { + static LoadResult success(SourceFile sourceFile) { + return new Success(sourceFile); + } + + @Nullable SourceFile unwrap(); + + record Success(SourceFile source) implements LoadResult { + @Override + @NotNull + public SourceFile unwrap() { + return source; + } + } + + record IOError(ResourceLocation location, IOException exception) implements LoadResult { + @Override + public SourceFile unwrap() { + return null; + } + } + + record IncludeError(ResourceLocation location, List innerFailures) implements LoadResult { + @Override + public SourceFile unwrap() { + return null; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java index 70ac5d2ac..88273d7d4 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java @@ -23,7 +23,7 @@ public class ShaderSources { private final ResourceManager manager; - private final Map cache = new HashMap<>(); + private final Map cache = new HashMap<>(); /** * Tracks where we are in the mutual recursion to detect circular imports. @@ -35,7 +35,7 @@ public class ShaderSources { } @Nonnull - public SourceFile find(ResourceLocation location) { + public LoadResult find(ResourceLocation location) { pushFindStack(location); // Can't use computeIfAbsent because mutual recursion causes ConcurrentModificationExceptions var out = cache.get(location); @@ -48,15 +48,15 @@ public class ShaderSources { } @Nonnull - private SourceFile load(ResourceLocation loc) { + private LoadResult load(ResourceLocation loc) { try { var resource = manager.getResource(ResourceUtil.prefixed(SHADER_DIR, loc)); var sourceString = StringUtil.readToString(resource.getInputStream()); - return new SourceFile(this, loc, sourceString); - } catch (IOException ioException) { - throw new ShaderLoadingException("Could not load shader " + loc, ioException); + return SourceFile.parse(this, loc, sourceString); + } catch (IOException e) { + return new LoadResult.IOError(loc, e); } } diff --git a/src/main/java/com/jozufozu/flywheel/glsl/SourceFile.java b/src/main/java/com/jozufozu/flywheel/glsl/SourceFile.java index 02a6fa537..f3a7de09c 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/SourceFile.java @@ -1,12 +1,17 @@ package com.jozufozu.flywheel.glsl; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.regex.Matcher; +import org.jetbrains.annotations.NotNull; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.glsl.parse.Import; @@ -29,8 +34,6 @@ import net.minecraft.resources.ResourceLocation; public class SourceFile implements SourceComponent { public final ResourceLocation name; - public final ShaderSources parent; - public final SourceLines source; /** @@ -51,30 +54,51 @@ public class SourceFile implements SourceComponent { public final List included; - public SourceFile(ShaderSources sourceFinder, ResourceLocation name, String source) { - this.parent = sourceFinder; + public final String finalSource; + + private SourceFile(ResourceLocation name, SourceLines source, ImmutableMap functions, ImmutableMap structs, ImmutableList imports, ImmutableMap fields, List included, String finalSource) { this.name = name; + this.source = source; + this.functions = functions; + this.structs = structs; + this.imports = imports; + this.fields = fields; + this.included = included; + this.finalSource = finalSource; + } - this.source = new SourceLines(source); + public static LoadResult parse(ShaderSources sourceFinder, ResourceLocation name, String stringSource) { + var source = new SourceLines(name, stringSource); - this.imports = parseImports(source); - this.functions = parseFunctions(source); - this.structs = parseStructs(source); - this.fields = parseFields(source); + var imports = parseImports(source); - this.included = imports.stream() - .map(i -> i.file) - .map(Span::toString) - .distinct() - .mapMulti((file, sink) -> { - try { - var loc = new ResourceLocation(file); - var sourceFile = sourceFinder.find(loc); - sink.accept(sourceFile); - } catch (Exception ignored) { - } - }) - .toList(); + List included = new ArrayList<>(); + List failures = new ArrayList<>(); + + Set seen = new HashSet<>(); + for (Import i : imports) { + var fileSpan = i.file(); + String string = fileSpan.toString(); + if (!seen.add(string)) { + continue; + } + var result = sourceFinder.find(new ResourceLocation(string)); + if (result instanceof LoadResult.Success s) { + included.add(s.unwrap()); + } else { + failures.add(result); + } + } + if (!failures.isEmpty()) { + return new LoadResult.IncludeError(name, failures); + } + + var functions = parseFunctions(source); + var structs = parseStructs(source); + var fields = parseFields(source); + + var finalSource = generateFinalSource(imports, source); + return LoadResult.success(new SourceFile(name, source, functions, structs, imports, fields, included, finalSource)); } @Override @@ -84,7 +108,26 @@ public class SourceFile implements SourceComponent { @Override public String source() { - return this.genFinalSource(); + return finalSource; + } + + @NotNull + private static String generateFinalSource(ImmutableList imports, SourceLines source) { + var out = new StringBuilder(); + + int lastEnd = 0; + + for (var include : imports) { + var loc = include.self(); + + out.append(source, lastEnd, loc.startIndex()); + + lastEnd = loc.endIndex(); + } + + out.append(source, lastEnd, source.length()); + + return out.toString(); } @Override @@ -96,7 +139,7 @@ public class SourceFile implements SourceComponent { int begin = source.lineStartIndex(lineNo); int end = begin + source.lineString(lineNo) .length(); - return new StringSpan(this, source.getCharPos(begin), source.getCharPos(end)); + return new StringSpan(source, begin, end); } public Span getLineSpanNoWhitespace(int line) { @@ -108,7 +151,7 @@ public class SourceFile implements SourceComponent { begin++; } - return new StringSpan(this, source.getCharPos(begin), source.getCharPos(end)); + return new StringSpan(source, begin, end); } /** @@ -157,32 +200,6 @@ public class SourceFile implements SourceComponent { return Optional.empty(); } - public CharSequence importStatement() { - return "#use " + '"' + name + '"'; - } - - public String printSource() { - return "Source for shader '" + name + "':\n" + source.printLinesWithNumbers(); - } - - private String genFinalSource() { - StringBuilder out = new StringBuilder(); - - int lastEnd = 0; - - for (var include : imports) { - var loc = include.self; - - out.append(this.source, lastEnd, loc.getStartPos()); - - lastEnd = loc.getEndPos(); - } - - out.append(this.source, lastEnd, this.source.length()); - - return out.toString(); - } - @Override public String toString() { return name.toString(); @@ -199,19 +216,18 @@ public class SourceFile implements SourceComponent { return System.identityHashCode(this); } - /** * Scan the source for {@code #use "..."} directives. * Records the contents of the directive into an {@link Import} object, and marks the directive for elision. */ - private ImmutableList parseImports(String source) { + private static ImmutableList parseImports(SourceLines source) { Matcher uses = Import.PATTERN.matcher(source); var imports = ImmutableList.builder(); while (uses.find()) { - Span use = Span.fromMatcher(this, uses); - Span file = Span.fromMatcher(this, uses, 1); + Span use = Span.fromMatcher(source, uses); + Span file = Span.fromMatcher(source, uses, 1); imports.add(new Import(use, file)); } @@ -219,19 +235,18 @@ public class SourceFile implements SourceComponent { return imports.build(); } - /** * Scan the source for function definitions and "parse" them into objects that contain properties of the function. */ - private ImmutableMap parseFunctions(String source) { + private static ImmutableMap parseFunctions(SourceLines source) { Matcher matcher = ShaderFunction.PATTERN.matcher(source); Map functions = new HashMap<>(); while (matcher.find()) { - Span type = Span.fromMatcher(this, matcher, 1); - Span name = Span.fromMatcher(this, matcher, 2); - Span args = Span.fromMatcher(this, matcher, 3); + Span type = Span.fromMatcher(source, matcher, 1); + Span name = Span.fromMatcher(source, matcher, 2); + Span args = Span.fromMatcher(source, matcher, 3); int blockStart = matcher.end(); int blockEnd = findEndOfBlock(source, blockStart); @@ -239,11 +254,11 @@ public class SourceFile implements SourceComponent { Span self; Span body; if (blockEnd > blockStart) { - self = new StringSpan(this, matcher.start(), blockEnd + 1); - body = new StringSpan(this, blockStart, blockEnd); + self = new StringSpan(source, matcher.start(), blockEnd + 1); + body = new StringSpan(source, blockStart, blockEnd); } else { - self = new ErrorSpan(this, matcher.start(), matcher.end()); - body = new ErrorSpan(this, blockStart); + self = new ErrorSpan(source, matcher.start(), matcher.end()); + body = new ErrorSpan(source, blockStart); } ShaderFunction function = new ShaderFunction(self, type, name, args, body); @@ -257,15 +272,15 @@ public class SourceFile implements SourceComponent { /** * Scan the source for function definitions and "parse" them into objects that contain properties of the function. */ - private ImmutableMap parseStructs(String source) { + private static ImmutableMap parseStructs(SourceLines source) { Matcher matcher = ShaderStruct.PATTERN.matcher(source); ImmutableMap.Builder structs = ImmutableMap.builder(); while (matcher.find()) { - Span self = Span.fromMatcher(this, matcher); - Span name = Span.fromMatcher(this, matcher, 1); - Span body = Span.fromMatcher(this, matcher, 2); - Span variableName = Span.fromMatcher(this, matcher, 3); + Span self = Span.fromMatcher(source, matcher); + Span name = Span.fromMatcher(source, matcher, 1); + Span body = Span.fromMatcher(source, matcher, 2); + Span variableName = Span.fromMatcher(source, matcher, 3); ShaderStruct shaderStruct = new ShaderStruct(self, name, body, variableName); @@ -278,16 +293,16 @@ public class SourceFile implements SourceComponent { /** * Scan the source for function definitions and "parse" them into objects that contain properties of the function. */ - private ImmutableMap parseFields(String source) { + private static ImmutableMap parseFields(SourceLines source) { Matcher matcher = ShaderField.PATTERN.matcher(source); ImmutableMap.Builder fields = ImmutableMap.builder(); while (matcher.find()) { - Span self = Span.fromMatcher(this, matcher); - Span location = Span.fromMatcher(this, matcher, 1); - Span decoration = Span.fromMatcher(this, matcher, 2); - Span type = Span.fromMatcher(this, matcher, 3); - Span name = Span.fromMatcher(this, matcher, 4); + Span self = Span.fromMatcher(source, matcher); + Span location = Span.fromMatcher(source, matcher, 1); + Span decoration = Span.fromMatcher(source, matcher, 2); + Span type = Span.fromMatcher(source, matcher, 3); + Span name = Span.fromMatcher(source, matcher, 4); fields.put(location.get(), new ShaderField(self, location, decoration, type, name)); } @@ -298,13 +313,16 @@ public class SourceFile implements SourceComponent { /** * Given the position of an opening brace, scans through the source for a paired closing brace. */ - private static int findEndOfBlock(String source, int start) { + private static int findEndOfBlock(CharSequence source, int start) { int blockDepth = 0; for (int i = start + 1; i < source.length(); i++) { char ch = source.charAt(i); - if (ch == '{') blockDepth++; - else if (ch == '}') blockDepth--; + if (ch == '{') { + blockDepth++; + } else if (ch == '}') { + blockDepth--; + } if (blockDepth < 0) { return i; diff --git a/src/main/java/com/jozufozu/flywheel/glsl/SourceLines.java b/src/main/java/com/jozufozu/flywheel/glsl/SourceLines.java index 926cfd432..d9613b915 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/SourceLines.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/SourceLines.java @@ -11,11 +11,13 @@ 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. */ @@ -27,7 +29,8 @@ public class SourceLines implements CharSequence { private final ImmutableList lines; public final String raw; - public SourceLines(String raw) { + public SourceLines(ResourceLocation name, String raw) { + this.name = name; this.raw = raw; this.lineStarts = createLineLookup(raw); this.lines = getLines(raw, lineStarts); diff --git a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorBuilder.java b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorBuilder.java index e75633c08..af609671b 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorBuilder.java @@ -59,6 +59,10 @@ public class ErrorBuilder { return pointAtFile(file.name.toString()); } + public ErrorBuilder pointAtFile(SourceLines source) { + return pointAtFile(source.name.toString()); + } + public ErrorBuilder pointAtFile(String file) { lines.add(new FileLine(file)); return this; @@ -69,13 +73,13 @@ public class ErrorBuilder { return this; } - SourceFile sourceFile = span.getSourceFile(); + var source = span.source(); - String builder = "add " + sourceFile.importStatement() + ' ' + msg + "\n defined here:"; + String builder = "add " + "#use " + '"' + source.name + '"' + ' ' + msg + "\n defined here:"; header(ErrorLevel.HINT, builder); - return this.pointAtFile(sourceFile) + return this.pointAtFile(source) .pointAt(span, 0); } @@ -85,12 +89,12 @@ public class ErrorBuilder { public ErrorBuilder pointAt(Span span, int ctxLines) { if (span.lines() == 1) { - SourceLines lines = span.getSourceFile().source; + SourceLines lines = span.source(); int spanLine = span.firstLine(); - int firstCol = span.getStart() + int firstCol = span.start() .col(); - int lastCol = span.getEnd() + int lastCol = span.end() .col(); pointAtLine(lines, spanLine, ctxLines, firstCol, lastCol); diff --git a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java index 7691a8efa..a73265797 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java @@ -62,7 +62,7 @@ public class ErrorReporter { } public ErrorBuilder generateSpanError(Span span, String message) { - SourceFile file = span.getSourceFile(); + var file = span.source(); return error(message).pointAtFile(file) .pointAt(span, 2); diff --git a/src/main/java/com/jozufozu/flywheel/glsl/parse/Import.java b/src/main/java/com/jozufozu/flywheel/glsl/parse/Import.java index e13e2e702..4ef2033ba 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/parse/Import.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/parse/Import.java @@ -4,16 +4,6 @@ import java.util.regex.Pattern; import com.jozufozu.flywheel.glsl.span.Span; -public class Import { - +public record Import(Span self, Span file) { public static final Pattern PATTERN = Pattern.compile("^\\s*#\\s*use\\s+\"(.*)\"", Pattern.MULTILINE); - - public final Span self; - public final Span file; - - public Import(Span self, Span file) { - this.self = self; - this.file = file; - } - } diff --git a/src/main/java/com/jozufozu/flywheel/glsl/span/ErrorSpan.java b/src/main/java/com/jozufozu/flywheel/glsl/span/ErrorSpan.java index 9fd40d290..3a34cc408 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/span/ErrorSpan.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/span/ErrorSpan.java @@ -1,20 +1,20 @@ package com.jozufozu.flywheel.glsl.span; -import com.jozufozu.flywheel.glsl.SourceFile; +import com.jozufozu.flywheel.glsl.SourceLines; /** * Represents a (syntactically) malformed segment of code. */ public class ErrorSpan extends Span { - public ErrorSpan(SourceFile in, int loc) { + public ErrorSpan(SourceLines in, int loc) { super(in, loc, loc); } - public ErrorSpan(SourceFile in, int start, int end) { + public ErrorSpan(SourceLines in, int start, int end) { super(in, start, end); } - public ErrorSpan(SourceFile in, CharPos start, CharPos end) { + public ErrorSpan(SourceLines in, CharPos start, CharPos end) { super(in, start, end); } diff --git a/src/main/java/com/jozufozu/flywheel/glsl/span/Span.java b/src/main/java/com/jozufozu/flywheel/glsl/span/Span.java index bf6a73d0c..5f13578c8 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/span/Span.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/span/Span.java @@ -1,13 +1,11 @@ package com.jozufozu.flywheel.glsl.span; -import java.util.Optional; import java.util.regex.Matcher; import org.jetbrains.annotations.NotNull; import com.jozufozu.flywheel.glsl.SourceFile; -import com.jozufozu.flywheel.glsl.parse.ShaderFunction; -import com.jozufozu.flywheel.glsl.parse.ShaderStruct; +import com.jozufozu.flywheel.glsl.SourceLines; /** * A segment of code in a {@link SourceFile}. @@ -17,16 +15,15 @@ import com.jozufozu.flywheel.glsl.parse.ShaderStruct; *

*/ public abstract class Span implements CharSequence, Comparable { - - protected final SourceFile in; + protected final SourceLines in; protected final CharPos start; protected final CharPos end; - public Span(SourceFile in, int start, int end) { - this(in, in.source.getCharPos(start), in.source.getCharPos(end)); + public Span(SourceLines in, int start, int end) { + this(in, in.getCharPos(start), in.getCharPos(end)); } - public Span(SourceFile in, CharPos start, CharPos end) { + public Span(SourceLines in, CharPos start, CharPos end) { this.in = in; this.start = start; this.end = end; @@ -35,29 +32,29 @@ public abstract class Span implements CharSequence, Comparable { /** * @return The file that contains this code segment. */ - public SourceFile getSourceFile() { + public SourceLines source() { return in; } - public CharPos getStart() { + public CharPos start() { return start; } - public CharPos getEnd() { + public CharPos end() { return end; } /** * @return the string index at the (inclusive) beginning of this code segment. */ - public int getStartPos() { + public int startIndex() { return start.pos(); } /** * @return the string index at the (exclusive) end of this code segment. */ - public int getEndPos() { + public int endIndex() { return end.pos(); } @@ -93,12 +90,12 @@ public abstract class Span implements CharSequence, Comparable { @Override public int length() { - return getEndPos() - getStartPos(); + return endIndex() - startIndex(); } @Override public char charAt(int index) { - return in.source.charAt(start.pos() + index); + return in.charAt(start.pos() + index); } @Override @@ -111,7 +108,7 @@ public abstract class Span implements CharSequence, Comparable { return get(); } - public static Span fromMatcher(SourceFile src, Matcher m, int group) { + public static Span fromMatcher(SourceLines src, Matcher m, int group) { return new StringSpan(src, m.start(group), m.end(group)); } @@ -119,7 +116,7 @@ public abstract class Span implements CharSequence, Comparable { return superSpan.subSpan(m.start(group), m.end(group)); } - public static Span fromMatcher(SourceFile src, Matcher m) { + public static Span fromMatcher(SourceLines src, Matcher m) { return new StringSpan(src, m.start(), m.end()); } @@ -127,22 +124,8 @@ public abstract class Span implements CharSequence, Comparable { return superSpan.subSpan(m.start(), m.end()); } - public Optional findStruct() { - if (isErr()) { - return Optional.empty(); - } - return in.findStructByName(this.toString()); - } - - public Optional findFunction() { - if (isErr()) { - return Optional.empty(); - } - return in.findFunction(this.toString()); - } - @Override public int compareTo(@NotNull Span o) { - return Integer.compareUnsigned(getStartPos(), o.getStartPos()); + return Integer.compareUnsigned(startIndex(), o.startIndex()); } } diff --git a/src/main/java/com/jozufozu/flywheel/glsl/span/StringSpan.java b/src/main/java/com/jozufozu/flywheel/glsl/span/StringSpan.java index 9d1835504..1ebc228be 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/span/StringSpan.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/span/StringSpan.java @@ -1,14 +1,10 @@ package com.jozufozu.flywheel.glsl.span; -import com.jozufozu.flywheel.glsl.SourceFile; +import com.jozufozu.flywheel.glsl.SourceLines; public class StringSpan extends Span { - public StringSpan(SourceFile in, int start, int end) { - super(in, start, end); - } - - public StringSpan(SourceFile in, CharPos start, CharPos end) { + public StringSpan(SourceLines in, int start, int end) { super(in, start, end); } @@ -19,7 +15,7 @@ public class StringSpan extends Span { @Override public String get() { - return in.source.raw.substring(start.pos(), end.pos()); + return in.raw.substring(start.pos(), end.pos()); } @Override