Skip to content

Commit

Permalink
Fix valid on unnamed fields (introduce Ast.expr.InternalName)
Browse files Browse the repository at this point in the history
  • Loading branch information
generalmimon committed Jun 17, 2022
1 parent 0a04070 commit e535b20
Show file tree
Hide file tree
Showing 26 changed files with 241 additions and 149 deletions.
20 changes: 20 additions & 0 deletions shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends
determineType(nowClass, attrName)
}

override def determineType(attrId: Identifier): DataType = {
determineType(nowClass, attrId)
}

override def determineType(inClass: ClassSpec, attrName: String): DataType = {
attrName match {
case Identifier.ROOT =>
Expand All @@ -42,6 +46,22 @@ class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends
}
}

override def determineType(inClass: ClassSpec, attrId: Identifier): DataType = {
attrId match {
case _: NumberedIdentifier =>
// only 'seq' fields can be unnamed (numbered)
inClass.seq.foreach { el =>
if (el.id == attrId)
return el.dataTypeComposite
}
case NamedIdentifier(name) => return determineType(inClass, name)
case InstanceIdentifier(name) => return determineType(inClass, name)
case SpecialIdentifier(name) => return determineType(inClass, name)
case _ => // do nothing
}
throw new FieldNotFoundError(attrId.humanReadable, inClass)
}

/**
* Attempts to resolve a member (seq attribute, parameter, instance) by given name.
* @param inClass type specification to search member in
Expand Down
4 changes: 4 additions & 0 deletions shared/src/main/scala/io/kaitai/struct/exprlang/Ast.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.kaitai.struct.exprlang

import io.kaitai.struct.format.Identifier

/**
* Loosely based on /pythonparse/shared/src/main/scala/pythonparse/
* from FastParse, Copyright (c) 2014 Li Haoyi ([email protected])
Expand Down Expand Up @@ -72,6 +74,8 @@ object Ast {
/** Represents `X[Y]`. */
case class Subscript(value: expr, idx: expr) extends expr
case class Name(id: identifier) extends expr
/** For internal use in the compiler. It cannot appear in an AST parsed from a user-supplied string. */
case class InternalName(id: Identifier) extends expr
case class List(elts: Seq[expr]) extends expr
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,25 +549,16 @@ class CSharpCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts("}")
}

def idToStr(id: Identifier): String = {
def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}
}

override def publicMemberName(id: Identifier): String = {
id match {
case SpecialIdentifier(name) => s"M${Utils.upperCamelCase(name)}"
case NamedIdentifier(name) => Utils.upperCamelCase(name)
case NumberedIdentifier(idx) => s"${NumberedIdentifier.TEMPLATE.capitalize}_$idx"
case InstanceIdentifier(name) => Utils.upperCamelCase(name)
case RawIdentifier(innerId) => s"M_Raw${publicMemberName(innerId)}"
}
}
override def publicMemberName(id: Identifier): String = CSharpCompiler.publicMemberName(id)

override def privateMemberName(id: Identifier): String = {
id match {
Expand Down Expand Up @@ -608,6 +599,15 @@ object CSharpCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new CSharpCompiler(tp, config)

def publicMemberName(id: Identifier): String =
id match {
case SpecialIdentifier(name) => s"M${Utils.upperCamelCase(name)}"
case NamedIdentifier(name) => Utils.upperCamelCase(name)
case NumberedIdentifier(idx) => s"${NumberedIdentifier.TEMPLATE.capitalize}_$idx"
case InstanceIdentifier(name) => Utils.upperCamelCase(name)
case RawIdentifier(innerId) => s"M_Raw${publicMemberName(innerId)}"
}

/**
* Determine .NET data type corresponding to a KS data type.
*
Expand Down
26 changes: 15 additions & 11 deletions shared/src/main/scala/io/kaitai/struct/languages/CppCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -956,20 +956,12 @@ class CppCompiler(
def nullFlagForName(ksName: Identifier) =
s"n_${idToStr(ksName)}"

override def idToStr(id: Identifier): String = {
id match {
case RawIdentifier(inner) => s"_raw_${idToStr(inner)}"
case IoStorageIdentifier(inner) => s"_io_${idToStr(inner)}"
case si: SpecialIdentifier => Utils.lowerUnderscoreCase(si.name)
case ni: NamedIdentifier => Utils.lowerUnderscoreCase(ni.name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case ni: InstanceIdentifier => Utils.lowerUnderscoreCase(ni.name)
}
}
override def idToStr(id: Identifier): String = CppCompiler.idToStr(id)

override def publicMemberName(id: Identifier): String = CppCompiler.publicMemberName(id)

override def privateMemberName(id: Identifier): String = s"m_${idToStr(id)}"

override def publicMemberName(id: Identifier): String = idToStr(id)

override def localTemporaryName(id: Identifier): String = s"_t_${idToStr(id)}"

Expand Down Expand Up @@ -1058,6 +1050,18 @@ object CppCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new CppCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => Utils.lowerUnderscoreCase(name)
case NamedIdentifier(name) => Utils.lowerUnderscoreCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerUnderscoreCase(name)
case RawIdentifier(inner) => s"_raw_${idToStr(inner)}"
case IoStorageIdentifier(inner) => s"_io_${idToStr(inner)}"
}

def publicMemberName(id: Identifier): String = idToStr(id)

override def kstructName = "kaitai::kstruct"
override def kstreamName = "kaitai::kstream"

Expand Down
44 changes: 22 additions & 22 deletions shared/src/main/scala/io/kaitai/struct/languages/GoCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -519,30 +519,11 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts(")")
}

def idToStr(id: Identifier): String = {
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.upperCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
case IoStorageIdentifier(innerId) => "_io_" + idToStr(innerId)
}
}
override def idToStr(id: Identifier): String = GoCompiler.idToStr(id)

override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"
override def publicMemberName(id: Identifier): String = GoCompiler.publicMemberName(id)

override def publicMemberName(id: Identifier): String = {
id match {
case IoIdentifier => "_IO"
case RootIdentifier => "_Root"
case ParentIdentifier => "_Parent"
case NamedIdentifier(name) => Utils.upperCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.upperCamelCase(name)
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
}
}
override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"

override def localTemporaryName(id: Identifier): String = s"_t_${idToStr(id)}"

Expand Down Expand Up @@ -583,6 +564,25 @@ object GoCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new GoCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.upperCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
case IoStorageIdentifier(innerId) => s"_io_${idToStr(innerId)}"
}

def publicMemberName(id: Identifier): String =
id match {
case IoIdentifier => "_IO"
case RootIdentifier => "_Root"
case ParentIdentifier => "_Parent"
case InstanceIdentifier(name) => Utils.upperCamelCase(name)
case _ => idToStr(id)
}

/**
* Determine Go data type corresponding to a KS data type.
*
Expand Down
25 changes: 14 additions & 11 deletions shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -718,19 +718,11 @@ class JavaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)

def value2Const(s: String) = Utils.upperUnderscoreCase(s)

def idToStr(id: Identifier): String = {
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
}
}
override def idToStr(id: Identifier): String = JavaCompiler.idToStr(id)

override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"
override def publicMemberName(id: Identifier) = JavaCompiler.publicMemberName(id)

override def publicMemberName(id: Identifier) = idToStr(id)
override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"

override def localTemporaryName(id: Identifier): String = s"_t_${idToStr(id)}"

Expand Down Expand Up @@ -763,6 +755,17 @@ object JavaCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new JavaCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}

def publicMemberName(id: Identifier) = idToStr(id)

def kaitaiType2JavaType(attrType: DataType): String = kaitaiType2JavaTypePrim(attrType)

def kaitaiType2JavaType(attrType: DataType, isNullable: Boolean): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,24 +555,11 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts("}")
}

def idToStr(id: Identifier): String = {
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => s"_m_${Utils.lowerCamelCase(name)}"
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
}
}
def idToStr(id: Identifier): String = JavaScriptCompiler.idToStr(id)

override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"
override def publicMemberName(id: Identifier) = JavaCompiler.publicMemberName(id)

override def publicMemberName(id: Identifier): String = {
id match {
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
}
}
override def privateMemberName(id: Identifier): String = s"this.${idToStr(id)}"

override def localTemporaryName(id: Identifier): String = s"_t_${idToStr(id)}"

Expand Down Expand Up @@ -619,6 +606,21 @@ object JavaScriptCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new JavaScriptCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => s"_m_${Utils.lowerCamelCase(name)}"
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}

def publicMemberName(id: Identifier): String =
id match {
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case _ => idToStr(id)
}

override def kstreamName: String = "KaitaiStream"

// FIXME: probably KaitaiStruct will emerge some day in JavaScript runtime, but for now it is unused
Expand Down
32 changes: 19 additions & 13 deletions shared/src/main/scala/io/kaitai/struct/languages/LuaCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -292,21 +292,12 @@ class LuaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts
}

override def idToStr(id: Identifier): String = id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => name
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => s"_m_$name"
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}
override def idToStr(id: Identifier): String = LuaCompiler.idToStr(id)

override def publicMemberName(id: Identifier): String = LuaCompiler.publicMemberName(id)

override def privateMemberName(id: Identifier): String =
s"self.${idToStr(id)}"
override def publicMemberName(id: Identifier): String = id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => name
case InstanceIdentifier(name) => name
case RawIdentifier(innerId) => s"_raw_${publicMemberName(innerId)}"
}
override def localTemporaryName(id: Identifier): String =
s"_t_${idToStr(id)}"

Expand Down Expand Up @@ -447,6 +438,21 @@ object LuaCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new LuaCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => name
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => s"_m_$name"
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}

def publicMemberName(id: Identifier): String =
id match {
case InstanceIdentifier(name) => name
case _ => idToStr(id)
}

override def kstructName: String = "KaitaiStruct"
override def kstreamName: String = "KaitaiStream"
override def ksErrorName(err: KSError): String = err.name
Expand Down
25 changes: 14 additions & 11 deletions shared/src/main/scala/io/kaitai/struct/languages/PHPCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,9 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)

def value2Const(label: String) = Utils.upperUnderscoreCase(label)

def idToStr(id: Identifier): String = {
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => "_raw_" + idToStr(innerId)
}
}
override def idToStr(id: Identifier): String = PHPCompiler.idToStr(id)

override def publicMemberName(id: Identifier) = PHPCompiler.publicMemberName(id)

override def privateMemberName(id: Identifier): String = {
id match {
Expand All @@ -445,8 +439,6 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
}
}

override def publicMemberName(id: Identifier) = idToStr(id)

override def localTemporaryName(id: Identifier): String = s"$$_t_${idToStr(id)}"

override def paramName(id: Identifier): String = s"$$${idToStr(id)}"
Expand Down Expand Up @@ -507,6 +499,17 @@ object PHPCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new PHPCompiler(tp, config)

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => Utils.lowerCamelCase(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => Utils.lowerCamelCase(name)
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
}

def publicMemberName(id: Identifier) = idToStr(id)

override def kstreamName: String = "\\Kaitai\\Struct\\Stream"

override def kstructName: String = "\\Kaitai\\Struct\\Struct"
Expand Down
Loading

0 comments on commit e535b20

Please sign in to comment.