Skip to content

Commit

Permalink
JavaScriptSG: fix broken generation of enum literals
Browse files Browse the repository at this point in the history
Related to kaitai-io/kaitai_struct#1074

Until this commit, any generated JS test spec from a `.kst` file
containing an enum literal would have a syntax error because of lines
like `const ./Enum0 = require(...);`. It seems that this bug exists
since 66e75b3. In that commit, I tried
to fix the build error of KST translator due to the compiler API change
in kaitai-io/kaitai_struct_compiler@8007e0e#diff-6164bdf7b558cea6ff36b4a50508205a4569f8e98e398e77c4373679fceafffa.
In JavaScriptSG, I just passed the existing `importList` to
JavaScriptTranslator without thinking about the consequences (which were
exactly the illegal `const ./Enum0 = require(...);` lines). This should
now be fixed.
  • Loading branch information
generalmimon committed Sep 29, 2024
1 parent 7e77f5f commit 4c7f24a
Showing 1 changed file with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.kaitai.struct.testtranslator.specgenerators

import _root_.io.kaitai.struct.ClassTypeProvider
import _root_.io.kaitai.struct.{ClassTypeProvider, ImportList}
import _root_.io.kaitai.struct.datatype.{DataType, KSError}
import _root_.io.kaitai.struct.datatype.DataType.BytesType
import _root_.io.kaitai.struct.exprlang.Ast
Expand All @@ -10,7 +10,24 @@ import _root_.io.kaitai.struct.translators.JavaScriptTranslator

class JavaScriptSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGenerator(spec) {
val className = JavaScriptCompiler.type2class(spec.id)
val translator = new JavaScriptTranslator(provider, importList)
// JavaScriptTranslator accepts an ImportList so that if it translates an enum
// literal referencing an external enum (e.g. `external_spec::enum::label`),
// it can generate an import of the .ksy module in which the enum is defined.
// We don't pass our main `importList` and instead create a separate
// ImportList, because we don't want to output these imports at the top level.
// The reason is that they might refer to generated parsers that don't exist
// or contain syntax errors because of KSC bugs, and if a top-level
// `require()` fails, then the test spec "crashes" without the test framework
// having a clue what test it was).
//
// For now, we use `spec.extraImports` (i.e. the manually specified `imports`
// in the .kst spec) in runParse() instead, which we can output into the test
// body (which means that `require()` failures will be assigned correctly to
// the specific test). We cannot use `translatorImportList` there because it
// will still be empty at that point - some refactoring would be needed to use
// it instead of `spec.extraImports`.
val translatorImportList = new ImportList()
val translator = new JavaScriptTranslator(provider, translatorImportList)

importList.add("assert")

Expand All @@ -21,11 +38,12 @@ class JavaScriptSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGene
override def runParse(): Unit = {
importList.add("testHelper")

out.puts(s"testHelper('$className', 'src/${spec.data}', function(r, $className) {")
out.puts(s"testHelper('$className', 'src/${spec.data}', function(r, ${className}_) {")
out.inc
// TODO: replace `spec.extraImports` with `translatorImportList` (see comment above)
spec.extraImports.foreach { (entry) =>
val entryClass = JavaScriptCompiler.type2class(entry)
out.puts(s"var $entryClass = require('$entryClass').$entryClass;")
out.puts(s"var ${entryClass}_ = require('$entryClass');")
}
}

Expand Down

0 comments on commit 4c7f24a

Please sign in to comment.