From ffc695dcfe2854ded55bfc3a72884eec3cf6fd33 Mon Sep 17 00:00:00 2001 From: Mingun Date: Thu, 25 Nov 2021 23:11:37 +0500 Subject: [PATCH] Raise human-readable error in case of incorrect usage of `_on` or `_` special variables in expressions --- .../io/kaitai/struct/ClassTypeProvider.scala | 16 ++++++++++------ .../io/kaitai/struct/precompile/Exceptions.scala | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala b/shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala index abed472ff..f06f2591a 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 { @@ -12,8 +12,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) @@ -29,14 +27,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 32411d9b4..3713d2e46 100644 --- a/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala +++ b/shared/src/main/scala/io/kaitai/struct/precompile/Exceptions.scala @@ -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)