From ee8dccf07f18039dd4e1f45531d1f9df287c350b Mon Sep 17 00:00:00 2001 From: Javier <10879637+javiertuya@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:42:09 +0200 Subject: [PATCH 1/2] Convert class bounded type parameters, close #125 --- JavaToCSharp.Tests/ConvertTypeTests.cs | 31 +++++++++++++++++++ .../ClassOrInterfaceDeclarationVisitor.cs | 1 + JavaToCSharp/TypeHelper.cs | 25 +++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/JavaToCSharp.Tests/ConvertTypeTests.cs b/JavaToCSharp.Tests/ConvertTypeTests.cs index b9cf4b79..558a8efc 100644 --- a/JavaToCSharp.Tests/ConvertTypeTests.cs +++ b/JavaToCSharp.Tests/ConvertTypeTests.cs @@ -113,4 +113,35 @@ public void ConvertTypeSyntax_GivenMismatchedRank_ShouldThrowException() Assert.Throws(() => TypeHelper.ConvertTypeSyntax(type, 1)); } + + [Theory] + [InlineData("GenericClass", "GenericClass")] + [InlineData("GenericClass>", "GenericClass\n where T : BoundType")] + [InlineData("GenericClass", "GenericClass\n where T : BoundType")] + + [InlineData("GenericClass", "GenericClass")] + [InlineData("GenericClass>", "GenericClass\n where U : BoundType")] + [InlineData("GenericClass, U extends BoundType2>", "GenericClass\n where T : BoundType1 where U : BoundType2")] + + [InlineData("GenericClass & BoundType2>", "GenericClass\n where T : BoundType1, BoundType2")] + public void ConvertClassTypeBoundedParameters(string javaClass, string csharpClass) + { + string javaCode = $$""" + public class {{javaClass}} { } + """; + var options = new JavaConversionOptions + { + IncludeUsings = false, + IncludeNamespace = false, + }; + var parsed = JavaToCSharpConverter.ConvertText(javaCode, options) ?? ""; + string expected = $$""" + public class {{csharpClass}} + { + } + + """; + + Assert.Equal(expected.ReplaceLineEndings(), parsed.ReplaceLineEndings()); + } } diff --git a/JavaToCSharp/Declarations/ClassOrInterfaceDeclarationVisitor.cs b/JavaToCSharp/Declarations/ClassOrInterfaceDeclarationVisitor.cs index 0c3532e9..23494ebe 100644 --- a/JavaToCSharp/Declarations/ClassOrInterfaceDeclarationVisitor.cs +++ b/JavaToCSharp/Declarations/ClassOrInterfaceDeclarationVisitor.cs @@ -128,6 +128,7 @@ public static ClassDeclarationSyntax VisitClassDeclaration(ConversionContext con { classSyntax = classSyntax.AddTypeParameterListParameters(typeParams .Select(i => SyntaxFactory.TypeParameter(i.getNameAsString())).ToArray()); + classSyntax = classSyntax.AddConstraintClauses(TypeHelper.GetTypeParameterListConstraints(typeParams).ToArray()); } var mods = classDecl.getModifiers().ToModifierKeywordSet(); diff --git a/JavaToCSharp/TypeHelper.cs b/JavaToCSharp/TypeHelper.cs index d75d10f1..0eedaa70 100644 --- a/JavaToCSharp/TypeHelper.cs +++ b/JavaToCSharp/TypeHelper.cs @@ -194,6 +194,31 @@ private static SeparatedSyntaxList GetSeparatedListFromArguments return SyntaxFactory.SeparatedList(argSyntaxes, separators); } + /// + /// Returns the list of C# type parameter constraints that must be added to a class syntax + /// to convert the java bounded type parameters of a class declaration. + /// e.g. to convert > ]]> into where T : Clazz ]]> + /// + public static IEnumerable GetTypeParameterListConstraints(List typeParams) + { + var typeParameterConstraints = new List(); + foreach (TypeParameter typeParam in typeParams) + { + if (typeParam.getTypeBound().size() > 0) + { + var typeConstraintsSyntax = new SeparatedSyntaxList(); + foreach (ClassOrInterfaceType bound in typeParam.getTypeBound()) + typeConstraintsSyntax = typeConstraintsSyntax.Add(SyntaxFactory.TypeConstraint(SyntaxFactory.ParseTypeName(bound.asString()))); + + var typeIdentifier = SyntaxFactory.IdentifierName(typeParam.getName().asString()); + var parameterConstraintClauseSyntax = SyntaxFactory.TypeParameterConstraintClause(typeIdentifier, typeConstraintsSyntax); + + typeParameterConstraints.Add(parameterConstraintClauseSyntax); + } + } + return typeParameterConstraints; + } + /// /// Transforms method calls into property and indexer accesses where appropriate. /// From 0f726fe62003ce03a2b6c1f8559ef0ff98ba84e9 Mon Sep 17 00:00:00 2001 From: Javier <10879637+javiertuya@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:09:10 +0100 Subject: [PATCH 2/2] Update comment test with class type bounded params --- JavaToCSharp.Tests/CommentTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JavaToCSharp.Tests/CommentTests.cs b/JavaToCSharp.Tests/CommentTests.cs index 1b666ded..c60d636e 100644 --- a/JavaToCSharp.Tests/CommentTests.cs +++ b/JavaToCSharp.Tests/CommentTests.cs @@ -110,7 +110,7 @@ public class Foo [InlineData("Child extends Parent implements IParent", "Child : Parent, IParent")] [InlineData("Parent", "Parent")] - [InlineData("Child>", "Child")] // issue #125, should add: where T : BoundType + [InlineData("Child>", "Child\n where T : BoundType")] [InlineData("Child extends Parent", "Child : Parent")] public void CommentsInsideClass_ShouldNotBeDuplicated_Fix_88(string javaClass, string csharpClass) {