diff --git a/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala b/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala index 0dee55827..daa72de96 100644 --- a/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala +++ b/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala @@ -4,7 +4,7 @@ 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, TypeNotFoundError, TypeUndecidedError} import io.kaitai.struct.translators.TypeProvider class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends TypeProvider { @@ -13,8 +13,6 @@ class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends 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) @@ -30,14 +28,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 ExpressionError(s"Context variable '$attrName' is available only in the 'repeat-until' attributes") + } case Identifier.SWITCH_ON => - currentSwitchType + _currentSwitchType match { + case Some(value) => value + case None => throw new ExpressionError(s"Context variable '$attrName' is available only in the 'cases.' expressions") + } case Identifier.INDEX => CalcIntType case Identifier.SIZEOF => diff --git a/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala b/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala index 1ac6035bb..3a5a9e6e3 100644 --- a/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala +++ b/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala @@ -8,7 +8,7 @@ import io.kaitai.struct.translators.MethodArgType * 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) class WrongMethodCall(val dataType: MethodArgType, val methodName: String, val expectedSigs: Iterable[String], val actualSig: String)