See More

using System.Collections.Generic; using System.Linq; using JavaToCSharp.Expressions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using ast = com.github.javaparser.ast; namespace JavaToCSharp { public static class TypeHelper { private static readonly Dictionary _typeNameConversions = new() { // Simple types ["boolean"] = "bool", ["Boolean"] = "bool", ["ICloseable"] = "IDisposable", ["Integer"] = "int", ["String"] = "string", ["Object"] = "object", // Generic types ["ArrayList"] = "List", ["List"] = "IList", // Exceptions ["AlreadyClosedException"] = "ObjectDisposedException", ["Error"] = "Exception", ["IllegalArgumentException"] = "ArgumentException", ["IllegalStateException"] = "InvalidOperationException", ["UnsupportedOperationException"] = "NotSupportedException", ["RuntimeException"] = "Exception", }; public static string ConvertTypeOf(ast.nodeTypes.NodeWithType typedNode) { return ConvertType(typedNode.getType().toString()); } public static string ConvertType(ast.type.Type type) { return ConvertType(type.toString()); } public static string ConvertType(string typeName) { return TypeNameParser.ParseTypeName(typeName, s => { if (_typeNameConversions.TryGetValue(s, out string converted)) { return converted; } return s; }); } public static string Capitalize(string name) { var parts = name.Split('.'); var joined = string.Join(".", parts.Select(i => { if (i.Length == 1) return i.ToUpper(); else return i[0].ToString().ToUpper() + i.Substring(1); })); return joined; } public static string EscapeIdentifier(string name) { // @ (C# Reference): https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim switch (name) { case "string": case "ref": case "object": case "int": case "short": case "float": case "long": case "double": case "in": case "out": case "byte": case "class": case "delegate": case "params": case "is": case "as": case "base": case "namespace": case "event": case "lock": case "operator": case "override": return "@" + name; default: return name; } } public static string ReplaceCommonMethodNames(string name) { switch (name.ToLower()) { case "hashcode": return "GetHashCode"; case "getclass": return "GetType"; default: return name; } } public static TypeSyntax GetSyntaxFromType(ast.type.ClassOrInterfaceType type, bool addI = false) { string typeName = type.getName(); string originalTypeName = typeName; typeName = ConvertType(typeName); if (addI && typeName == originalTypeName) typeName = "I" + typeName; var typeArgs = type.getTypeArgs().ToList(); TypeSyntax typeSyntax; if (typeArgs != null && typeArgs.Count > 0) { typeSyntax = SyntaxFactory.GenericName(typeName) .AddTypeArgumentListArguments(typeArgs.Select(t => SyntaxFactory.ParseTypeName(ConvertType(t))).ToArray()); } else { typeSyntax = SyntaxFactory.ParseTypeName(typeName); } return typeSyntax; } public static ArgumentListSyntax GetSyntaxFromArguments(ConversionContext context, java.util.List args) { return SyntaxFactory.ArgumentList(GetSeparatedListFromArguments(context, args)); } private static SeparatedSyntaxList GetSeparatedListFromArguments(ConversionContext context, java.util.List args) { return GetSeparatedListFromArguments(context, args.OfType()); } private static SeparatedSyntaxList GetSeparatedListFromArguments(ConversionContext context, IEnumerable args) { var argSyntaxes = new List(); foreach (var arg in args) { var argSyntax = ExpressionVisitor.VisitExpression(context, arg); argSyntaxes.Add(SyntaxFactory.Argument(argSyntax)); } var separators = Enumerable.Repeat(SyntaxFactory.Token(SyntaxKind.CommaToken), argSyntaxes.Count - 1); return SyntaxFactory.SeparatedList(argSyntaxes, separators); } ///

/// Transforms method calls into property and indexer accesses where appropriate. /// /// The conversion context. /// The MethodCallExpr to be transformed. /// The resulting transformed syntax. /// true if the syntax was transformed, false otherwise public static bool TryTransformMethodCall(ConversionContext context, ast.expr.MethodCallExpr methodCallExpr, out ExpressionSyntax transformedSyntax) { if (methodCallExpr.getScope() is ast.expr.Expression scope) { string methodName = methodCallExpr.getName(); var args = methodCallExpr.getArgs(); ExpressionSyntax scopeSyntax = ExpressionVisitor.VisitExpression(context, scope); switch (methodName) { case "size" when args.size() == 0: transformedSyntax = ReplaceSizeByCount(scopeSyntax); return true; case "get" when args.size() == 1: transformedSyntax = ReplaceGetByIndexAccess(context, scopeSyntax, args); return true; case "set" when args.size() == 2: transformedSyntax = ReplaceSetByIndexAccess(context, scopeSyntax, args); return true; } } transformedSyntax = null; return false; static MemberAccessExpressionSyntax ReplaceSizeByCount(ExpressionSyntax scopeSyntax) { // Replace expr.Size() by expr.Count return SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, scopeSyntax, SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Count"))); } static ExpressionSyntax ReplaceGetByIndexAccess(ConversionContext context, ExpressionSyntax scopeSyntax, java.util.List args) { // Replace expr.Get(i) by expr[i] return SyntaxFactory.ElementAccessExpression( scopeSyntax, SyntaxFactory.BracketedArgumentList(GetSeparatedListFromArguments(context, args)) ); } static ExpressionSyntax ReplaceSetByIndexAccess(ConversionContext context, ExpressionSyntax scopeSyntax, java.util.List args) { // Replace expr.Set(i,v) by expr[i] = v var argsList = args.ToList(); return SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.ElementAccessExpression( scopeSyntax, SyntaxFactory.BracketedArgumentList(GetSeparatedListFromArguments(context, argsList.Take(1))) ).WithTrailingTrivia(SyntaxFactory.Whitespace(" ")), ExpressionVisitor.VisitExpression(context, argsList[1]).WithLeadingTrivia(SyntaxFactory.Whitespace(" ")) ); } } } }