-
Notifications
You must be signed in to change notification settings - Fork 200
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
Access to foreign types using :: syntax #275
Comments
I have the following KSY: meta:
id: fmt_oms_apl_error
endian: le
imports:
- ../fmt_oms_rec
seq:
[...]
- id: dyn_app_error
type: fmt_oms_rec::fmt_oms_apl_vdb
if: (not _io.eof) and (value == 0xF0) which results in the following Java-snippet: [...]
private void _read() {
if (!(_io().isEof())) {
this.value = this._io.readU1();
}
if ( ((!(_io().isEof())) && (value() == 240)) ) {
this.dynAppError = new FmtOmsRec.FmtOmsAplVdb(this._io);
}
}
[....]
private FmtOmsAplVdb dynAppError;
public FmtOmsAplVdb dynAppError() { return dynAppError; } As you can see, KS successfully compiles a type using |
Declarations and getters (they're called "readers" in the code) are done around here. As you can see, that in turn passes the torch to either kaitaiType2JavaTypePrim or kaitaiType2JavaTypeBoxed, which, in their turn, invoke Most likely for Java we could do that by replacing that with |
I've followed your suggestion and got this.dynAppError = new FmtOmsRec.FmtOmsAplVdb(this._io, this, _root); Notice the changed CTOR, which I guess is because the type is properly resolved and not opaque anymore. The problem is that because that type comes from another type, its CTOR looks like the following: public FmtOmsAplVdb(KaitaiStream _io, KaitaiStruct _parent, FmtOmsRec _root) {
case t: UserType =>
val addArgs = if (t.isOpaque) {
""
} else {
val parent = t.forcedParent match {
case Some(USER_TYPE_NO_PARENT) => "null"
case Some(fp) => translator.translate(fp)
case None => "this"
}
val addEndian = t.classSpec.get.meta.endian match {
case Some(InheritedEndian) => ", _is_le"
case _ => ""
}
s", $parent, _root$addEndian"
}
val addParams = Utils.join(t.args.map((a) => translator.translate(a)), ", ", ", ", "")
s"new ${types2class(t.name)}($io$addArgs$addParams)" What would be the proper behaviour, which CTOR should be used and how do I achieve that? To start things, I guess dealing with the invocation as if it was an opaque type again would be a good idea. But how do I check the context I have, that a type is used in some external KSY? I even thought of using |
I guess this part needs some adjustment as well. The first thing that comes to mind is that it would be probably the right way out would be to generate ctor invocation like that in this case: this.dynAppError = new FmtOmsRec.FmtOmsAplVdb(this._io, this); which would effectively make new However, things get slightly messier here, because one actually has to support more than 3 arg ctors here, i.e. for stuff like parameters and calculated endianness. This trip into a rabbit hole could be slightly more complicated than expected originally. As the very least, we'll need several new tests for that:
|
With your example CTOR invocation, I'm not sure how much time I can spend on this anymore. Is there any interest to get my two changes so far as PR? |
Yeah, and that things actually bothers me as well. The problem is that right now
Sure :) |
I would like to additionally mention something I just recognized in my use case, because I have 4 types in 2 KSY files currently using each other:
Breaks on compile time, but might be logically wrong and might get fixed, which most likely leads to something like the following, breaking on runtime, because
To solve the problem on runtime in
Maybe I'm missing some important discussion, but aren't Actually, I'm forwarding my logical root using I saw things like For backwards compatibility, one could create some |
I've added nested_types3 test that demonstrates and tests new syntax. Hopefully, it would work already for Java, JS, Python, Ruby, C++, and hopefully we'll get it working for the rest of the languages soon. @tschoening I'll try to reply tomorrow, sorry for it taking so long. |
Guten Tag Mikhail Yakshin,
am Freitag, 16. März 2018 um 03:38 schrieben Sie:
@tschoening I'll try to reply tomorrow, sorry for it taking so long.
No problem, take your time, at least I am not forced to wait for KS
enhancements on this topic currently.
Mit freundlichen Grüßen,
Thorsten Schöning
…--
Thorsten Schöning E-Mail: [email protected]
AM-SoFT IT-Systeme http://www.AM-SoFT.de/
Telefon...........05151- 9468- 55
Fax...............05151- 9468- 88
Mobil..............0178-8 9468- 04
AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow
|
Has this been addressed by the Kaitai team? |
@lrodri29 Yes, this should be implemented by now. This ticket is still pending a reply to Thorsten Schöning, so this is why it's still not closed. |
As it doesn't make sense to keep this issue open just because we're waiting for a reply to this comment by @ams-tschoening, which is off-topic in this issue, I transferred it into a new issue #770. Please continue the discussion there, if you want to comment on that topic. According to @GreyCat, this issue is resolved, so I'm closing it. |
For now we cannot access foreign types using :: syntax. It is bad:
1 We cannot access foreign types enums which makes us to lift enum definition into upper scope. This is needed for example when iterating and a specific enum value means end of iteration.
2 We cannot access foreign types members. It's the most critical when we cannot access subtypes of imported types.
So I propose to add a C++-like syntax to access types and enums of types.
The text was updated successfully, but these errors were encountered: