GlobalGenerics eingeführt

This commit is contained in:
JanUlrich 2017-09-20 23:41:06 +02:00
parent 8ce017c2f2
commit 0e2390a80a
6 changed files with 96 additions and 20 deletions

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.core;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
@ -80,7 +81,7 @@ public class JavaTXCompiler {
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile));
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null));
SourceFile ret = generator.convert(tree);
return ret;
}

View File

@ -1,7 +1,49 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
public class GenericsRegistry extends HashMap<String, GenericContext> {
public class GenericsRegistry {
private final List<GenericVariable> registry = new ArrayList<>();
public final GenericsRegistry globalRegistry;
public GenericsRegistry(GenericsRegistry globalRegistry){
this.globalRegistry = globalRegistry;
}
public void put(String name, GenericContext genericContext){
registry.add(new GenericVariable(genericContext,name));
if(globalRegistry != null)globalRegistry.put(name, genericContext);
}
public boolean contains(String name) {
Optional<Boolean> ret = registry.stream().<Boolean>map(((GenericVariable genericVariable) -> genericVariable.name.equals(name)))
.reduce(((a, b) -> a || b));
if(ret.isPresent())
return ret.get();
return false;
}
public GenericContext get(String name) {
return registry.stream()
.filter((genericVariable -> genericVariable.name.equals(name))).findAny().get().context;
}
public void putAll(GenericsRegistry generics) {
for(GenericVariable generic : generics.registry){
this.put(generic.name, generic.context);
}
}
}
class GenericVariable{
final GenericContext context;
final String name;
GenericVariable(GenericContext context, String name){
this.context = context;
this.name = name;
}
}

View File

@ -27,12 +27,17 @@ import org.antlr.v4.runtime.tree.TerminalNode;
public class SyntaxTreeGenerator{
private JavaClassRegistry reg;
private final GenericsRegistry globalGenerics;
private String pkgName = "";
List<JavaClassName> imports = new ArrayList();
List<Statement> fieldInitializations = new ArrayList<>();
public SyntaxTreeGenerator(JavaClassRegistry reg){
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics){
//Die Generics müssen während des Bauens des AST erstellt werden,
// da diese mit der Methode oder Klasse, in welcher sie deklariert werden
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer globalen Datenbank benötigt.
this.globalGenerics = globalGenerics;
this.reg = reg;
}
@ -434,7 +439,7 @@ public class SyntaxTreeGenerator{
}
private GenericsRegistry createGenerics(Java8Parser.TypeParametersContext ctx, JavaClassName parentClass, String parentMethod) {
GenericsRegistry ret = new GenericsRegistry();
GenericsRegistry ret = new GenericsRegistry(this.globalGenerics);
if(ctx == null || ctx.typeParameterList() == null)return ret;
for(Java8Parser.TypeParameterContext tp : ctx.typeParameterList().typeParameter()){
TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret);

View File

@ -16,6 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import javassist.bytecode.stackmap.TypeData;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
@ -76,13 +77,37 @@ public class TypeGenerator {
}
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if(typeBoundContext == null){
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
ret.add(ASTFactory.createObjectClass().getType());
return ret;
}
if(typeBoundContext.typeVariable() != null){
ret.add(convert(typeBoundContext.typeVariable()));
return ret;
}
if(typeBoundContext.classOrInterfaceType() != null){
ret.add(convert(typeBoundContext.classOrInterfaceType()));
if(typeBoundContext.additionalBound() != null)
for(Java8Parser.AdditionalBoundContext addCtx : typeBoundContext.additionalBound()){
ret.add(convert(addCtx.interfaceType()));
}
return ret;
}else{
throw new NotImplementedException();
}
}
throw new de.dhbwstuttgart.exceptions.NotImplementedException();
private static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.ClassOrInterfaceTypeContext classOrInterfaceTypeContext) {
throw new NotImplementedException();
}
private static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.InterfaceTypeContext interfaceTypeContext) {
throw new NotImplementedException();
}
private static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.TypeVariableContext typeVariableContext) {
throw new NotImplementedException();
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.ReferenceTypeContext referenceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
@ -96,7 +121,7 @@ public class TypeGenerator {
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(
String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein
if(generics.keySet().contains(name)){
if(generics.contains(name)){
return new GenericRefType(new GenericTypeName(generics.get(name),name), offset);
}else{
throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset);

View File

@ -3,6 +3,9 @@ package de.dhbwstuttgart.parser.scope;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.parser.antlr.Java8BaseListener;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
import org.antlr.v4.runtime.tree.TerminalNode;
import de.dhbwstuttgart.environment.PackageCrawler;
@ -10,17 +13,6 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser;
public class GatherNames {
private static String getPackageName(Java8Parser.CompilationUnitContext ctx){
String pkgName = "";
if(ctx.packageDeclaration() != null){
for(TerminalNode t : ctx.packageDeclaration().Identifier()){
pkgName = pkgName + "." + t.toString();
}
pkgName = pkgName.substring(1);
}
return pkgName;
}
public static List<String> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{
List<String> ret = new ArrayList<>();
String pkgName = getPackageName(ctx);
@ -89,4 +81,15 @@ public class GatherNames {
}
return ret;
}
private static String getPackageName(Java8Parser.CompilationUnitContext ctx){
String pkgName = "";
if(ctx.packageDeclaration() != null){
for(TerminalNode t : ctx.packageDeclaration().Identifier()){
pkgName = pkgName + "." + t.toString();
}
pkgName = pkgName.substring(1);
}
return pkgName;
}
}

View File

@ -1,6 +1,6 @@
class Generics<B> {
<A> A mt1(A a, B b){
<A extends B> A mt1(A a, B b){
return mt1(a, a);
}
}