Skip to content

Commit

Permalink
Raise human-readable error in case of incorrect usage of _on or _
Browse files Browse the repository at this point in the history
… special variables in expressions
  • Loading branch information
Mingun committed Nov 25, 2021
1 parent e854281 commit 6043d46
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
16 changes: 10 additions & 6 deletions shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import io.kaitai.struct.datatype.DataType
import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format._
import io.kaitai.struct.precompile.{EnumNotFoundError, FieldNotFoundError, TypeNotFoundError, TypeUndecidedError}
import io.kaitai.struct.precompile.{EnumNotFoundError, ExpressionError, FieldNotFoundError, InvalidVarContextError, TypeNotFoundError, TypeUndecidedError}
import io.kaitai.struct.translators.TypeProvider

class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends TypeProvider {
var nowClass = topClass

var _currentIteratorType: Option[DataType] = None
var _currentSwitchType: Option[DataType] = None
def currentIteratorType: DataType = _currentIteratorType.get
def currentSwitchType: DataType = _currentSwitchType.get

override def determineType(attrName: String): DataType = {
determineType(nowClass, attrName)
Expand All @@ -25,14 +23,20 @@ class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends
topClass.toDataType
case Identifier.PARENT =>
if (inClass.parentClass == UnknownClassSpec)
throw new RuntimeException(s"Unable to derive ${Identifier.PARENT} type in ${inClass.name.mkString("::")}")
throw new ExpressionError(s"Unable to derive '${Identifier.PARENT}' type in '${inClass.nameAsStr}'")
inClass.parentClass.toDataType
case Identifier.IO =>
KaitaiStreamType
case Identifier.ITERATOR =>
currentIteratorType
_currentIteratorType match {
case Some(value) => value
case None => throw new InvalidVarContextError(attrName, "repeat-until")
}
case Identifier.SWITCH_ON =>
currentSwitchType
_currentSwitchType match {
case Some(value) => value
case None => throw new InvalidVarContextError(attrName, "cases.<case>")
}
case Identifier.INDEX =>
CalcIntType
case Identifier.SIZEOF =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.kaitai.struct.format.ClassSpec
* Base class for all expression-related errors, not localized to a certain path
* in source file.
*/
sealed abstract class ExpressionError(msg: String) extends RuntimeException(msg)
sealed class ExpressionError(msg: String) extends RuntimeException(msg)
class TypeMismatchError(msg: String) extends ExpressionError(msg)
class TypeUndecidedError(msg: String) extends ExpressionError(msg)

Expand All @@ -21,6 +21,13 @@ class EnumNotFoundError(val name: String, val curClass: ClassSpec)
class MethodNotFoundError(val name: String, val dataType: DataType)
extends NotFoundError(s"don't know how to call method '$name' of object type '$dataType'")

/**
* @param id Name of a special context variable that can be used in expressions (see [[Identifier]])
* @param context Description of the context (name of property) in which variable can be used
*/
class InvalidVarContextError(val id: String, val context: String)
extends ExpressionError(s"Context variable '$id' is available only in the '$context' expressions")

/**
* Internal compiler logic error: should never happen, but at least we want to
* handle it gracefully if it's happening.
Expand Down

0 comments on commit 6043d46

Please sign in to comment.