JavaPatternMatching/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java

335 lines
13 KiB
Java
Raw Normal View History

2017-03-15 15:17:07 +00:00
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
2017-03-17 14:48:06 +00:00
import de.dhbwstuttgart.exceptions.NotImplementedException;
2017-03-15 15:17:07 +00:00
import de.dhbwstuttgart.parser.InvalidClassNameException;
2017-03-22 15:05:59 +00:00
import de.dhbwstuttgart.parser.NullToken;
2017-03-15 15:17:07 +00:00
import de.dhbwstuttgart.parser.PackageCrawler;
import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*;
2017-03-17 14:48:06 +00:00
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
2017-03-15 15:17:07 +00:00
import de.dhbwstuttgart.syntaxtree.statement.*;
2017-03-17 14:48:06 +00:00
import de.dhbwstuttgart.syntaxtree.type.RefType;
2017-03-16 19:02:53 +00:00
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
2017-03-22 15:16:38 +00:00
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
2017-03-15 15:17:07 +00:00
import de.dhbwstuttgart.typecheck.*;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNode;
public class SyntaxTreeGenerator{
private JavaClassRegistry reg;
private String pkgName = "";
List<JavaClassName> imports = new ArrayList();
2017-03-22 15:05:59 +00:00
private GenericsRegistry generics = new GenericsRegistry();
2017-03-15 15:17:07 +00:00
public SyntaxTreeGenerator(JavaClassRegistry reg){
this.reg = reg;
}
public void setPackageName(Java8Parser.CompilationUnitContext ctx){
if(ctx.packageDeclaration() != null){
for(TerminalNode t : ctx.packageDeclaration().Identifier()){
this.pkgName = this.pkgName + "." + t.toString();
}
this.pkgName = this.pkgName.substring(1);
}
}
public void getNames(Java8Parser.CompilationUnitContext ctx){
if(this.pkgName == "") this.setPackageName(ctx);
String nameString = "";
for (Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){
if(typeDecl.interfaceDeclaration() != null){
if(typeDecl.interfaceDeclaration().normalInterfaceDeclaration() != null){
if(this.pkgName != ""){
nameString = this.pkgName + "." + typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString();
}
else{
nameString = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString();
}
2017-03-22 15:05:59 +00:00
//Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry anfügen:
2017-03-15 15:17:07 +00:00
if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){
for(Java8Parser.TypeParameterContext tp : typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter()){
2017-03-22 15:05:59 +00:00
//this.reg.add(tp.Identifier().toString());
2017-03-15 15:17:07 +00:00
}
}
this.reg.add(nameString);
}
}
else{
if(typeDecl.classDeclaration().normalClassDeclaration() != null){
if(this.pkgName != ""){
nameString = this.pkgName + "." + typeDecl.classDeclaration().normalClassDeclaration().Identifier().toString();
}
else{
nameString = typeDecl.classDeclaration().normalClassDeclaration().Identifier().toString();
}
//Die Generic TypeParameter Definitionen ebenfalls an die JavaClassName-Registry anfügen:
if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){
for(Java8Parser.TypeParameterContext tp : typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter()){
this.reg.add(tp.Identifier().toString());
}
}
this.reg.add(nameString);
}
}
}
}
public JavaClassRegistry getReg(){
return this.reg;
}
// Converts type name to String.
public String convertTypeName(Java8Parser.TypeNameContext ctx){
String ret;
if(ctx.packageOrTypeName() == null){
ret = ctx.Identifier().toString();
}
else{
ret = convertPackageOrTypeName(ctx.packageOrTypeName()) + "." + ctx.Identifier().toString();
}
return ret;
}
// Converts PackageOrTypeName to String.
public String convertPackageOrTypeName(Java8Parser.PackageOrTypeNameContext ctx){
String ret;
if(ctx.packageOrTypeName() == null){
ret = ctx.Identifier().toString();
}
else{
ret = convertPackageOrTypeName(ctx.packageOrTypeName()) + "." + ctx.Identifier().toString();
}
return ret;
}
public void setImports(Java8Parser.CompilationUnitContext ctx) throws InvalidClassNameException {
List<JavaClassName> newImports = new ArrayList();
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){
if(importDeclCtx.singleTypeImportDeclaration() != null){
newImports.add(convertSingleTypeImportDeclaration(importDeclCtx.singleTypeImportDeclaration()));
}
else if(importDeclCtx.typeImportOnDemandDeclaration() != null){
newImports.add(convertTypeImportOnDemandDeclaration(importDeclCtx.typeImportOnDemandDeclaration()));
}
else if(importDeclCtx.singleStaticImportDeclaration() != null){
newImports.add(convertSingleStaticImportDeclaration(importDeclCtx.singleStaticImportDeclaration()));
}
else{
newImports.add(convertStaticImportOnDemandDeclaration(importDeclCtx.staticImportOnDemandDeclaration()));
}
}
this.imports.addAll(newImports);
}
private JavaClassName convertSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) throws InvalidClassNameException{
String typeName = convertTypeName(ctx.typeName());
String packageName = getPackageFromClass(typeName);
List<JavaClassName> classes = PackageCrawler.getClassNames(packageName);
reg.add(typeName);
JavaClassName ret = reg.getName(typeName);
if(classes.contains(ret)){
return ret;
}
else{
throw new InvalidClassNameException();
}
}
private JavaClassName convertTypeImportOnDemandDeclaration(Java8Parser.TypeImportOnDemandDeclarationContext ctx){
return null;
}
private JavaClassName convertSingleStaticImportDeclaration(Java8Parser.SingleStaticImportDeclarationContext ctx){
return null;
}
private JavaClassName convertStaticImportOnDemandDeclaration(Java8Parser.StaticImportOnDemandDeclarationContext ctx){
return null;
}
private String getPackageFromClass(String cls){
String ret = "";
String[] parts = cls.split("\\.");
for(int i = 0; i < parts.length - 1; i++){
ret = ret + "." + parts[i];
}
ret = ret.substring(1);
return ret;
}
public SourceFile convert(Java8Parser.CompilationUnitContext ctx){
List<ClassOrInterface> classes = new ArrayList<>();
this.getNames(ctx);
for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){
ClassOrInterface newClass;
if(typeDecl.classDeclaration() != null){
newClass = convertClass(typeDecl.classDeclaration());
}
else{
newClass = convertInterface(typeDecl.interfaceDeclaration());
}
classes.add(newClass);
}
return new SourceFile(this.pkgName, classes, this.imports);
}
private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) {
ClassOrInterface newClass;
if(ctx.normalClassDeclaration() != null){
newClass = convertNormal(ctx.normalClassDeclaration());
}
else{
newClass = convertEnum(ctx.enumDeclaration());
}
return newClass;
}
private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx){
int modifiers = 0;
if(ctx.classModifier() != null){
for(Java8Parser.ClassModifierContext mod : ctx.classModifier()){
int newModifier = convert(mod);
modifiers += newModifier;
}
}
JavaClassName name = reg.getName(ctx.Identifier().getText());
2017-03-29 15:28:29 +00:00
GenericDeclarationList genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics);
2017-03-15 15:17:07 +00:00
List<Field> fielddecl = convertFields(ctx.classBody());
2017-03-29 15:28:29 +00:00
List<Method> methods = convertMethods(ctx.classBody(), name);
2017-03-22 15:05:59 +00:00
2017-03-15 15:17:07 +00:00
Token offset = ctx.getStart();
2017-03-17 14:48:06 +00:00
RefType superClass ;
if(ctx.superclass() != null){
superClass = convert(ctx.superclass());
}else{
superClass = new ASTFactory(reg).createObjectClass().getType();
}
2017-03-15 15:17:07 +00:00
Boolean isInterface = false;
2017-03-16 19:02:53 +00:00
List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = null;
2017-03-15 15:17:07 +00:00
return new ClassOrInterface(modifiers, name, fielddecl, methods, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
}
2017-03-17 14:48:06 +00:00
private RefType convert(Java8Parser.SuperclassContext superclass) {
throw new NotImplementedException();
}
2017-03-29 15:28:29 +00:00
private List<Method> convertMethods(Java8Parser.ClassBodyContext classBodyContext, JavaClassName parentClass) {
2017-03-15 15:17:07 +00:00
List<Method> ret = new ArrayList<>();
for(Java8Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()){
if(classMember.classMemberDeclaration() != null){
Java8Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration();
if(classMemberDeclarationContext.fieldDeclaration() != null){
//Do nothing!
}else if(classMemberDeclarationContext.methodDeclaration()!= null){
2017-03-22 15:05:59 +00:00
StatementGenerator stmtGen = new StatementGenerator(reg, generics);
2017-03-29 15:28:29 +00:00
ret.add(stmtGen.convert(classMemberDeclarationContext.methodDeclaration(), parentClass));
2017-03-15 15:17:07 +00:00
}
}
}
return ret;
}
private List<Field> convertFields(Java8Parser.ClassBodyContext classBodyContext) {
List<Field> ret = new ArrayList<>();
for(Java8Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()){
if(classMember.classMemberDeclaration() != null){
Java8Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration();
if(classMemberDeclarationContext.fieldDeclaration() != null){
ret.addAll(convert(classMember.classMemberDeclaration().fieldDeclaration()));
}else if(classMemberDeclarationContext.methodDeclaration()!= null){
//Do nothing!
}
}
}
return ret;
}
public static int convert(List<Java8Parser.MethodModifierContext> methodModifierContexts) {
int ret = 0;
for(Java8Parser.MethodModifierContext mod : methodModifierContexts){
if(mod.annotation() == null)convertModifier(mod.getText());
}
return ret;
}
private List<? extends Field> convert(Java8Parser.FieldDeclarationContext fieldDeclarationContext) {
List<Field> ret = new ArrayList<>();
int modifiers = 0;
for(Java8Parser.FieldModifierContext fieldModifierContext : fieldDeclarationContext.fieldModifier()){
modifiers+=(convert(fieldModifierContext));
}
2017-03-22 15:16:38 +00:00
RefTypeOrTPHOrWildcardOrGeneric fieldType;
if(fieldDeclarationContext.unannType() != null){
fieldType = TypeGenerator.convert(fieldDeclarationContext.unannType(), reg, generics);
}else{
fieldType = TypePlaceholder.fresh(fieldDeclarationContext.getStart());
}
2017-03-15 15:17:07 +00:00
for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){
String fieldName = convert(varCtx.variableDeclaratorId());
if(varCtx.variableInitializer() != null){
initializeField(fieldDeclarationContext);
}
else{
ret.add(new Field(fieldName,fieldType,modifiers,varCtx.getStart()));
}
}
return ret;
}
public static String convert(Java8Parser.VariableDeclaratorIdContext variableDeclaratorIdContext) {
return variableDeclaratorIdContext.getText();
}
// Initialize a field by creating implicit constructor.
private void initializeField(Java8Parser.FieldDeclarationContext ctx){
//TODO
}
public static int convertModifier(String modifier){
HashMap<String, Integer> modifiers = new HashMap<>();
modifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC);
modifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE);
modifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED);
modifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT);
modifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC);
modifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT);
modifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL);
modifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT);
modifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE);
modifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED);
modifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE);
modifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
int ret = 0;
for(String m : modifiers.keySet()){
if(modifier.startsWith(m))ret+=modifiers.get(m);
}
return ret;
}
private int convert(Java8Parser.ClassModifierContext ctx){
if(ctx.annotation() != null)return 0;
return convertModifier(ctx.getText());
}
private int convert(Java8Parser.FieldModifierContext ctx){
if(ctx.annotation() != null)return 0;
return convertModifier(ctx.getText());
}
private ClassOrInterface convertEnum(Java8Parser.EnumDeclarationContext ctx){
return null;
}
private ClassOrInterface convertInterface(Java8Parser.InterfaceDeclarationContext ctx){
return null;
}
}