j4ts/j4ts

Possibility to tune the translated TypeScript enumerated type

edouardmercier opened this issue · 1 comments

I'm using Jsweet 2.2.0-SNAPSHOT.

As explained in the documentation, at https://github.com/cincheo/jsweet/blob/master/doc/jsweet-language-specifications.md#enums, JSweet translates the Java enumerated type into a simple TypeScript enumerated type.

Since TypeScript now offers "String enums", https://www.typescriptlang.org/docs/handbook/enums.html, it would be nice to be able to customize the translation behavior.

In my case, I would like to translate the following Java type:

public enum MyEnum
{
  Value1,
  Value2
}

into

enum MyEnum
{
  Value1 = "Value1",
  Value2 = "Value2"
}

I managed to do the trick by using this quick and ugly Jsweet factory:

package my.project;

import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import org.jsweet.transpiler.JSweetContext;
import org.jsweet.transpiler.JSweetFactory;
import org.jsweet.transpiler.Java2TypeScriptTranslator;
import org.jsweet.transpiler.TranspilationHandler;
import org.jsweet.transpiler.extension.PrinterAdapter;
import org.jsweet.transpiler.util.AbstractTreePrinter;

public final class MyJSweetFactory
    extends JSweetFactory
{

  @Override
  public Java2TypeScriptTranslator createTranslator(PrinterAdapter adapter, TranspilationHandler transpilationHandler,
      JSweetContext context, JCCompilationUnit compilationUnit, boolean fillSourceMap)
  {
    // This introduces an ugly hack which enables to assign values to enumerated types
    return new Java2TypeScriptTranslator(adapter, transpilationHandler, context, compilationUnit, fillSourceMap)
    {

      private JCVariableDecl lastEnumJcVariableDecl;

      public AbstractTreePrinter print(String string)
      {
        if (string.equals(", ") && lastEnumJcVariableDecl != null)
        {
          return super.print(" = \"" + lastEnumJcVariableDecl.getName() + "\"" + string);
        }
        else
        {
          return super.print(string);
        }
      }

      @Override
      public AbstractTreePrinter print(JCTree tree)
      {
        if (tree instanceof JCTree.JCVariableDecl)
        {
          lastEnumJcVariableDecl = (JCVariableDecl) tree;
        }
        else
        {
          lastEnumJcVariableDecl = null;
        }
        return super.print(tree);
      }

    };
  }

}

I could not find a more elegant way since the Java2TypeScriptTranslator.visitClassDef(JCClassDecl classdecl) does not seem to offer the required granularity.

What do you think of this requirement? Do you think that there is a better way to achieved this?

Sorry, this was posted on the wrong place, the right post is at cincheo/jsweet#513.