From 207089546e213d0f00a544da1a1ab5c5f7ce12f5 Mon Sep 17 00:00:00 2001 From: TUPUNCO Date: Fri, 8 Oct 2021 23:12:42 +0800 Subject: [PATCH 1/9] Add simple enumeration type code conversions - enum `body/args` to `code Comment` - enum `method-body` to `code Comment` - TODO: How do I add comments to the end of the `class code`? --- JavaToCSharp/CommentsHelper.cs | 34 +++++++ .../Declarations/EnumDeclarationVisitor.cs | 89 +++++++++++++++---- JavaToCSharp/JavaToCSharpConverter.cs | 9 ++ 3 files changed, 113 insertions(+), 19 deletions(-) diff --git a/JavaToCSharp/CommentsHelper.cs b/JavaToCSharp/CommentsHelper.cs index b70d3ad7..38d8f5f7 100644 --- a/JavaToCSharp/CommentsHelper.cs +++ b/JavaToCSharp/CommentsHelper.cs @@ -171,6 +171,40 @@ private static JavaAst.Node GetPreviousSibling(JavaAst.Node parentNode, JavaPars }); } + /// + /// Convert `JavaAst.Node` code to Comments + /// + /// + /// + /// + /// + public static IEnumerable ConvertToComment(IEnumerable codes, string tag, bool hasBlockMark = true) + { + var outputs = new List(); + foreach (var code in codes) + { + string[] input = code.ToString().Split(new[] { "\r\n" }, StringSplitOptions.None); + outputs.AddRange(input); + } + + if (outputs.Count > 0) + { + if (hasBlockMark) + { + yield return SyntaxFactory.Comment($"\r\n// --------------------"); + yield return SyntaxFactory.Comment($"// TODO {tag}"); + } + + foreach (var t in outputs) + { + yield return SyntaxFactory.Comment($"// {t}"); + } + + if (hasBlockMark) + yield return SyntaxFactory.Comment($"// --------------------\r\n"); + } + } + private static IEnumerable ConvertDocComment(JavaComments.Comment comment, string post) { string[] input = comment.getContent().Split(new[] { "\r\n" }, StringSplitOptions.None); diff --git a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs index 523764f8..e90c9dc5 100644 --- a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs +++ b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs @@ -1,8 +1,12 @@ -using com.github.javaparser.ast; +using System.Collections.Generic; +using System.Linq; + +using com.github.javaparser.ast; using com.github.javaparser.ast.body; + +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Linq; namespace JavaToCSharp.Declarations { @@ -10,33 +14,80 @@ public class EnumDeclarationVisitor : BodyDeclarationVisitor { public override MemberDeclarationSyntax VisitForClass(ConversionContext context, ClassDeclarationSyntax classSyntax, EnumDeclaration enumDecl) { - var name = enumDecl.getName(); + return VisitEnumDeclaration(context, enumDecl); + } + + public override MemberDeclarationSyntax VisitForInterface(ConversionContext context, InterfaceDeclarationSyntax interfaceSyntax, EnumDeclaration declaration) + { + return VisitForClass(context, null, declaration); + } - var members = enumDecl.getMembers().ToList(); + /// + /// + /// + /// + /// + /// + public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext context, EnumDeclaration javai) + { + var name = javai.getName(); + context.LastTypeName = name; - var entries = enumDecl.getEntries().ToList(); + var classSyntax = SyntaxFactory.EnumDeclaration(name); - if (members is {Count: > 0}) - context.Options.Warning("Members found in enum " + name + " will not be ported. Check for correctness.", enumDecl.getBegin().line); + var typeConstants = javai.getEntries().ToList(); + if (typeConstants is { Count: > 0 }) + { + var enumMembers = new List(typeConstants.Count); + foreach (var itemConst in typeConstants) + { + var memberDecl = SyntaxFactory.EnumMemberDeclaration(itemConst.getName()) + .WithJavaComments(itemConst); - var enumSyntax = SyntaxFactory.EnumDeclaration(name) - .AddMembers(entries.Select(entry => SyntaxFactory.EnumMemberDeclaration(entry.getName())).ToArray()); + //java-enum `body/args` to `code Comment` + var constArgs = itemConst.getArgs(); + var classBody = itemConst.getClassBody(); + if (!constArgs.isEmpty() || !classBody.isEmpty()) + { + var bodyCodes = CommentsHelper.ConvertToComment(new[] { itemConst }, "enum member body", false); + var firstLeadingTrivia = memberDecl.GetLeadingTrivia().Last(); + memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); + } - var mods = enumDecl.getModifiers(); + enumMembers.Add(memberDecl); + } + classSyntax = classSyntax.AddMembers(enumMembers.ToArray()); + } + var mods = javai.getModifiers(); if (mods.HasFlag(Modifier.PRIVATE)) - enumSyntax = enumSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); + classSyntax = classSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); if (mods.HasFlag(Modifier.PROTECTED)) - enumSyntax = enumSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)); + classSyntax = classSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)); if (mods.HasFlag(Modifier.PUBLIC)) - enumSyntax = enumSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); + classSyntax = classSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); - return enumSyntax; - } + var members = javai.getMembers().ToList(); + if (members is { Count: > 0 }) + { + //java-enum `method-body` to `code Comment` + var todoCodes = CommentsHelper.ConvertToComment(members, "enum body members"); + if (todoCodes != null) + { + var lastMember = classSyntax.Members.Last(); + var lastMemberTrailingTrivia = lastMember.GetTrailingTrivia(); + var lastMemberLeadingTrivia = lastMember.GetLeadingTrivia(); - public override MemberDeclarationSyntax VisitForInterface(ConversionContext context, InterfaceDeclarationSyntax interfaceSyntax, EnumDeclaration declaration) - { - return VisitForClass(context, null, declaration); + //TODO: How do I add comments to the end of the `class code`? + if (lastMemberTrailingTrivia.Count > 0) + classSyntax = classSyntax.InsertTriviaAfter(lastMemberTrailingTrivia.Last(), todoCodes); + else if (lastMemberLeadingTrivia.Count > 0) + classSyntax = classSyntax.InsertTriviaBefore(lastMemberLeadingTrivia.First(), todoCodes); + } + context.Options.Warning($"Members found in enum {name} will not be ported. Check for correctness.", javai.getBegin().line); + } + + return classSyntax.WithJavaComments(javai); } } -} +} \ No newline at end of file diff --git a/JavaToCSharp/JavaToCSharpConverter.cs b/JavaToCSharp/JavaToCSharpConverter.cs index 2e95504d..feace6d1 100644 --- a/JavaToCSharp/JavaToCSharpConverter.cs +++ b/JavaToCSharp/JavaToCSharpConverter.cs @@ -95,6 +95,15 @@ public static string ConvertText(string javaText, JavaConversionOptions options rootMembers.Add(classSyntax); } } + else if (type is EnumDeclaration enumType) + { + var classSyntax = EnumDeclarationVisitor.VisitEnumDeclaration(context, enumType); + + if (namespaceSyntax != null) + namespaceSyntax = namespaceSyntax.AddMembers(classSyntax); + else + rootMembers.Add(classSyntax); + } } if (namespaceSyntax != null) From 22422fdd61f1e20db786bdc0fc397eb11822c30d Mon Sep 17 00:00:00 2001 From: TUPUNCO Date: Sun, 17 Oct 2021 16:48:34 +0800 Subject: [PATCH 2/9] simple enumeration type code conversions: optimize `method-body to code-Comment` output - add comments to the end of the `class code` - fix `Incorrect indent for front whitespace` --- JavaToCSharp/CommentsHelper.cs | 19 ++++---- .../Declarations/EnumDeclarationVisitor.cs | 46 +++++++++++-------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/JavaToCSharp/CommentsHelper.cs b/JavaToCSharp/CommentsHelper.cs index 38d8f5f7..f90ff80b 100644 --- a/JavaToCSharp/CommentsHelper.cs +++ b/JavaToCSharp/CommentsHelper.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; + using JavaAst = com.github.javaparser.ast; using JavaComments = com.github.javaparser.ast.comments; using JavaParser = com.github.javaparser; @@ -120,7 +122,6 @@ private static (SyntaxKind kind, string pre, string post) GetCommentInfo(JavaCom } } - return result; } @@ -191,7 +192,8 @@ public static IEnumerable ConvertToComment(IEnumerable ConvertToComment(IEnumerable output, string tag, string t } break; + case "param": // label (id, label) = ParseByFirstWord(text); output.Add($"{label}"); break; + case "exception": // label (id, label) = ParseByFirstWord(text); output.Add($"{label}"); break; + default: output.Add($"<{tag}>{text}"); break; } - static (string id, string label) ParseByFirstWord(string text) { string id = text.Split()[0]; @@ -350,19 +354,18 @@ public static SyntaxNode FixCommentsWhitespaces(SyntaxNode node) return node; - static SyntaxNode InsertEmptyLineBeforeComment(SyntaxNode node) { /* For increased readability we change this - * + * * DoSomething(); * // Comment * DoSomethingElse(); - * + * * to this * * DoSomething(); - * + * * // Comment * DoSomethingElse(); */ diff --git a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs index e90c9dc5..00b805ba 100644 --- a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs +++ b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using com.github.javaparser.ast; using com.github.javaparser.ast.body; @@ -38,11 +37,14 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte var typeConstants = javai.getEntries().ToList(); if (typeConstants is { Count: > 0 }) { - var enumMembers = new List(typeConstants.Count); - foreach (var itemConst in typeConstants) + var membersCount = typeConstants.Count; + var enumMembers = new List(membersCount); + var lastMembersIndex = membersCount - 1; + for (int i = 0; i < membersCount; i++) { + var itemConst = typeConstants[i]; var memberDecl = SyntaxFactory.EnumMemberDeclaration(itemConst.getName()) - .WithJavaComments(itemConst); + .WithJavaComments(itemConst); //java-enum `body/args` to `code Comment` var constArgs = itemConst.getArgs(); @@ -54,6 +56,9 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); } + if (i == lastMembersIndex) + memberDecl = MembersToCommentTrivia(memberDecl); + enumMembers.Add(memberDecl); } classSyntax = classSyntax.AddMembers(enumMembers.ToArray()); @@ -67,27 +72,28 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte if (mods.HasFlag(Modifier.PUBLIC)) classSyntax = classSyntax.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); - var members = javai.getMembers().ToList(); - if (members is { Count: > 0 }) + return classSyntax.WithJavaComments(javai); + + EnumMemberDeclarationSyntax MembersToCommentTrivia(EnumMemberDeclarationSyntax lastMemberDecl) { //java-enum `method-body` to `code Comment` - var todoCodes = CommentsHelper.ConvertToComment(members, "enum body members"); - if (todoCodes != null) + var members = javai.getMembers().ToList(); + if (members is { Count: > 0 }) { - var lastMember = classSyntax.Members.Last(); - var lastMemberTrailingTrivia = lastMember.GetTrailingTrivia(); - var lastMemberLeadingTrivia = lastMember.GetLeadingTrivia(); - - //TODO: How do I add comments to the end of the `class code`? - if (lastMemberTrailingTrivia.Count > 0) - classSyntax = classSyntax.InsertTriviaAfter(lastMemberTrailingTrivia.Last(), todoCodes); - else if (lastMemberLeadingTrivia.Count > 0) - classSyntax = classSyntax.InsertTriviaBefore(lastMemberLeadingTrivia.First(), todoCodes); + var todoCodes = CommentsHelper.ConvertToComment(members, "enum body members"); + if (todoCodes != null) + { + var lastMemberTrailingTrivia = lastMemberDecl.GetTrailingTrivia(); + if (lastMemberTrailingTrivia.Count > 0) + lastMemberDecl = lastMemberDecl.InsertTriviaAfter(lastMemberTrailingTrivia.Last(), todoCodes); + else + lastMemberDecl = lastMemberDecl.WithTrailingTrivia(todoCodes); + } + context.Options.Warning($"Members found in enum {name} will not be ported. Check for correctness.", javai.getBegin().line); } - context.Options.Warning($"Members found in enum {name} will not be ported. Check for correctness.", javai.getBegin().line); - } - return classSyntax.WithJavaComments(javai); + return lastMemberDecl; + } } } } \ No newline at end of file From bb354f65aa31811ee398ff3eaa5a47b4c0580ea8 Mon Sep 17 00:00:00 2001 From: Tom Tang Date: Wed, 20 Oct 2021 01:52:11 +0800 Subject: [PATCH 3/9] New feature, batch mode command for cli. **First argument becomes a mode indicator.** - f mode: file to file convert. - d mode: folder to folder convert -> means get ting all *.java files for converting to *.cs. --- JavaToCSharpCli/Program.cs | 63 +++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/JavaToCSharpCli/Program.cs b/JavaToCSharpCli/Program.cs index 54f32a23..8c8308e4 100644 --- a/JavaToCSharpCli/Program.cs +++ b/JavaToCSharpCli/Program.cs @@ -8,28 +8,61 @@ public class Program { public static void Main(string[] args) { - if (args == null || args.Length < 2) - { - Console.WriteLine("Usage: JavaToCSharpCli.exe [pathToJavaFile] [pathToCsOutputFile]"); - return; - } + if (args == null || args.Length < 3) + ShowHelp(); + else + switch (args[0]) + { + case "-f": + ConvertToCSharpFile(args[1], args[2]); + break; + case "-d": + ConvertToCSharpDir(args[1], args[2]); + break; + default: + ShowHelp(); + break; + } + } - if (!File.Exists(args[0])) + private static void ConvertToCSharpDir(string folderPath, string outputFolderPath) + { + if (Directory.Exists(folderPath)) { - Console.WriteLine("Java input file doesn't exist!"); - return; + var input = new DirectoryInfo(folderPath); + var output = new DirectoryInfo(outputFolderPath); + foreach (var f in input.GetFiles("*.java", SearchOption.AllDirectories)) + ConvertToCSharpFile( + f.FullName, + Path.Combine(output.FullName, f.Name.Replace(f.Extension, ".cs"))); } + else + Console.WriteLine("Java input folder doesn't exist!"); + } - var javaText = File.ReadAllText(args[0]); + private static void ConvertToCSharpFile(string filePath, string outputFilePath) + { + if (File.Exists(filePath)) + { + var javaText = File.ReadAllText(filePath); + var options = new JavaConversionOptions(); - var options = new JavaConversionOptions(); + options.WarningEncountered += (sender, eventArgs) + => Console.WriteLine($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); - options.WarningEncountered += (sender, eventArgs) => Console.WriteLine($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); + var parsed = JavaToCSharpConverter.ConvertText(javaText, options); - var parsed = JavaToCSharpConverter.ConvertText(javaText, options); + File.WriteAllText(outputFilePath, parsed); + Console.WriteLine("Done!"); + } + else + Console.WriteLine("Java input file doesn't exist!"); + } - File.WriteAllText(args[1], parsed); - Console.WriteLine("Done!"); + private static void ShowHelp() + { + Console.WriteLine("Usage:\r\n\tJavaToCSharpCli.exe -f [pathToJavaFile] [pathToCsOutputFile]"); + Console.WriteLine("Usage:\tJavaToCSharpCli.exe -d [pathToJavaFolder] [pathToCsOutputFolder]"); } } -} +} \ No newline at end of file From b2d60f0ef7890f974ca3676473b1873430ce703f Mon Sep 17 00:00:00 2001 From: Tom Tang Date: Wed, 20 Oct 2021 02:18:48 +0800 Subject: [PATCH 4/9] Enhance error handling. - Prevent interrupt from single file was failed. - In folder mode, will skip when destination file was there already. --- JavaToCSharpCli/Program.cs | 67 ++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/JavaToCSharpCli/Program.cs b/JavaToCSharpCli/Program.cs index 8c8308e4..61db55e9 100644 --- a/JavaToCSharpCli/Program.cs +++ b/JavaToCSharpCli/Program.cs @@ -8,21 +8,28 @@ public class Program { public static void Main(string[] args) { - if (args == null || args.Length < 3) - ShowHelp(); - else - switch (args[0]) - { - case "-f": - ConvertToCSharpFile(args[1], args[2]); - break; - case "-d": - ConvertToCSharpDir(args[1], args[2]); - break; - default: - ShowHelp(); - break; - } + try + { + if (args == null || args.Length < 3) + ShowHelp(); + else + switch (args[0]) + { + case "-f": + ConvertToCSharpFile(args[1], args[2]); + break; + case "-d": + ConvertToCSharpDir(args[1], args[2]); + break; + default: + ShowHelp(); + break; + } + } + catch(Exception ex) + { + Console.WriteLine(ex); + } } private static void ConvertToCSharpDir(string folderPath, string outputFolderPath) @@ -34,26 +41,36 @@ private static void ConvertToCSharpDir(string folderPath, string outputFolderPat foreach (var f in input.GetFiles("*.java", SearchOption.AllDirectories)) ConvertToCSharpFile( f.FullName, - Path.Combine(output.FullName, f.Name.Replace(f.Extension, ".cs"))); + Path.Combine(output.FullName, f.Name.Replace(f.Extension, ".cs")), + false); } else Console.WriteLine("Java input folder doesn't exist!"); } - private static void ConvertToCSharpFile(string filePath, string outputFilePath) + private static void ConvertToCSharpFile(string filePath, string outputFilePath, bool overwrite = true) { - if (File.Exists(filePath)) + if (!overwrite && File.Exists(outputFilePath)) + Console.WriteLine($"[INFO] {outputFilePath} exists, skip to next."); + else if (File.Exists(filePath)) { - var javaText = File.ReadAllText(filePath); - var options = new JavaConversionOptions(); + try + { + var javaText = File.ReadAllText(filePath); + var options = new JavaConversionOptions(); - options.WarningEncountered += (sender, eventArgs) - => Console.WriteLine($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); + options.WarningEncountered += (sender, eventArgs) + => Console.WriteLine($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); - var parsed = JavaToCSharpConverter.ConvertText(javaText, options); + var parsed = JavaToCSharpConverter.ConvertText(javaText, options); - File.WriteAllText(outputFilePath, parsed); - Console.WriteLine("Done!"); + File.WriteAllText(outputFilePath, parsed); + Console.WriteLine($"{filePath} was done!"); + } + catch (Exception ex) + { + Console.WriteLine($"[ERROR] {filePath} was failed! err = " + ex); + } } else Console.WriteLine("Java input file doesn't exist!"); From 51ebf17ddeeca41a590e4e098cb77910a52b809d Mon Sep 17 00:00:00 2001 From: Tom Tang Date: Wed, 20 Oct 2021 02:30:33 +0800 Subject: [PATCH 5/9] Adopt *log4net* for logging. --- JavaToCSharpCli/JavaToCSharpCli.csproj | 8 +++ JavaToCSharpCli/Program.cs | 19 +++--- JavaToCSharpCli/log4net.config | 84 ++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 JavaToCSharpCli/log4net.config diff --git a/JavaToCSharpCli/JavaToCSharpCli.csproj b/JavaToCSharpCli/JavaToCSharpCli.csproj index 3b7851d7..17e63ce9 100644 --- a/JavaToCSharpCli/JavaToCSharpCli.csproj +++ b/JavaToCSharpCli/JavaToCSharpCli.csproj @@ -4,7 +4,15 @@ Exe net5.0 + + + + + + PreserveNewest + + \ No newline at end of file diff --git a/JavaToCSharpCli/Program.cs b/JavaToCSharpCli/Program.cs index 61db55e9..e3367b76 100644 --- a/JavaToCSharpCli/Program.cs +++ b/JavaToCSharpCli/Program.cs @@ -1,13 +1,18 @@ using System; using System.IO; using JavaToCSharp; +using log4net; +using log4net.Config; namespace JavaToCSharpCli { public class Program { + private static readonly ILog _logger = LogManager.GetLogger(typeof(Program)); public static void Main(string[] args) { + GlobalContext.Properties["appname"] = "JavaToCSharpCli"; + XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config")); try { if (args == null || args.Length < 3) @@ -28,7 +33,7 @@ public static void Main(string[] args) } catch(Exception ex) { - Console.WriteLine(ex); + _logger.Error(ex.Message, ex); } } @@ -45,13 +50,13 @@ private static void ConvertToCSharpDir(string folderPath, string outputFolderPat false); } else - Console.WriteLine("Java input folder doesn't exist!"); + _logger.Info("Java input folder doesn't exist!"); } private static void ConvertToCSharpFile(string filePath, string outputFilePath, bool overwrite = true) { if (!overwrite && File.Exists(outputFilePath)) - Console.WriteLine($"[INFO] {outputFilePath} exists, skip to next."); + _logger.Info($"{outputFilePath} exists, skip to next."); else if (File.Exists(filePath)) { try @@ -60,20 +65,20 @@ private static void ConvertToCSharpFile(string filePath, string outputFilePath, var options = new JavaConversionOptions(); options.WarningEncountered += (sender, eventArgs) - => Console.WriteLine($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); + => _logger.Warn($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); var parsed = JavaToCSharpConverter.ConvertText(javaText, options); File.WriteAllText(outputFilePath, parsed); - Console.WriteLine($"{filePath} was done!"); + _logger.Info($"{filePath} was done!"); } catch (Exception ex) { - Console.WriteLine($"[ERROR] {filePath} was failed! err = " + ex); + _logger.Error($"{filePath} was failed! err = " + ex.Message, ex); } } else - Console.WriteLine("Java input file doesn't exist!"); + _logger.Info("Java input file doesn't exist!"); } private static void ShowHelp() diff --git a/JavaToCSharpCli/log4net.config b/JavaToCSharpCli/log4net.config new file mode 100644 index 00000000..f89f2b39 --- /dev/null +++ b/JavaToCSharpCli/log4net.config @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 79cd45547c31f90d00bb24e7d7a417a970c15d44 Mon Sep 17 00:00:00 2001 From: TUPUNCO Date: Sun, 14 Nov 2021 16:01:55 +0800 Subject: [PATCH 6/9] add `UseUnrecognizedCodeToComment` options: default True --- .../Declarations/EnumDeclarationVisitor.cs | 46 +++++++++++-------- JavaToCSharp/JavaConversionOptions.cs | 8 +++- JavaToCSharpGui/App.config | 3 ++ .../Properties/Settings.Designer.cs | 12 +++++ JavaToCSharpGui/Properties/Settings.settings | 3 ++ JavaToCSharpGui/ViewModels/ShellViewModel.cs | 15 ++++++ JavaToCSharpGui/Views/ShellView.xaml | 1 + 7 files changed, 67 insertions(+), 21 deletions(-) diff --git a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs index 00b805ba..145f77aa 100644 --- a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs +++ b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs @@ -21,12 +21,6 @@ public override MemberDeclarationSyntax VisitForInterface(ConversionContext cont return VisitForClass(context, null, declaration); } - /// - /// - /// - /// - /// - /// public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext context, EnumDeclaration javai) { var name = javai.getName(); @@ -37,30 +31,42 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte var typeConstants = javai.getEntries().ToList(); if (typeConstants is { Count: > 0 }) { + var useCodeToComment = context.Options.UseUnrecognizedCodeToComment; var membersCount = typeConstants.Count; var enumMembers = new List(membersCount); var lastMembersIndex = membersCount - 1; + var showNoPortedWarning = false; for (int i = 0; i < membersCount; i++) { var itemConst = typeConstants[i]; var memberDecl = SyntaxFactory.EnumMemberDeclaration(itemConst.getName()) - .WithJavaComments(itemConst); + .WithJavaComments(itemConst); - //java-enum `body/args` to `code Comment` - var constArgs = itemConst.getArgs(); - var classBody = itemConst.getClassBody(); - if (!constArgs.isEmpty() || !classBody.isEmpty()) + if (useCodeToComment) { - var bodyCodes = CommentsHelper.ConvertToComment(new[] { itemConst }, "enum member body", false); - var firstLeadingTrivia = memberDecl.GetLeadingTrivia().Last(); - memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); - } + //java-enum `body/args` to `code Comment` + var constArgs = itemConst.getArgs(); + var classBody = itemConst.getClassBody(); + if (!constArgs.isEmpty() || !classBody.isEmpty()) + { + var bodyCodes = CommentsHelper.ConvertToComment(new[] { itemConst }, "enum member body", false); + var firstLeadingTrivia = memberDecl.GetLeadingTrivia().Last(); + memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); + + showNoPortedWarning = true; + } - if (i == lastMembersIndex) - memberDecl = MembersToCommentTrivia(memberDecl); + //java-enum `method-body` to `code Comment` + if (i == lastMembersIndex) + memberDecl = MembersToCommentTrivia(memberDecl, ref showNoPortedWarning); + } enumMembers.Add(memberDecl); } + + if (showNoPortedWarning) + context.Options.Warning($"Members found in enum {name} will not be ported. Check for correctness.", javai.getBegin().line); + classSyntax = classSyntax.AddMembers(enumMembers.ToArray()); } @@ -74,9 +80,8 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte return classSyntax.WithJavaComments(javai); - EnumMemberDeclarationSyntax MembersToCommentTrivia(EnumMemberDeclarationSyntax lastMemberDecl) + EnumMemberDeclarationSyntax MembersToCommentTrivia(EnumMemberDeclarationSyntax lastMemberDecl, ref bool showNoPortedWarning) { - //java-enum `method-body` to `code Comment` var members = javai.getMembers().ToList(); if (members is { Count: > 0 }) { @@ -88,8 +93,9 @@ EnumMemberDeclarationSyntax MembersToCommentTrivia(EnumMemberDeclarationSyntax l lastMemberDecl = lastMemberDecl.InsertTriviaAfter(lastMemberTrailingTrivia.Last(), todoCodes); else lastMemberDecl = lastMemberDecl.WithTrailingTrivia(todoCodes); + + showNoPortedWarning = true; } - context.Options.Warning($"Members found in enum {name} will not be ported. Check for correctness.", javai.getBegin().line); } return lastMemberDecl; diff --git a/JavaToCSharp/JavaConversionOptions.cs b/JavaToCSharp/JavaConversionOptions.cs index 11e3dd84..f29988be 100644 --- a/JavaToCSharp/JavaConversionOptions.cs +++ b/JavaToCSharp/JavaConversionOptions.cs @@ -10,6 +10,7 @@ public JavaConversionOptions() { IncludeNamespace = true; IncludeUsings = true; + UseUnrecognizedCodeToComment = true; } public event EventHandler WarningEncountered; @@ -32,6 +33,11 @@ public JavaConversionOptions() public bool UseDebugAssertForAsserts { get; set; } + /// + /// Unrecognized code is translated into comments + /// + public bool UseUnrecognizedCodeToComment { get; set; } + public ConversionState ConversionState { get; set; } public JavaConversionOptions AddPackageReplacement(string pattern, string replacement, RegexOptions options = RegexOptions.None) @@ -64,4 +70,4 @@ internal void ConversionStateChanged(ConversionState newState) StateChanged?.Invoke(this, new ConversionStateChangedEventArgs(newState)); } } -} +} \ No newline at end of file diff --git a/JavaToCSharpGui/App.config b/JavaToCSharpGui/App.config index 373cdd66..15a122ab 100644 --- a/JavaToCSharpGui/App.config +++ b/JavaToCSharpGui/App.config @@ -16,6 +16,9 @@ False + + True + diff --git a/JavaToCSharpGui/Properties/Settings.Designer.cs b/JavaToCSharpGui/Properties/Settings.Designer.cs index 50c4fb1c..9c70760e 100644 --- a/JavaToCSharpGui/Properties/Settings.Designer.cs +++ b/JavaToCSharpGui/Properties/Settings.Designer.cs @@ -58,5 +58,17 @@ public bool UseDebugAssertPreference { this["UseDebugAssertPreference"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool UseUnrecognizedCodeToComment { + get { + return ((bool)(this["UseUnrecognizedCodeToComment"])); + } + set { + this["UseUnrecognizedCodeToComment"] = value; + } + } } } diff --git a/JavaToCSharpGui/Properties/Settings.settings b/JavaToCSharpGui/Properties/Settings.settings index 11da0f53..f78589f4 100644 --- a/JavaToCSharpGui/Properties/Settings.settings +++ b/JavaToCSharpGui/Properties/Settings.settings @@ -11,5 +11,8 @@ False + + True + \ No newline at end of file diff --git a/JavaToCSharpGui/ViewModels/ShellViewModel.cs b/JavaToCSharpGui/ViewModels/ShellViewModel.cs index d50260b6..998a740e 100644 --- a/JavaToCSharpGui/ViewModels/ShellViewModel.cs +++ b/JavaToCSharpGui/ViewModels/ShellViewModel.cs @@ -30,6 +30,7 @@ public class ShellViewModel : Screen, IShell private bool _includeUsings = true; private bool _includeNamespace = true; private bool _useDebugAssertForAsserts; + private bool _useUnrecognizedCodeToComment; private bool _isConvertEnabled = true; #region UseFolder @@ -50,6 +51,7 @@ public ShellViewModel() _includeUsings = Properties.Settings.Default.UseUsingsPreference; _includeNamespace = Properties.Settings.Default.UseNamespacePreference; _useDebugAssertForAsserts = Properties.Settings.Default.UseDebugAssertPreference; + _useUnrecognizedCodeToComment = Properties.Settings.Default.UseUnrecognizedCodeToComment; } public ObservableCollection Usings { get; } = new(new JavaConversionOptions().Usings); @@ -156,6 +158,18 @@ public bool UseDebugAssertForAsserts } } + public bool UseUnrecognizedCodeToComment + { + get => _useUnrecognizedCodeToComment; + set + { + _useUnrecognizedCodeToComment = value; + NotifyOfPropertyChange(() => UseUnrecognizedCodeToComment); + Properties.Settings.Default.UseUnrecognizedCodeToComment = value; + Properties.Settings.Default.Save(); + } + } + public bool IsConvertEnabled { get => _isConvertEnabled; @@ -200,6 +214,7 @@ public void Convert() options.IncludeUsings = _includeUsings; options.IncludeNamespace = _includeNamespace; options.UseDebugAssertForAsserts = _useDebugAssertForAsserts; + options.UseUnrecognizedCodeToComment = _useUnrecognizedCodeToComment; options.WarningEncountered += Options_WarningEncountered; options.StateChanged += Options_StateChanged; diff --git a/JavaToCSharpGui/Views/ShellView.xaml b/JavaToCSharpGui/Views/ShellView.xaml index e7016468..8efa3fc5 100644 --- a/JavaToCSharpGui/Views/ShellView.xaml +++ b/JavaToCSharpGui/Views/ShellView.xaml @@ -68,6 +68,7 @@ Include Usings in Output Include Namespace in Output Use Debug.Assert() for asserts + Use Unrecognized Code To Comment Use Folder Convert From 48aa9d15cd6db02df6b352a71f02f53680eccd09 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 9 Mar 2022 14:06:49 -0700 Subject: [PATCH 7/9] Fix InvalidOperationException if no leading trivia in enum declaration --- JavaToCSharp/Declarations/EnumDeclarationVisitor.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs index 145f77aa..de24f4c2 100644 --- a/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs +++ b/JavaToCSharp/Declarations/EnumDeclarationVisitor.cs @@ -50,8 +50,16 @@ public static EnumDeclarationSyntax VisitEnumDeclaration(ConversionContext conte if (!constArgs.isEmpty() || !classBody.isEmpty()) { var bodyCodes = CommentsHelper.ConvertToComment(new[] { itemConst }, "enum member body", false); - var firstLeadingTrivia = memberDecl.GetLeadingTrivia().Last(); - memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); + + if (memberDecl.HasLeadingTrivia) + { + var firstLeadingTrivia = memberDecl.GetLeadingTrivia().Last(); + memberDecl = memberDecl.InsertTriviaAfter(firstLeadingTrivia, bodyCodes); + } + else + { + memberDecl = memberDecl.WithLeadingTrivia(bodyCodes); + } showNoPortedWarning = true; } From 8d1a00513f373c6254cc59e8a480c107bee8fef4 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 9 Mar 2022 14:36:04 -0700 Subject: [PATCH 8/9] Change log4net to use Microsoft.Extensions.Logging. --- JavaToCSharpCli/JavaToCSharpCli.csproj | 9 +-- JavaToCSharpCli/Program.cs | 38 +++++++----- JavaToCSharpCli/log4net.config | 84 -------------------------- 3 files changed, 25 insertions(+), 106 deletions(-) delete mode 100644 JavaToCSharpCli/log4net.config diff --git a/JavaToCSharpCli/JavaToCSharpCli.csproj b/JavaToCSharpCli/JavaToCSharpCli.csproj index 17e63ce9..78b860e0 100644 --- a/JavaToCSharpCli/JavaToCSharpCli.csproj +++ b/JavaToCSharpCli/JavaToCSharpCli.csproj @@ -1,18 +1,13 @@ - + 2.0.2 Exe net5.0 - + - - - PreserveNewest - - \ No newline at end of file diff --git a/JavaToCSharpCli/Program.cs b/JavaToCSharpCli/Program.cs index e3367b76..ea0f7668 100644 --- a/JavaToCSharpCli/Program.cs +++ b/JavaToCSharpCli/Program.cs @@ -1,18 +1,23 @@ using System; using System.IO; +using System.Threading; using JavaToCSharp; -using log4net; -using log4net.Config; +using Microsoft.Extensions.Logging; namespace JavaToCSharpCli { public class Program { - private static readonly ILog _logger = LogManager.GetLogger(typeof(Program)); + private static readonly ILogger _logger; + + static Program() + { + var loggerFactory = LoggerFactory.Create(builder => builder.AddSimpleConsole().SetMinimumLevel(LogLevel.Information)); + _logger = loggerFactory.CreateLogger(); + } + public static void Main(string[] args) { - GlobalContext.Properties["appname"] = "JavaToCSharpCli"; - XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config")); try { if (args == null || args.Length < 3) @@ -31,10 +36,13 @@ public static void Main(string[] args) break; } } - catch(Exception ex) + catch (Exception ex) { - _logger.Error(ex.Message, ex); + _logger.LogError(ex.Message, ex); } + + // allow logger background thread to flush + Thread.Sleep(TimeSpan.FromSeconds(1)); } private static void ConvertToCSharpDir(string folderPath, string outputFolderPath) @@ -46,17 +54,17 @@ private static void ConvertToCSharpDir(string folderPath, string outputFolderPat foreach (var f in input.GetFiles("*.java", SearchOption.AllDirectories)) ConvertToCSharpFile( f.FullName, - Path.Combine(output.FullName, f.Name.Replace(f.Extension, ".cs")), + Path.Combine(output.FullName, f.Name.Replace(f.Extension, ".cs")), false); } else - _logger.Info("Java input folder doesn't exist!"); + _logger.LogError("Java input folder {path} doesn't exist!", folderPath); } private static void ConvertToCSharpFile(string filePath, string outputFilePath, bool overwrite = true) { if (!overwrite && File.Exists(outputFilePath)) - _logger.Info($"{outputFilePath} exists, skip to next."); + _logger.LogInformation("{outputFilePath} exists, skip to next.", outputFilePath); else if (File.Exists(filePath)) { try @@ -65,26 +73,26 @@ private static void ConvertToCSharpFile(string filePath, string outputFilePath, var options = new JavaConversionOptions(); options.WarningEncountered += (sender, eventArgs) - => _logger.Warn($"[WARNING] Line {eventArgs.JavaLineNumber}: {eventArgs.Message}"); + => _logger.LogWarning("Line {line}: {message}", eventArgs.JavaLineNumber, eventArgs.Message); var parsed = JavaToCSharpConverter.ConvertText(javaText, options); File.WriteAllText(outputFilePath, parsed); - _logger.Info($"{filePath} was done!"); + _logger.LogInformation("{filePath} converted!", filePath); } catch (Exception ex) { - _logger.Error($"{filePath} was failed! err = " + ex.Message, ex); + _logger.LogError("{filePath} failed! {type}: {message}", filePath, ex.GetType().Name, ex.Message); } } else - _logger.Info("Java input file doesn't exist!"); + _logger.LogError("Java input file {filePath} doesn't exist!", filePath); } private static void ShowHelp() { Console.WriteLine("Usage:\r\n\tJavaToCSharpCli.exe -f [pathToJavaFile] [pathToCsOutputFile]"); - Console.WriteLine("Usage:\tJavaToCSharpCli.exe -d [pathToJavaFolder] [pathToCsOutputFolder]"); + Console.WriteLine("\tJavaToCSharpCli.exe -d [pathToJavaFolder] [pathToCsOutputFolder]"); } } } \ No newline at end of file diff --git a/JavaToCSharpCli/log4net.config b/JavaToCSharpCli/log4net.config deleted file mode 100644 index f89f2b39..00000000 --- a/JavaToCSharpCli/log4net.config +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 8b765c626f899387535c28b90fc54fde54a53b38 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 9 Mar 2022 14:38:38 -0700 Subject: [PATCH 9/9] Bump version to 2.1.0 --- JavaToCSharp/JavaToCSharp.csproj | 2 +- JavaToCSharpCli/JavaToCSharpCli.csproj | 4 ++-- JavaToCSharpGui/JavaToCSharpGui.csproj | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/JavaToCSharp/JavaToCSharp.csproj b/JavaToCSharp/JavaToCSharp.csproj index 626ad91a..0e5f883a 100644 --- a/JavaToCSharp/JavaToCSharp.csproj +++ b/JavaToCSharp/JavaToCSharp.csproj @@ -1,6 +1,6 @@ - 2.0.2 + 2.1.0 net5.0 enable latest diff --git a/JavaToCSharpCli/JavaToCSharpCli.csproj b/JavaToCSharpCli/JavaToCSharpCli.csproj index 78b860e0..8202a63f 100644 --- a/JavaToCSharpCli/JavaToCSharpCli.csproj +++ b/JavaToCSharpCli/JavaToCSharpCli.csproj @@ -1,6 +1,6 @@ - + - 2.0.2 + 2.1.0 Exe net5.0 diff --git a/JavaToCSharpGui/JavaToCSharpGui.csproj b/JavaToCSharpGui/JavaToCSharpGui.csproj index 98533078..1dfa8727 100644 --- a/JavaToCSharpGui/JavaToCSharpGui.csproj +++ b/JavaToCSharpGui/JavaToCSharpGui.csproj @@ -1,6 +1,6 @@ - 2.0.2 + 2.1.0 WinExe net5.0-windows true