diff --git a/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java b/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java index 2fa63614..3c1c4d1f 100644 --- a/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java +++ b/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java @@ -296,6 +296,7 @@ public class JSweetTranspiler { compiler.attrParseOnly = true; compiler.verbose = false; compiler.genEndPos = true; + compiler.keepComments = true; log = Log.instance(context); diff --git a/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java b/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java index c8ddee7d..71a2cb37 100644 --- a/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java +++ b/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java @@ -54,6 +54,7 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Type.ArrayType; import com.sun.tools.javac.code.Type.MethodType; import com.sun.tools.javac.code.TypeTag; +import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCArrayAccess; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; @@ -461,6 +462,25 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { private boolean declareClassScope; + private void printDocComment(JCTree element, boolean indent) { + if (compilationUnit.docComments != null && compilationUnit.docComments.hasComment(element)) { + Comment comment = compilationUnit.docComments.getComment(element); + String[] lines = comment.getText().split("\n"); + if (indent) { + printIndent(); + } + print("/**").println(); + for (String line : lines) { + printIndent().print(" * ").print(line.trim()).print("\n"); + } + removeLastChar(); + println().printIndent().print(" ").print("*/\n"); + if (!indent) { + printIndent(); + } + } + } + @Override public void visitClassDef(JCClassDecl classdecl) { if (getParent() instanceof JCClassDecl) { @@ -474,6 +494,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { enumScope = false; boolean globals = JSweetConfig.GLOBALS_CLASS_NAME.equals(classdecl.name.toString()); if (!globals) { + printDocComment(classdecl, false); if (!globalModule) { print("export "); } @@ -680,6 +701,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { } boolean globals = JSweetConfig.GLOBALS_CLASS_NAME.equals(parent.name.toString()); + printDocComment(methodDecl, false); if (globals) { if (constructor) { report(methodDecl, methodDecl.name, JSweetProblem.GLOBAL_CONSTRUCTOR_DEF); @@ -856,6 +878,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { boolean globals = (parent instanceof JCClassDecl) && JSweetConfig.GLOBALS_CLASS_NAME.equals(((JCClassDecl) parent).name.toString()); + printDocComment(varDecl, false); if (!globals && parent instanceof JCClassDecl) { if (varDecl.mods.getFlags().contains(Modifier.PUBLIC)) { if (!interfaceScope) { @@ -1078,7 +1101,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { if (methSym != null) { Map vars = new HashMap<>(); Util.fillAllVariablesInScope(vars, getStack(), inv, getParent(JCMethodDecl.class)); - if(vars.containsKey(methSym.getSimpleName().toString())) { + if (vars.containsKey(methSym.getSimpleName().toString())) { report(inv, JSweetProblem.HIDDEN_INVOCATION, methSym.getSimpleName()); } } diff --git a/src/test/java/org/jsweet/test/transpiler/SyntaxTests.java b/src/test/java/org/jsweet/test/transpiler/SyntaxTests.java index 31d52ec6..42b2f8b6 100644 --- a/src/test/java/org/jsweet/test/transpiler/SyntaxTests.java +++ b/src/test/java/org/jsweet/test/transpiler/SyntaxTests.java @@ -18,15 +18,19 @@ package org.jsweet.test.transpiler; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.commons.io.FileUtils; import org.jsweet.transpiler.JSweetProblem; +import org.jsweet.transpiler.SourceFile; import org.jsweet.transpiler.util.EvaluationResult; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import source.syntax.AnnotationQualifiedNames; +import source.syntax.DocComments; import source.syntax.FinalVariables; import source.syntax.FinalVariablesRuntime; import source.syntax.GlobalsCastMethod; @@ -152,5 +156,21 @@ public class SyntaxTests extends AbstractTest { } , getSourceFile(GlobalsCastMethod.class)); } + @Test + public void testDocComments() { + SourceFile f = getSourceFile(DocComments.class); + transpile(logHandler -> { + assertEquals("There should be no errors", 0, logHandler.reportedProblems.size()); + try { + String generatedCode = FileUtils.readFileToString(f.getTsFile()); + assertTrue(generatedCode.contains("This is a test of comment.")); + assertTrue(generatedCode.contains("A method, which has some doc comment.")); + assertTrue(generatedCode.contains("This is a constant field.")); + } catch(Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } , f); + } } diff --git a/src/test/java/source/syntax/GlobalsInvocation.java b/src/test/java/source/syntax/GlobalsInvocation.java index 1a2c8e4b..32c82caf 100644 --- a/src/test/java/source/syntax/GlobalsInvocation.java +++ b/src/test/java/source/syntax/GlobalsInvocation.java @@ -35,7 +35,13 @@ public class GlobalsInvocation { } } +/** + * This is a doc comment to test comments. + */ class Globals { + /** + * A global method. + */ public static String toTitleCase(String str) { return string(str).replace(new RegExp("/\\w\\S*/g"), (tok, i) -> { jsweet.lang.String txt = string(tok);