Browse Source

Add initial Java parsing support.

java
Joao Matos 4 years ago
parent
commit
06dce35cca
  1. 772
      external/JavaParser/JavaParser/JavaAST.cs
  2. 25
      external/JavaParser/JavaParser/JavaParser.csproj
  3. 650
      external/JavaParser/JavaParser/Program.cs

772
external/JavaParser/JavaParser/JavaAST.cs vendored

@ -0,0 +1,772 @@ @@ -0,0 +1,772 @@
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var cppSharpAstJava = CppSharpAstJava.FromJson(jsonString);
using Newtonsoft.Json.Linq;
namespace JavaParser.AST
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
#region Base
public partial class Range
{
[JsonProperty("beginLine")]
public long BeginLine { get; set; }
[JsonProperty("beginColumn")]
public long BeginColumn { get; set; }
[JsonProperty("endLine")]
public long EndLine { get; set; }
[JsonProperty("endColumn")]
public long EndColumn { get; set; }
}
public partial class TokenRange
{
[JsonProperty("beginToken")]
public Token BeginToken { get; set; }
[JsonProperty("endToken")]
public Token EndToken { get; set; }
}
public partial class Token
{
[JsonProperty("kind")]
public long Kind { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
#endregion
#region Nodes
public partial class Node
{
[JsonProperty("!")]
public string Kind { get; set; }
[JsonProperty("range")]
public Range Range { get; set; }
[JsonProperty("tokenRange")]
public TokenRange TokenRange { get; set; }
[JsonProperty("comment")]
public Comment Comment { get; set; }
}
public partial class ArrayCreationLevel : Node
{
[JsonProperty("dimension")]
public Expression Dimension { get; set; }
[JsonProperty("annotations")]
public AnnotationExpr[] Annotations { get; set; }
}
public partial class CompilationUnit : Node
{
public string FileName { get; set; }
[JsonProperty("imports")]
public ImportDeclaration[] Imports { get; set; }
[JsonProperty("packageDeclaration")]
public PackageDeclaration PackageDeclaration { get; set; }
[JsonProperty("types")]
public TypeDeclaration[] Types { get; set; }
}
public partial class ImportDeclaration : Node
{
[JsonProperty("name")]
public Name Name;
[JsonProperty("isStatic")]
public bool IsStatic;
[JsonProperty("isAsterisk")]
public bool IsAsterisk;
}
public partial class PackageDeclaration : Node
{
[JsonProperty("annotations")]
public AnnotationExpr[] Annotations { get; set; }
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public Name Name { get; set; }
}
public partial class Modifier : Node
{
[JsonProperty("keyword")]
public string Keyword;
}
#endregion
#region Body
public partial class BodyDeclaration : Node
{
[JsonProperty("annotations")]
public AnnotationExpr[] Annotations { get; set; }
}
public partial class AnnotationDeclaration : TypeDeclaration
{
}
public partial class AnnotationMemberDeclaration : BodyDeclaration
{
[JsonProperty("modifiers")]
public Modifier[] Modifiers;
[JsonProperty("type")]
public Type Type;
[JsonProperty("name")]
public SimpleName Name;
[JsonProperty("defaultValue")]
public Expression DefaultValue;
}
public partial class TypeDeclaration : BodyDeclaration
{
[JsonProperty("name")]
public SimpleName Name { get; set; }
[JsonProperty("modifiers")]
public Modifier[] Modifiers { get; set; }
[JsonProperty("members")]
public BodyDeclaration[] Members { get; set; }
}
public partial class ClassOrInterfaceDeclaration : TypeDeclaration
{
[JsonProperty("isInterface")]
public bool IsInterface { get; set; }
[JsonProperty("typeParameters")]
public TypeParameter[] TypeParameters { get; set; }
[JsonProperty("implementedTypes")]
public ClassOrInterfaceType[] ImplementedTypes { get; set; }
[JsonProperty("extendedTypes")]
public ClassOrInterfaceType[] ExtendedTypes { get; set; }
}
public partial class ConstructorDeclaration : CallableDeclaration
{
[JsonProperty("body")]
public BlockStmt Body;
}
public partial class EnumDeclaration : TypeDeclaration
{
[JsonProperty("entries")]
public EnumConstantDeclaration[] Entries { get; set; }
}
public partial class EnumConstantDeclaration : BodyDeclaration
{
[JsonProperty("name")]
public SimpleName Name { get; set; }
[JsonProperty("arguments")]
public Expression[] Arguments { get; set; }
[JsonProperty("classBody")]
public BodyDeclaration[] ClassBody { get; set; }
}
public partial class FieldDeclaration : BodyDeclaration
{
[JsonProperty("modifiers")]
public Modifier[] Modifiers;
[JsonProperty("variables")]
public VariableDeclarator[] Variables;
}
public partial class InitializerDeclaration : BodyDeclaration
{
[JsonProperty("isStatic")]
public bool IsStatic;
[JsonProperty("body")]
public BlockStmt Body;
}
public partial class CallableDeclaration : BodyDeclaration
{
[JsonProperty("modifiers")]
public Modifier[] Modifiers;
[JsonProperty("typeParameters")]
public TypeParameter[] TypeParameters;
[JsonProperty("name")]
public SimpleName Name;
[JsonProperty("parameters")]
public Parameter[] Parameters;
[JsonProperty("thrownExceptions")]
public ReferenceType[] ThrownExceptions;
//public ReceiverParameter receiverParameter;
}
public partial class MethodDeclaration : CallableDeclaration
{
[JsonProperty("type")]
public Type Type;
[JsonProperty("body")]
public BlockStmt Body;
}
public partial class Parameter : Node
{
[JsonProperty("type")]
public Type Type;
[JsonProperty("isVarArgs")]
public bool IsVarArgs;
[JsonProperty("varArgsAnnotations")]
public AnnotationExpr[] VarArgsAnnotations;
[JsonProperty("modifiers")]
public Modifier[] Modifiers;
[JsonProperty("annotations")]
public AnnotationExpr[] Annotations;
[JsonProperty("name")]
public SimpleName Name;
}
public partial class VariableDeclarator : Node
{
[JsonProperty("name")]
public SimpleName Name;
[JsonProperty("initializer")]
public Expression Initializer;
[JsonProperty("type")]
public Type Type;
}
#endregion
#region Comments
public partial class BlockComment : Comment
{
}
public partial class Comment : Node
{
[JsonProperty("content")]
public string Content { get; set; }
}
public partial class JavadocComment : Comment
{
}
public partial class LineComment : Comment
{
}
#endregion
#region Types
public partial class Type
{
[JsonProperty("annotations")]
public AnnotationExpr[] Annotations { get; set; }
}
public partial class ArrayType : ReferenceType
{
[JsonProperty("componentType")]
public Type ComponentType { get; set; }
}
public partial class ClassOrInterfaceType : ReferenceType
{
[JsonProperty("name")]
public SimpleName Name { get; set; }
[JsonProperty("typeArguments")]
public Type[] TypeArguments { get; set; }
}
public partial class PrimitiveType : Type
{
[JsonProperty("type")]
public string Type { get; set; }
}
public partial class ReferenceType : Type
{
}
public partial class TypeParameter : ReferenceType
{
[JsonProperty("name")]
public SimpleName Name { get; set; }
[JsonProperty("typeBound")]
public ClassOrInterfaceType[] TypeBound { get; set; }
}
public partial class UnknownType : Type
{
}
public partial class VoidType : Type
{
}
public partial class WildcardType : Type
{
[JsonProperty("extendedType")]
public ReferenceType ExtendedType;
[JsonProperty("superType")]
public ReferenceType SuperType;
}
#endregion
#region Expressions
public partial class Expression : Node
{
}
public partial class AnnotationExpr : Expression
{
[JsonProperty("name")]
public Name Name;
}
public partial class ArrayAccessExpr : Expression
{
[JsonProperty("name")]
public Expression Name;
[JsonProperty("index")]
public Expression Index;
}
public partial class ArrayCreationExpr : Expression
{
[JsonProperty("levels")]
public ArrayCreationLevel[] Levels;
[JsonProperty("elementType")]
public Type ElementType;
[JsonProperty("initializer")]
public ArrayInitializerExpr Initializer;
}
public partial class ArrayInitializerExpr : Expression
{
[JsonProperty("values")]
public Expression[] Values;
}
public partial class BinaryExpr : Expression
{
}
public partial class ClassExpr : Expression
{
[JsonProperty("type")]
public Type Type;
}
public partial class DoubleLiteralExpr : LiteralStringValueExpr
{
}
public partial class FieldAccessExpr : Expression
{
[JsonProperty("scope")]
public Expression Scope;
[JsonProperty("typeArguments")]
public Type[] TypeArguments;
[JsonProperty("name")]
public SimpleName Name;
}
public partial class IntegerLiteralExpr : LiteralStringValueExpr
{
}
public partial class LambdaExpr : Expression
{
[JsonProperty("parameters")]
public Parameter[] Parameters;
[JsonProperty("isEnclosingParameters")]
public bool IsEnclosingParameters;
[JsonProperty("body")]
public Statement Body;
}
public partial class LiteralExpr : Expression
{
}
public partial class LiteralStringValueExpr : LiteralExpr
{
[JsonProperty("value")]
public string Value;
}
public partial class MarkerAnnotationExpr : AnnotationExpr
{
}
public partial class MemberValuePair : Node
{
[JsonProperty("name")]
public SimpleName Name;
[JsonProperty("value")]
public Expression Value;
}
public partial class MethodCallExpr : Expression
{
[JsonProperty("scope")]
public Expression Scope;
[JsonProperty("typeArguments")]
public Type[] TypeArguments;
[JsonProperty("name")]
public SimpleName Name;
[JsonProperty("arguments")]
public Expression[] Arguments;
}
public partial class NameExpr : Expression
{
[JsonProperty("name")]
public SimpleName Name;
}
public partial class NormalAnnotationExpr : AnnotationExpr
{
[JsonProperty("pairs")]
public MemberValuePair[] Pairs;
}
public partial class NullLiteralExpr : LiteralExpr
{
}
public partial class ObjectCreationExpr : Expression
{
[JsonProperty("scope")]
public Expression Scope;
[JsonProperty("type")]
public ClassOrInterfaceType Type;
[JsonProperty("typeArguments")]
public Type[] TypeArguments;
[JsonProperty("arguments")]
public Expression[] Arguments;
[JsonProperty("anonymousClassBody")]
public BodyDeclaration[] AnonymousClassBody;
}
public partial class StringLiteralExpr : LiteralStringValueExpr
{
}
public partial class SimpleName : Node
{
[JsonProperty("identifier")]
public string Identifier { get; set; }
}
public partial class SingleMemberAnnotationExpr : AnnotationExpr
{
[JsonProperty("memberValue")]
public Expression MemberValue;
}
public partial class UnaryExpr : Expression
{
}
public partial class Name : Node
{
[JsonProperty("identifier")]
public string Identifier { get; set; }
[JsonProperty("qualifier")]
public Name Qualifier;
}
#endregion
#region Statements
public class Statement
{
}
public class BlockStmt : Statement
{
[JsonProperty("statements")]
public Statement[] Statements;
}
#endregion
public partial class CompilationUnit
{
public static CompilationUnit FromJson(string json) =>
JsonConvert.DeserializeObject<CompilationUnit>(json, Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this CompilationUnit self) =>
JsonConvert.SerializeObject(self, Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal },
new NodeConverter(),
new TypeConverter()
},
};
}
internal class NodeConverter : JsonCreationConverter<Node>
{
protected override Node Create(System.Type objectType, JObject jObject)
{
switch (jObject["!"].ToString())
{
case "com.github.javaparser.ast.ArrayCreationLevel":
return new ArrayCreationLevel();
case "com.github.javaparser.ast.CompilationUnit":
return new CompilationUnit();
case "com.github.javaparser.ast.ImportDeclaration":
return new ImportDeclaration();
case "com.github.javaparser.ast.Modifier":
return new Modifier();
case "com.github.javaparser.ast.PackageDeclaration":
return new PackageDeclaration();
case "com.github.javaparser.ast.body.AnnotationDeclaration":
return new AnnotationDeclaration();
case "com.github.javaparser.ast.body.AnnotationMemberDeclaration":
return new AnnotationMemberDeclaration();
case "com.github.javaparser.ast.body.ClassOrInterfaceDeclaration":
return new ClassOrInterfaceDeclaration();
case "com.github.javaparser.ast.body.ConstructorDeclaration":
return new ConstructorDeclaration();
case "com.github.javaparser.ast.body.FieldDeclaration":
return new FieldDeclaration();
case "com.github.javaparser.ast.body.InitializerDeclaration":
return new InitializerDeclaration();
case "com.github.javaparser.ast.body.EnumConstantDeclaration":
return new EnumConstantDeclaration();
case "com.github.javaparser.ast.body.EnumDeclaration":
return new EnumDeclaration();
case "com.github.javaparser.ast.body.MethodDeclaration":
return new MethodDeclaration();
case "com.github.javaparser.ast.body.Parameter":
return new Parameter();
case "com.github.javaparser.ast.body.VariableDeclarator":
return new VariableDeclarator();
case "com.github.javaparser.ast.comments.BlockComment":
return new BlockComment();
case "com.github.javaparser.ast.comments.Comment":
return new Comment();
case "com.github.javaparser.ast.comments.JavadocComment":
return new JavadocComment();
case "com.github.javaparser.ast.comments.LineComment":
return new LineComment();
case "com.github.javaparser.ast.expr.AnnotationExpr":
return new AnnotationExpr();
case "com.github.javaparser.ast.expr.ArrayAccessExpr":
return new ArrayAccessExpr();
case "com.github.javaparser.ast.expr.ArrayCreationExpr":
return new ArrayCreationExpr();
case "com.github.javaparser.ast.expr.ArrayInitializerExpr":
return new ArrayInitializerExpr();
case "com.github.javaparser.ast.expr.BinaryExpr":
return new BinaryExpr();
case "com.github.javaparser.ast.expr.ClassExpr":
return new ClassExpr();
case "com.github.javaparser.ast.expr.DoubleLiteralExpr":
return new DoubleLiteralExpr();
case "com.github.javaparser.ast.expr.FieldAccessExpr":
return new FieldAccessExpr();
case "com.github.javaparser.ast.expr.IntegerLiteralExpr":
return new IntegerLiteralExpr();
case "com.github.javaparser.ast.expr.LambdaExpr":
return new LambdaExpr();
case "com.github.javaparser.ast.expr.LiteralExpr":
return new LiteralExpr();
case "com.github.javaparser.ast.expr.LiteralStringValueExpr":
return new LiteralStringValueExpr();
case "com.github.javaparser.ast.expr.MarkerAnnotationExpr":
return new MarkerAnnotationExpr();
case "com.github.javaparser.ast.expr.MemberValuePair":
return new MemberValuePair();
case "com.github.javaparser.ast.expr.MethodCallExpr":
return new MethodCallExpr();
case "com.github.javaparser.ast.expr.NameExpr":
return new NameExpr();
case "com.github.javaparser.ast.expr.NormalAnnotationExpr":
return new NormalAnnotationExpr();
case "com.github.javaparser.ast.expr.NullLiteralExpr":
return new NullLiteralExpr();
case "com.github.javaparser.ast.expr.Name":
return new Name();
case "com.github.javaparser.ast.expr.ObjectCreationExpr":
return new ObjectCreationExpr();
case "com.github.javaparser.ast.expr.SimpleName":
return new SimpleName();
case "com.github.javaparser.ast.expr.SingleMemberAnnotationExpr":
return new SingleMemberAnnotationExpr();
case "com.github.javaparser.ast.expr.StringLiteralExpr":
return new StringLiteralExpr();
case "com.github.javaparser.ast.expr.UnaryExpr":
return new UnaryExpr();
default:
throw new NotImplementedException($"Missing handler for: {jObject["!"]}");
}
}
}
internal class TypeConverter : JsonCreationConverter<Type>
{
protected override Type Create(System.Type objectType, JObject jObject)
{
switch (jObject["!"].ToString())
{
case "com.github.javaparser.ast.type.ArrayType":
return new ArrayType();
case "com.github.javaparser.ast.type.ClassOrInterfaceType":
return new ClassOrInterfaceType();
case "com.github.javaparser.ast.type.PrimitiveType":
return new PrimitiveType();
case "com.github.javaparser.ast.type.TypeParameter":
return new TypeParameter();
case "com.github.javaparser.ast.type.UnknownType":
return new UnknownType();
case "com.github.javaparser.ast.type.VoidType":
return new VoidType();
case "com.github.javaparser.ast.type.WildcardType":
return new WildcardType();
default:
throw new NotImplementedException($"Missing handler for: {jObject["!"]}");
}
}
}
internal abstract class JsonCreationConverter<T> : JsonConverter
{
/// <summary>
/// Create an instance of objectType, based properties in the JSON object
/// </summary>
/// <param name="objectType">type of object expected</param>
/// <param name="jObject">
/// contents of JSON object that will be deserialized
/// </param>
/// <returns></returns>
protected abstract T Create(System.Type objectType, JObject jObject);
public override bool CanConvert(System.Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override bool CanWrite => false;
public override object ReadJson(JsonReader reader,
System.Type objectType,
object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
// Create target object based on JObject
T target = Create(objectType, jObject);
// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}

25
external/JavaParser/JavaParser/JavaParser.csproj vendored

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="IKVM.OpenJDK.Core, Version=8.5.0.3, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\deps\ikvm\bin\Debug\netcoreapp3.1\IKVM.OpenJDK.Core.dll</HintPath>
</Reference>
<Reference Include="IKVM.Runtime, Version=8.5.0.3, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\deps\ikvm\bin\Debug\netcoreapp3.1\IKVM.Runtime.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\AST\CppSharp.AST.csproj" />
<ProjectReference Include="..\..\..\src\Generator\CppSharp.Generator.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" PrivateAssets="All" />
</ItemGroup>
</Project>

650
external/JavaParser/JavaParser/Program.cs vendored

@ -0,0 +1,650 @@ @@ -0,0 +1,650 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CppSharp;
using CppSharp.AST;
using CppSharp.Generators;
using CppSharp.Parser;
using IKVM.Internal;
using ArrayType = CppSharp.AST.ArrayType;
using Parameter = CppSharp.AST.Parameter;
using PrimitiveType = CppSharp.AST.PrimitiveType;
using Type = CppSharp.AST.Type;
namespace JavaParser.AST
{
public class Options : DriverOptions
{
/// <summary>
/// The name of the library to be bound.
/// </summary>
public Module Module;
}
public class JavaJarASTGenerator
{
public static Dictionary<TranslationUnit, ClassFile> JavaClassFiles
= new Dictionary<TranslationUnit, ClassFile>();
ASTContext ASTContext { get; set; }
Options Options { get; set; }
public JavaJarASTGenerator(ASTContext context, Options options)
{
ASTContext = context;
Options = options;
}
public TranslationUnit VisitClassFile(ClassFile classFile)
{
var unit = GetTranslationUnit(classFile);
var components = classFile.Name.Split(".").ToArray();
var namespaces = components.SkipLast(1).ToArray();
Namespace currentNamespace = unit;
bool flattenNamespaces = true;
if (!flattenNamespaces)
{
foreach (var @namespace in namespaces)
currentNamespace = currentNamespace.FindCreateNamespace(@namespace);
}
DeclarationContext decl = classFile.IsEnum ? (DeclarationContext)VisitEnum(classFile) :
(DeclarationContext)VisitClass(classFile);
decl.Namespace = currentNamespace;
currentNamespace.Declarations.Add(decl);
return unit;
}
public Enumeration VisitEnum(ClassFile classFile)
{
var components = classFile.Name.Split(".").ToArray();
var @class = new Enumeration
{
Name = components.Last(),
};
return @class;
}
public static AccessSpecifier ConvertMethodAccess(ClassFile.Method method)
{
if (method.IsInternal)
return AccessSpecifier.Internal;
if (method.IsPrivate)
return AccessSpecifier.Private;
if (method.IsProtected)
return AccessSpecifier.Protected;
if (method.IsPublic)
return AccessSpecifier.Public;
return AccessSpecifier.Public;
}
public Class VisitClass(ClassFile classFile)
{
var components = classFile.Name.Split(".").ToArray();
var @class = new Class
{
Name = components.Last(),
Type = classFile.IsInterface ? ClassType.Interface : ClassType.RefType
};
foreach (var javaMethod in classFile.Methods)
{
var method = new Method
{
Name = javaMethod.Name,
Access = ConvertMethodAccess(javaMethod)
};
var (retType, paramTypes) = GetTypeFromMethodSig(javaMethod.Signature);
method.ReturnType = new QualifiedType(retType);
var paramIndex = 0;
foreach (var paramType in paramTypes)
{
var param = new CppSharp.AST.Parameter
{
Namespace = method,
QualifiedType = new QualifiedType(paramType)
};
if (javaMethod.MethodParameters != null)
if (paramIndex < javaMethod.MethodParameters.Length)
param.Name = javaMethod.MethodParameters[paramIndex].name;
method.Parameters.Add(param);
paramIndex++;
}
@class.Methods.Add(method);
}
return @class;
}
public static CppSharp.AST.PrimitiveType GetPrimitiveTypeFromJavaSig(char sig)
{
switch (sig)
{
case 'B':
return CppSharp.AST.PrimitiveType.Char;
case 'C':
return CppSharp.AST.PrimitiveType.WideChar;
case 'D':
return CppSharp.AST.PrimitiveType.Double;
case 'F':
return CppSharp.AST.PrimitiveType.Float;
case 'I':
return CppSharp.AST.PrimitiveType.Int;
case 'J':
return CppSharp.AST.PrimitiveType.Long;
case 'S':
return CppSharp.AST.PrimitiveType.Short;
case 'Z':
return CppSharp.AST.PrimitiveType.Bool;
case 'V':
return CppSharp.AST.PrimitiveType.Void;
default:
throw new NotImplementedException();
}
}
public static (CppSharp.AST.Type, List<CppSharp.AST.Type>) GetTypeFromMethodSig(string sig)
{
var types = new List<CppSharp.AST.Type>();
int i = 1;
while(sig[i] != ')')
types.Add(GetTypeFromSig(sig, ref i));
i++;
var retType = GetTypeFromSig(sig, ref i);
return (retType, types);
}
public static CppSharp.AST.TagType GetTagTypeFromSig(string sig, ref int index)
{
int pos = index;
index = sig.IndexOf(';', index) + 1;
var className = sig.Substring(pos, index - pos - 1);
var @class = new TagType();
return @class;
}
public static CppSharp.AST.Type GetTypeFromSig(string sig, ref int index)
{
var @char = sig[index++];
switch(@char)
{
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
case 'V':
return new BuiltinType(GetPrimitiveTypeFromJavaSig(@char));
case 'L':
{
int pos = index;
index = sig.IndexOf(';', index) + 1;
var className = sig.Substring(pos, index - pos - 1);
var @class = new TagType();
return @class;
}
case '[':
{
var rootArrayType = new CppSharp.AST.ArrayType
{
SizeType = CppSharp.AST.ArrayType.ArraySize.Variable
};
var arrayType = rootArrayType;
while(sig[index] == '[')
{
index++;
var newArrayType = new CppSharp.AST.ArrayType
{
SizeType = CppSharp.AST.ArrayType.ArraySize.Variable
};
arrayType.QualifiedType = new QualifiedType(newArrayType);
arrayType = newArrayType;
}
var innerType = GetTypeFromSig(sig, ref index);
arrayType.QualifiedType = new QualifiedType(innerType);
return rootArrayType;
}
default:
throw new InvalidOperationException(sig.Substring(index));
}
}
TranslationUnit GetTranslationUnit(ClassFile classFile)
{
var unitName = Options.Module.LibraryName ?? Path.GetFileName (classFile.Name);
var unit = ASTContext.TranslationUnits.Find(m => m.FileName.Equals(unitName));
if (unit != null)
return unit;
unit = ASTContext.FindOrCreateTranslationUnit(unitName);
unit.FilePath = unitName;
JavaClassFiles[unit] = classFile;
return unit;
}
}
public class JavaJsonASTGenerator
{
ASTContext ASTContext { get; set; }
Options Options { get; set; }
public JavaJsonASTGenerator(ASTContext context, Options options)
{
ASTContext = context;
Options = options;
}
public TranslationUnit CurrentUnit;
public void VisitCompilationUnits(List<CompilationUnit> compilationUnits)
{
foreach (var unit in compilationUnits)
{
CurrentUnit = GetTranslationUnit(unit);
CurrentUnit.Module = Options.Module;
foreach (var type in unit.Types)
{
var decl = VisitTypeDeclaration(type);
if (decl == null)
continue;
decl.Namespace = CurrentUnit;
if (CurrentUnit.Declarations.All(d => d.Name != decl.Name))
CurrentUnit.Declarations.Add(decl);
}
}
}
public TranslationUnit GetTranslationUnit(CompilationUnit compilationUnit)
{
var unitName = Options.Module.LibraryName ?? Path.GetFileName (compilationUnit.FileName);
var unit = ASTContext.TranslationUnits.Find(m => m.FileName.Equals(unitName));
if (unit != null)
return unit;
unit = ASTContext.FindOrCreateTranslationUnit(unitName);
unit.FilePath = unitName;
return unit;
}
public Declaration VisitTypeDeclaration(TypeDeclaration type)
{
switch (type)
{
case AnnotationDeclaration annotationDeclaration:
return null;
case ClassOrInterfaceDeclaration classOrInterfaceDeclaration:
return VisitClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
case EnumDeclaration enumDeclaration:
return VisitEnumDeclaration(enumDeclaration);
default:
throw new NotImplementedException();
}
}
public Declaration VisitEnumDeclaration(EnumDeclaration enumDeclaration)
{
var @class = HandleTypeDeclaration(enumDeclaration);
if (!@class.IsIncomplete)
return @class;
foreach (var entry in enumDeclaration.Entries)
{
}
@class.IsIncomplete = false;
return @class;
}
public Class VisitClassOrInterfaceDeclaration(ClassOrInterfaceDeclaration classOrInterfaceDeclaration)
{
var @class = HandleTypeDeclaration(classOrInterfaceDeclaration);
if (!@class.IsIncomplete)
return @class;
@class.Type = classOrInterfaceDeclaration.IsInterface ? ClassType.Interface : ClassType.RefType;
@class.IsIncomplete = false;
if (classOrInterfaceDeclaration.TypeParameters.Length > 0)
{
@class.IsDependent = true;
foreach (var typeParam in classOrInterfaceDeclaration.TypeParameters)
{
var templateParam = new TypeTemplateParameter { Name = typeParam.Name.Identifier };
if (typeParam.TypeBound.Length > 0)
templateParam.Constraint = ConvertType(typeParam.TypeBound.First()).ToString();
@class.TemplateParameters.Add(templateParam);
}
}
foreach (var extendedType in classOrInterfaceDeclaration.ExtendedTypes)
{
var extendedClassType = ConvertType(extendedType);
@class.Bases.Add(new BaseClassSpecifier
{
Access = AccessSpecifier.Public,
IsVirtual = false,
Type = extendedClassType
});
}
/*
foreach (var implementedType in classOrInterfaceDeclaration.ImplementedTypes)
{
var implementedClassType = ConvertType(implementedType);
@class.Bases.Add(new BaseClassSpecifier
{
Access = AccessSpecifier.Public,
IsVirtual = false,
Type = implementedClassType
});
}
*/
return @class;
}
public Class HandleTypeDeclaration(TypeDeclaration typeDeclaration)
{
var @class = ASTContext.FindClass(typeDeclaration.Name.Identifier).FirstOrDefault();
if (@class == null)
{
@class = new Class {Name = typeDeclaration.Name.Identifier, IsIncomplete = true};
CurrentUnit.Declarations.Add(@class);
}
if (!@class.IsIncomplete)
return @class;
foreach (var member in typeDeclaration.Members)
{
var decl = VisitBodyDeclaration(member);
if (decl == null)
continue;
decl.Namespace = @class;
switch (decl)
{
case Method method:
@class.Methods.Add(method);
break;
case Field field:
@class.Fields.Add(field);
break;
default:
@class.Declarations.Add(decl);
break;
}
}
return @class;
}
public Declaration VisitBodyDeclaration(BodyDeclaration body)
{
switch (body)
{
case ClassOrInterfaceDeclaration classOrInterfaceDeclaration:
return VisitClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
case ConstructorDeclaration constructorDeclaration:
return VisitCallableDeclaration(constructorDeclaration);
case EnumDeclaration enumDeclaration:
return VisitEnumDeclaration(enumDeclaration);
case InitializerDeclaration initializerDeclaration:
return VisitInitializerDeclaration(initializerDeclaration);
case FieldDeclaration fieldDeclaration:
return VisitFieldDeclaration(fieldDeclaration);
case MethodDeclaration methodDeclaration:
return VisitCallableDeclaration(methodDeclaration);
default:
throw new NotImplementedException();
}
}
private Declaration VisitInitializerDeclaration(InitializerDeclaration initializerDeclaration)
{
return null;
}
public Declaration VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
{
return null;
}
public Method VisitCallableDeclaration(CallableDeclaration callableDeclaration)
{
var method = new Method
{
Name = callableDeclaration.Name.Identifier,
Access = AccessSpecifier.Internal
};
if (callableDeclaration is ConstructorDeclaration)
method.Kind = CXXMethodKind.Constructor;
if (callableDeclaration.Modifiers.Length > 0)
method.Access = ConvertModifier(callableDeclaration.Modifiers);
if (callableDeclaration is MethodDeclaration methodDecl)
method.ReturnType = new QualifiedType(ConvertType(methodDecl.Type));
foreach (var parameter in callableDeclaration.Parameters)
{
var paramType = ConvertType(parameter.Type);
var param = new CppSharp.AST.Parameter
{
Name = parameter.Name.Identifier,
Namespace = method,
QualifiedType = new QualifiedType(paramType)
};
method.Parameters.Add(@param);
}
return method;
}
public static CppSharp.AST.PrimitiveType ConvertToPrimitiveType(string type)
{
return type switch
{
"BOOLEAN" => CppSharp.AST.PrimitiveType.Bool,
"CHAR" => CppSharp.AST.PrimitiveType.Char,
"BYTE" => CppSharp.AST.PrimitiveType.UChar,
"SHORT" => CppSharp.AST.PrimitiveType.Short,
"INT" => CppSharp.AST.PrimitiveType.Int,
"LONG" => CppSharp.AST.PrimitiveType.Long,
"FLOAT" => CppSharp.AST.PrimitiveType.Float,
"DOUBLE" => CppSharp.AST.PrimitiveType.Double,
_ => throw new NotImplementedException()
};
}
public CppSharp.AST.Type ConvertType(Type type)
{
switch (type)
{
case ArrayType arrayType:
return new CppSharp.AST.ArrayType(new QualifiedType(ConvertType(arrayType.ComponentType)))
{
SizeType = CppSharp.AST.ArrayType.ArraySize.Variable
};
case PrimitiveType primitiveType:
return new BuiltinType(ConvertToPrimitiveType(primitiveType.Type));
case ClassOrInterfaceType classOrInterfaceType:
{
var @class = ASTContext.FindClass(classOrInterfaceType.Name.Identifier).FirstOrDefault();
if (@class == null)
{
@class = new Class
{
Name = classOrInterfaceType.Name.Identifier,
Namespace = CurrentUnit,
IsIncomplete = true
};
CurrentUnit.Declarations.Add(@class);
}
if (classOrInterfaceType.TypeArguments == null || classOrInterfaceType.TypeArguments.Length == 0)
return new TagType(@class);
return new TemplateSpecializationType
{
Arguments = classOrInterfaceType.TypeArguments.Select(ConvertType).Select(t =>
new TemplateArgument
{
Kind = TemplateArgument.ArgumentKind.Type,
Type = new QualifiedType(t),
}).ToList(),
Desugared = new QualifiedType(new TagType(@class)),
Template = new ClassTemplate(@class)
};
}
case VoidType voidType:
return new BuiltinType(CppSharp.AST.PrimitiveType.Void);
case WildcardType wildcardType:
{
return new TemplateSpecializationType();
}
default:
throw new NotImplementedException();
}
}
public static AccessSpecifier ConvertModifier(Modifier[] modifiers)
{
foreach (var modifier in modifiers)
{
switch (modifier.Keyword)
{
case "PUBLIC":
return AccessSpecifier.Public;
case "PROTECTED":
return AccessSpecifier.Protected;
case "PRIVATE":
return AccessSpecifier.Private;
case "DEFAULT":
return AccessSpecifier.Internal;
}
}
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
var options = new Options
{
GeneratorKind = GeneratorKind.TypeScript,
OutputDir = "ts"
};
var module = new Module("runelite-api");
options.Module = module;
options.Modules.Add(module);
var driver = new Driver(options);
driver.Setup();
driver.SetupTypeMaps();
driver.Context.ASTContext = new ASTContext();
var astContext = driver.Context.ASTContext;
//var jarAstGenerator = new JavaJarASTGenerator(astContext, options);
//var jarFile = "runelite-api-3.5.4.jar";
//ReadJar(jarFile, astGenerator);
var compilationUnits = ReadJSON();
var jsonAstGenerator = new JavaJsonASTGenerator(astContext, options);
jsonAstGenerator.VisitCompilationUnits(compilationUnits);
// Sort declarations alphabetically
var translationUnit = astContext.TranslationUnits.First();
var decls = new List<Declaration>(translationUnit.Declarations);
decls = decls.OrderBy(d => d.Name).ToList();
translationUnit.Declarations.Clear();
translationUnit.Declarations.AddRange(decls);
driver.ProcessCode();
var outputs = driver.GenerateCode();
driver.SaveCode(outputs);
}
private static List<CompilationUnit> ReadJSON()
{
var compilationUnits = new List<CompilationUnit>();
var jsonDir = "/home/joao/dev/rs/flower/javaparser-gradle-sample/out";
var jsonFiles = Directory.EnumerateFiles(jsonDir, "*.json",
SearchOption.AllDirectories);
Parallel.ForEach(jsonFiles, (file) =>
{
if (Path.GetFileNameWithoutExtension(file).StartsWith("class"))
return;
var jsonText = File.ReadAllText(file);
var compilationUnit = CompilationUnit.FromJson(jsonText);
compilationUnit.FileName = Path.GetFileNameWithoutExtension(file);
compilationUnits.Add(compilationUnit);
});
return compilationUnits;
}
private static void ReadJar(string jarFile, JavaJarASTGenerator jarAstGenerator)
{
// TODO: Read from jar file directly.
var classDir = @"/home/joao/dev/CppSharp/tests2/jar";
foreach (var file in Directory.EnumerateFiles(classDir, "*.class",
SearchOption.AllDirectories))
{
if (Path.GetFileNameWithoutExtension(file).StartsWith("class"))
continue;
var data = File.ReadAllBytes(file);
var parseOptions = ClassFileParseOptions.RemoveAssertions;
var classFile = new ClassFile(data, 0, data.Length, file, parseOptions, null);
jarAstGenerator.VisitClassFile(classFile);
}
}
}
}
Loading…
Cancel
Save