-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CommonMethods: declarative specification of methods #269
Conversation
To begin with, I just have to make one technical remark: please resist the urge to write "nameless" commit messages like the one in 580e4bc. I mean the detail of the content is fine, but the problem is that it's missing the title line, so Git tools don't have a good way to display this. GitHub truncates it after the first line break (which means that I only get to see the beginning of your first bullet point), but my usual way of displaying the commit tree locally doesn't, which is arguably even worse: Needless to say, if you feel the urge to cram so many bullet points into one commit, it should've likely been multiple commits. But you probably know this ;) @GreyCat I strongly recommend you to check out https://cbea.ms/git-commit/#seven-rules. The relevant and the most important rule in my opinion is https://cbea.ms/git-commit/#separate - "Separate subject from body with a blank line". Another good rule is to keep the subject line short, ideally under 50 characters - https://cbea.ms/git-commit/#limit-50. I personally try to follow this, so I know very well that 50 characters is often not much for what I want to tell the world, so I often allow myself to go with 65 or so. Just like they recommend:
|
shared/src/main/scala/io/kaitai/struct/translators/CommonMethods.scala
Outdated
Show resolved
Hide resolved
shared/src/main/scala/io/kaitai/struct/translators/CommonMethods.scala
Outdated
Show resolved
Hide resolved
jvm/src/test/scala/io/kaitai/struct/translators/ExpressionValidator$Test.scala
Outdated
Show resolved
Hide resolved
jvm/src/test/scala/io/kaitai/struct/translators/ExpressionValidator$Test.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GreyCat Thanks for this improvement! The code looks good to me, but I haven't tested it - hopefully it works as expected 🤞
Hey, really appreciate you calling this out. Much to my shame, I was not really aware of this integration capabilities, nor I have ever pain attention to this. Will fix. |
|
||
case class MethodSig0( | ||
name: String, | ||
returnType: DataType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just noticed that returnType
is not used anywhere and the detectAttributeType
method still contains match cases like case "first" | "last" | "min" | "max" => Int1Type(false)
, I suppose the detectAttributeType
method is planned to be migrated to use these new method signatures (in this PR / later)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great observation! Yeah, that is the idea. Or at least that was the idea.
Now, though, the more I think about it, the more I understand how our story with all these checks/modularization went crazy and it's hard to untangle it:
- TypeProvider is keeping state of current parsing point for resolving fields out of "this" context, providing point in the tree, and keeping KS io.kaitai.struct.format constructs separate from io.kaitai.struct.exprlang. We can argue how bad it is that it's stateful, but for now I believe this is least of the concerns.
- TypeDetector existing by itself (and used in quite a few places, including CommonMethods) — but ideally this should be tied closely to a declarative method description like the one in CommonMethods, otherwise we have a lot of duplication and error stemming from that.
CommonMethods[T]
and other generic components that together make up a "translator" — but they for sure depend on TypeDetector (or do they?)ExpressionValidator
which follows "translator" pattern in spirit (by providingdef validate(v: Ast.expr): Unit
which throws exceptions), but not in letter (i.e. it doesn't inherit from AbstractTranslator or BaseTranslator, because their basic requirement is havingdef translate(v: Ast.expr): String
).- It still inherits
TypeDetector
. - It still inherits
CommonMethods[Unit]
. - In the hindsight, I see the idea of returning Unit and throwing exceptions as particularly bad — it should have been refactored as returning list of
CompilationProblem
or something like that, so we can accumulate those.
- It still inherits
TypeValidator
(which is a precompile step) traverses everything and then selectively invokedExpressionValidator
on expressions to both use it asTypeDetector
and dovalidate(...)
. This one also adds layer of exception catching wrappers (which are, in all fairness, done quite poorly) and do that translation from exceptions to CompilationProblem.
So, a lot of things to think of...
* Refactored CommonMethods to use declarative specification of methods, and build all checks for arguments quantity and types around that, equally for all the data types and implementations. * Introduced set of new case objects derived from `MethodArgType` to be able to embody expectations about argument types (e.g. `case _: IntType` will be represented as `IntArg`). * Introduced set of new `MethodSig` classes to be able to declaratively specify method signatures. * Added `ExpressionValidator$Test` that will test that functionality (as ExpressionValidator will be first in line, resuing CommonMethods functionality) * Added a few new exceptions to clearly communicate CommonMethods checks results (WrongMethodCall, MethodNotFoundErrorWithArg). * ExpressionValidator: fixed problem with validation of subscripts usage (and added relevant test to `ExpressionValidator$Test`). * Fixed `enum` warning -> `enumName` for Scala 3 compatibility.
c9dd0aa
to
df03ec7
Compare
Co-authored-by: Petr Pučil <[email protected]>
Co-authored-by: Petr Pučil <[email protected]>
…fied usage of Always
…069a708bd10cc5b4cc4e3ddf89f58289) Fixes [info] - expr_bytes_to_s_arg0 *** FAILED *** [info] expr_bytes_to_s_arg0.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got () [info] did not equal expr_bytes_to_s_arg0.ksy: /instances/bad/value: [info] error: to_s: expected 1 argument, got 0 (SimpleMatchers.scala:34) [info] - expr_bytes_to_s_arg2 *** FAILED *** [info] expr_bytes_to_s_arg2.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got (Str(foo), Str(bar)) [info] did not equal expr_bytes_to_s_arg2.ksy: /instances/bad/value: [info] error: to_s: expected 1 argument, got 2 (SimpleMatchers.scala:34) [info] - expr_bytes_to_s_type *** FAILED *** [info] expr_bytes_to_s_type.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got (IntNum(123)) [info] did not equal expr_bytes_to_s_type.ksy: /instances/bad/value: [info] error: to_s: argument #0: expected string literal, got IntNum(123) (SimpleMatchers.scala:34)
…069a708bd10cc5b4cc4e3ddf89f58289) Fixes [info] - expr_bytes_to_s_arg0 *** FAILED *** [info] expr_bytes_to_s_arg0.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got () [info] did not equal expr_bytes_to_s_arg0.ksy: /instances/bad/value: [info] error: to_s: expected 1 argument, got 0 (SimpleMatchers.scala:34) [info] - expr_bytes_to_s_arg2 *** FAILED *** [info] expr_bytes_to_s_arg2.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got (Str(foo), Str(bar)) [info] did not equal expr_bytes_to_s_arg2.ksy: /instances/bad/value: [info] error: to_s: expected 1 argument, got 2 (SimpleMatchers.scala:34) [info] - expr_bytes_to_s_type *** FAILED *** [info] expr_bytes_to_s_type.ksy: /instances/bad/value: [info] error: wrong arguments to method call `to_s` on byte array: expected (string), got (IntNum(123)) [info] did not equal expr_bytes_to_s_type.ksy: /instances/bad/value: [info] error: to_s: argument #0: expected string literal, got IntNum(123) (SimpleMatchers.scala:34)
MethodArgType
to be able to embody expectations about argument types (e.g.case _: IntType
will be represented asIntArg
).MethodSig
classes to be able to declaratively specify method signatures.ExpressionValidator$Test
that will test that functionality (as ExpressionValidator will be first in line, resuing CommonMethods functionality)ExpressionValidator$Test
).enum
warning ->enumName
for Scala 3 compatibility.