Skip to content

Commit

Permalink
Fix inconsistencies in defined vs. initialized "extra attrs"
Browse files Browse the repository at this point in the history
In particular, this commit fixes build errors of generated Java parsers
for these 5 tests:

- InstanceUserArray
- RepeatUntilCalcArrayType
- RepeatUntilSized
- SwitchRepeatExpr
- SwitchRepeatExprInvalid

The build error in all these parsers was caused by trying to initialize
a `_raw_*` field (like `this._raw_userEntries = new
ArrayList<byte[]>();`), which wasn't actually declared, though. This
inconsistency was possible because until now, we've had different code
deciding what fields to declare to code deciding what fields to
initialize. Since this commit, we're simply initializing all "extra
attrs" + the attribute itself (in case the attribute is repeated;
otherwise no init is needed), which avoids all discrepancies and also
results in simpler code.
  • Loading branch information
generalmimon committed Oct 15, 2023
1 parent ba40241 commit ae16dee
Show file tree
Hide file tree
Showing 15 changed files with 21 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,9 @@ class CSharpCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)

override def condIfFooter(expr: expr): Unit = fileFooter(null)

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit = {
importList.add("System.Collections.Generic")

if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = new List<byte[]>();")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new List<byte[]>();")
out.puts(s"${privateMemberName(id)} = new ${kaitaiType2NativeType(ArrayTypeInStream(dataType))}();")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,18 +619,9 @@ class CppCompiler(
outSrc.puts("}")
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit = {
importListHdr.addSystem("vector")

if (needRaw.level >= 1) {
outSrc.puts(s"${privateMemberName(RawIdentifier(id))} = ${newVector(CalcBytesType)};")
if (needRaw.hasIO) {
outSrc.puts(s"${privateMemberName(IoStorageIdentifier(RawIdentifier(id)))} = ${newVector(OwnedKaitaiStreamType)};")
}
}
if (needRaw.level >= 2) {
outSrc.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ${newVector(CalcBytesType)};")
}
outSrc.puts(s"${privateMemberName(id)} = ${newVector(dataType)};")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit = {
// slices don't have to be manually initialized in Go: the built-in append()
// function works even on `nil` slices (https://go.dev/tour/moretypes/15)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,8 @@ class JavaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = new ArrayList<byte[]>();")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new ArrayList<byte[]>();")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = new ${kaitaiType2JavaType(ArrayTypeInStream(dataType))}();")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts("{")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,8 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts("}")
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = [];")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = [];")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts("var i = 0;")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.kaitai.struct.languages

import io.kaitai.struct.{ClassTypeProvider, RuntimeConfig, Utils}
import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError, ValidationNotEqualError, NeedRaw}
import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError, ValidationNotEqualError}
import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format._
Expand Down Expand Up @@ -162,11 +162,7 @@ class LuaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts("end")
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = {}")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = {}")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit = {
out.puts(s"${privateMemberName(id)} = {}")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class NimCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
universalFooter
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit = {
// sequences don't have to be manually initialized in Nim - they're automatically initialized as
// empty sequences (see https://narimiran.github.io/nim-basics/#_result_variable)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.kaitai.struct.languages

import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.datatype.{CalcEndian, DataType, FixedEndian, InheritedEndian, KSError, NeedRaw, UndecidedEndiannessError}
import io.kaitai.struct.datatype.{CalcEndian, DataType, FixedEndian, InheritedEndian, KSError, UndecidedEndiannessError}
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format.{NoRepeat, RepeatEos, RepeatExpr, RepeatSpec, _}
import io.kaitai.struct.languages.components._
Expand Down Expand Up @@ -267,13 +267,8 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = [];")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = [];")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts("$i = 0;")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.kaitai.struct.languages

import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError, NeedRaw}
import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError}
import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.exprlang.Ast.expr
Expand Down Expand Up @@ -236,13 +236,8 @@ class PerlCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = [];")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = [];")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts(s"while (!$io->is_eof()) {")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,8 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = []")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = []")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts("i = 0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,8 @@ class RubyCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = []")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = []")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts("i = 0")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.kaitai.struct.languages

import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError, NeedRaw}
import io.kaitai.struct.datatype.{DataType, FixedEndian, InheritedEndian, KSError}
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format.{NoRepeat, RepeatEos, RepeatExpr, RepeatSpec, _}
import io.kaitai.struct.languages.components._
Expand Down Expand Up @@ -253,13 +253,8 @@ class RustCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.inc
}

override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = {
if (needRaw.level >= 1)
out.puts(s"${privateMemberName(RawIdentifier(id))} = vec!();")
if (needRaw.level >= 2)
out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = vec!();")
override def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit =
out.puts(s"${privateMemberName(id)} = vec!();")
}

override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = {
out.puts(s"while !$io.isEof() {")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ import io.kaitai.struct.format._
trait AllocateAndStoreIO extends ExtraAttrs {
def allocateIO(id: Identifier, rep: RepeatSpec): String

override def extraAttrForIO(id: Identifier, rep: RepeatSpec): List[AttrSpec] = {
val ioId = IoStorageIdentifier(id)
val ioType = rep match {
case NoRepeat => OwnedKaitaiStreamType
case _ => ArrayTypeInStream(OwnedKaitaiStreamType)
}
List(AttrSpec(List(), ioId, ioType))
}
override def extraAttrForIO(id: Identifier, rep: RepeatSpec): List[AttrSpec] =
List(AttrSpec(List(), IoStorageIdentifier(id), OwnedKaitaiStreamType, ConditionalSpec(None, rep)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ trait CommonReads extends LanguageCompiler {

def attrParse0(id: Identifier, attr: AttrLikeSpec, io: String, defEndian: Option[FixedEndian]): Unit = {
if (attr.cond.repeat != NoRepeat)
condRepeatCommonInit(id, attr.dataType, needRaw(attr.dataType))
(ExtraAttrs.forAttr(attr, this) ++ List(attr)).foreach(a => condRepeatInitAttr(a.id, a.dataType))
attr.cond.repeat match {
case RepeatEos =>
condRepeatEosHeader(id, io, attr.dataType)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.kaitai.struct.languages.components

import io.kaitai.struct.datatype.{DataType, Endianness, FixedEndian, InheritedEndian, NeedRaw}
import io.kaitai.struct.datatype.{DataType, Endianness, FixedEndian, InheritedEndian}
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format._
import io.kaitai.struct.translators.AbstractTranslator
Expand Down Expand Up @@ -131,7 +131,7 @@ abstract class LanguageCompiler(
def condIfHeader(expr: Ast.expr): Unit
def condIfFooter(expr: Ast.expr): Unit

def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit
def condRepeatInitAttr(id: Identifier, dataType: DataType): Unit

def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit
def condRepeatEosFooter: Unit
Expand Down

0 comments on commit ae16dee

Please sign in to comment.