Skip to content

Commit

Permalink
Merge pull request #267 from kaitai-io/fix-ks-opaque-types-incompat-w…
Browse files Browse the repository at this point in the history
…ith-imports

Fix `ks-opaque-types: true` and duplicate warnings if imports are used
  • Loading branch information
generalmimon authored Mar 7, 2024
2 parents d56a6ca + e2dc7f5 commit c24196b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 35 deletions.
44 changes: 16 additions & 28 deletions shared/src/main/scala/io/kaitai/struct/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,50 +31,38 @@ object Main {

/**
* Runs precompilation steps on every type in the given [[format.ClassSpecs]] collection,
* using provided configuration.
* using provided configuration. See individual precompile steps invocations for more
* in-depth description of what each step includes.
*
* @param specs [[format.ClassSpecs]] container with all types loaded into it
* @param config runtime configuration to be passed to precompile steps
* @return a list of compilation problems encountered during precompilation steps
*/
def precompile(specs: ClassSpecs, config: RuntimeConfig): Iterable[CompilationProblem] = {
specs.flatMap { case (_, classSpec) =>
precompile(specs, classSpec, config)
def precompile(specs: ClassSpecs, conf: RuntimeConfig): Iterable[CompilationProblem] = {
new MarkupClassNames(specs).run()
val resolveTypeProblems = specs.flatMap { case (_, topClass) =>
val config = updateConfigFromMeta(conf, topClass.meta)
new ResolveTypes(specs, topClass, config.opaqueTypes).run()
}
}

/**
* Does all precompiles steps on a single [[format.ClassSpec]] using provided configuration.
* See individual precompile steps invocations for more in-depth description of
* what each step includes.
*
* @param classSpecs [[format.ClassSpecs]] container with all types loaded into it
* @param topClass one top type to precompile
* @param conf runtime configuration to be passed to precompile steps
* @return a list of compilation problems encountered during precompilation steps
*/
def precompile(classSpecs: ClassSpecs, topClass: ClassSpec, conf: RuntimeConfig): Iterable[CompilationProblem] = {
val config = updateConfigFromMeta(conf, topClass.meta)

new MarkupClassNames(classSpecs).run()
val resolveTypeProblems = new ResolveTypes(classSpecs, config.opaqueTypes).run()

// For now, bail out early in case we have any type resolution problems
// TODO: try to recover and do some more passes even in face of these
if (resolveTypeProblems.nonEmpty) {
return resolveTypeProblems
}

new ParentTypes(classSpecs).run()
new SpecsValueTypeDerive(classSpecs).run()
new CalculateSeqSizes(classSpecs).run()
val typeValidatorProblems = new TypeValidator(classSpecs, topClass).run()
new ParentTypes(specs).run()
new SpecsValueTypeDerive(specs).run()
new CalculateSeqSizes(specs).run()
val typeValidatorProblems = new TypeValidator(specs).run()

// Warnings
val styleWarnings = new StyleCheckIds(classSpecs, topClass).run()
val encodingProblems = new CanonicalizeEncodingNames(classSpecs).run()
val styleWarnings = new StyleCheckIds(specs).run()
val encodingProblems = new CanonicalizeEncodingNames(specs).run()

topClass.parentClass = GenericStructClassSpec
specs.forEachTopLevel((_, spec) => {
spec.parentClass = GenericStructClassSpec
})

resolveTypeProblems ++ typeValidatorProblems ++ styleWarnings ++ encodingProblems
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import io.kaitai.struct.problems._
* A collection of methods that resolves user types and enum types, i.e.
* converts names into ClassSpec / EnumSpec references.
*/
class ResolveTypes(specs: ClassSpecs, opaqueTypes: Boolean) extends PrecompileStep {
override def run(): Iterable[CompilationProblem] = specs.mapRec(resolveUserTypes)
class ResolveTypes(specs: ClassSpecs, topClass: ClassSpec, opaqueTypes: Boolean) extends PrecompileStep {
override def run(): Iterable[CompilationProblem] =
topClass.mapRec(resolveUserTypes).map(problem => problem.localizedInType(topClass))

/**
* Resolves user types and enum types recursively starting from a certain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format._
import io.kaitai.struct.problems._

class StyleCheckIds(specs: ClassSpecs, topClass: ClassSpec) extends PrecompileStep {
val provider = new ClassTypeProvider(specs, topClass)
class StyleCheckIds(specs: ClassSpecs) extends PrecompileStep {
val provider = new ClassTypeProvider(specs, specs.firstSpec)

override def run(): Iterable[CompilationProblem] =
specs.mapRec(processType)
specs.mapTopLevel((_, typeSpec) => {
provider.topClass = typeSpec
typeSpec.mapRec(processType)
})

def processType(spec: ClassSpec): Iterable[CompilationProblem] = {
provider.nowClass = spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import scala.reflect.ClassTag
* @param specs bundle of class specifications (used only to find external references)
* @param topClass class to start check with
*/
class TypeValidator(specs: ClassSpecs, topClass: ClassSpec) extends PrecompileStep {
val provider = new ClassTypeProvider(specs, topClass)
class TypeValidator(specs: ClassSpecs) extends PrecompileStep {
val provider = new ClassTypeProvider(specs, specs.firstSpec)
val detector = new ExpressionValidator(provider)

/**
Expand Down

0 comments on commit c24196b

Please sign in to comment.