From 0e2390a80a0fb83181a5b0bc5a757aebce26d5de Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Sep 2017 23:41:06 +0200 Subject: [PATCH] =?UTF-8?q?GlobalGenerics=20eingef=C3=BChrt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 3 +- .../SyntaxTreeGenerator/GenericsRegistry.java | 44 ++++++++++++++++++- .../SyntaxTreeGenerator.java | 9 +++- .../SyntaxTreeGenerator/TypeGenerator.java | 31 +++++++++++-- .../parser/scope/GatherNames.java | 27 +++++++----- test/javFiles/Generics.jav | 2 +- 6 files changed, 96 insertions(+), 20 deletions(-) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 10371436..49df92e7 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -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; } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/GenericsRegistry.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/GenericsRegistry.java index 08212fc9..95a12ef6 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/GenericsRegistry.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/GenericsRegistry.java @@ -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 { +public class GenericsRegistry { + private final List 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 ret = registry.stream().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; + } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 3980369d..f9df6fb3 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -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 imports = new ArrayList(); List 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); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index ed46ee0e..a348622f 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -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 convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { + List ret = new ArrayList<>(); if(typeBoundContext == null){ - List 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); diff --git a/src/de/dhbwstuttgart/parser/scope/GatherNames.java b/src/de/dhbwstuttgart/parser/scope/GatherNames.java index 919dc386..2ec6d8ab 100644 --- a/src/de/dhbwstuttgart/parser/scope/GatherNames.java +++ b/src/de/dhbwstuttgart/parser/scope/GatherNames.java @@ -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 getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ List 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; + } +} \ No newline at end of file diff --git a/test/javFiles/Generics.jav b/test/javFiles/Generics.jav index 9e4361a9..477d2296 100644 --- a/test/javFiles/Generics.jav +++ b/test/javFiles/Generics.jav @@ -1,6 +1,6 @@ class Generics { - A mt1(A a, B b){ + A mt1(A a, B b){ return mt1(a, a); } }