Weitere Aussonderung von Constraints durch Unify

This commit is contained in:
JanUlrich 2014-10-09 17:38:10 +02:00
parent efa79da5d5
commit 1141417c0b
13 changed files with 92 additions and 51 deletions

2
bin/.gitignore vendored
View File

@ -1,3 +1,5 @@
/de/ /de/
/mycompiler/ /mycompiler/
/plugindevelopment/ /plugindevelopment/
/bytecode/
/parser/

View File

@ -11,7 +11,7 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
public class ConsoleInterface { public class ConsoleInterface {
private static final String directory = System.getProperty("user.dir"); private static final String directory = System.getProperty("user.dir");
private static final Logger log = Logger.getLogger( ConsoleInterface.class.getName() );
/** /**
* @param args * @param args
*/ */
@ -20,7 +20,7 @@ public class ConsoleInterface {
for(String file : args){ for(String file : args){
filenames.add(file); filenames.add(file);
} }
Logger.setOutput(null); // sämtliches Logging unterdrücken Logger.setStandardOutput(null); // sämtliches Logging unterdrücken
run(filenames); run(filenames);
} }

View File

@ -66,13 +66,13 @@ public class MyCompiler implements MyCompilerAPI
// Logger // Logger
// ino.end // ino.end
// ino.attribute.codegenlog.21265.declaration // ino.attribute.codegenlog.21265.declaration
protected static Logger codegenlog = Logger.getLogger("codegen"); //protected static Logger codegenlog = Logger.getLogger("codegen");
// ino.end // ino.end
// ino.attribute.inferencelog.21268.declaration // ino.attribute.inferencelog.21268.declaration
protected static Logger inferencelog = Logger.getLogger("inference"); protected static Logger inferencelog = Logger.getLogger(MyCompiler.class.getName());
// ino.end // ino.end
// ino.attribute.parserlog.21271.declaration // ino.attribute.parserlog.21271.declaration
protected static Logger parserlog = Logger.getLogger("parser"); //protected static Logger parserlog = Logger.getLogger("parser");
// ino.end // ino.end
// ino.attribute.OutputDir.21274.declaration // ino.attribute.OutputDir.21274.declaration
@ -180,7 +180,7 @@ public class MyCompiler implements MyCompilerAPI
} }
else else
{ {
parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " muss weitere Parameter besitzen (laut Klassendefinition)" ); //parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " muss weitere Parameter besitzen (laut Klassendefinition)" );
//FIXME Throw exception instead of simple exit //FIXME Throw exception instead of simple exit
System.exit( 1 ); System.exit( 1 );
} }
@ -512,6 +512,8 @@ public class MyCompiler implements MyCompilerAPI
// ino.end // ino.end
// ino.method.typeReconstruction.21304.body // ino.method.typeReconstruction.21304.body
{ {
Logger.setStandardOutput(System.out); //TODO: Hier noch das Log-Level richtig setzen (je nachdem ob debugt wird oder nicht)
if(m_AbstractSyntaxTree==null){ if(m_AbstractSyntaxTree==null){
throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!"); throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!");
} }

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.logger;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Level;
public class Logger { public class Logger {
@ -9,17 +10,35 @@ public class Logger {
private static final HashMap<String, Logger> LOGGER_DIRECTORY = new HashMap<>(); private static final HashMap<String, Logger> LOGGER_DIRECTORY = new HashMap<>();
private String name; private String name;
private PrintStream output; private final java.util.logging.Logger log;
private Logger(String name, PrintStream output) { private Logger(String name, PrintStream output) {
this.name = name; this.name = name;
this.output = output; this.log = java.util.logging.Logger.getLogger( name );
if(output != null)log.addHandler(new OutputHandler(output));
log.setLevel(Level.FINE);
} }
public void debug(String message){ /**
output(message); * Logt eine Debug Message, welche zusätzlich einer bestimmten Section zugewiesen wird.
* Dadurch lässt sich die DEBUG ausgabe übersichtlicher gestalten.
* @param message
* @param section
*/
public void debug(String message, Section section){
output(message, Level.FINE);
} }
public void debug(String message){
//output(message, Level.FINE);
}
/**
* Liefert den Logger mit dem angegebenen Namen.
* Üblicherweise wird diese Methode mit dem Namen der Klasse aufgerufen, in welcher der Logger tätig ist.
* @param name - Name der Klasse ( Ermittelbar mittels <Klasse>.class.getName() )
* @return
*/
public static Logger getLogger(String name) { public static Logger getLogger(String name) {
Logger ret; Logger ret;
if(LOGGER_DIRECTORY.containsKey(name)){ if(LOGGER_DIRECTORY.containsKey(name)){
@ -31,22 +50,23 @@ public class Logger {
return ret; return ret;
} }
private void output(String msg){ private void output(String msg , Level logLevel){
log.log(logLevel, msg);
/*
if(output != null){ if(output != null){
output.println(msg); output.println(msg);
}else if(standardOutput != null){ }else if(standardOutput != null){
standardOutput.println(msg); standardOutput.println(msg);
} }
*/
} }
public void info(String string) { public void info(String message) {
// TODO Auto-generated method stub output(message, Level.INFO);
} }
public void error(String string) { public void error(String message) {
// TODO Auto-generated method stub output(message, Level.WARNING);
} }
/** /**

View File

@ -10,7 +10,7 @@ import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.core.AClassOrInterface; import de.dhbwstuttgart.core.AClassOrInterface;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.parser.JavaClassName;
@ -44,8 +44,8 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
* Log4j - Loggerinstanzen * Log4j - Loggerinstanzen
*/ */
protected static Logger inferencelog = Logger.getLogger("inference"); protected static Logger inferencelog = Logger.getLogger("inference");
protected static Logger codegenlog = Logger.getLogger("codegen"); //protected static Logger codegenlog = Logger.getLogger("codegen");
protected static Logger parserlog = Logger.getLogger("parser"); //protected static Logger parserlog = Logger.getLogger("parser");
protected UsedId pkgName; protected UsedId pkgName;
protected Modifiers modifiers; protected Modifiers modifiers;
protected String name; protected String name;
@ -137,9 +137,9 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
private TypeAssumptions typeAssumptions = null;//muss mit null Initialisiert werden. Darf nur über getTypeAssumptions abgerufen werden. private TypeAssumptions typeAssumptions = null;//muss mit null Initialisiert werden. Darf nur über getTypeAssumptions abgerufen werden.
// ino.attribute.parserlog.23038.declaration // ino.attribute.parserlog.23038.declaration
protected Logger parselog = Logger.getLogger("parser"); //protected Logger parselog = Logger.getLogger("parser");
// ino.end // ino.end
protected Logger typinferenzLog = Logger.getLogger("Typeinference"); protected Logger typinferenzLog = Logger.getLogger(Class.class.getName());
private SyntaxTreeNode parent; private SyntaxTreeNode parent;
private Vector<Field> fielddecl = new Vector<Field>(); private Vector<Field> fielddecl = new Vector<Field>();
private GenericDeclarationList genericClassParameters; private GenericDeclarationList genericClassParameters;
@ -267,7 +267,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
} }
parserlog.debug("Neue Klasse: " + name); //parserlog.debug("Neue Klasse: " + name);
} }
// ino.end // ino.end
@ -658,7 +658,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
////////////////////////////// //////////////////////////////
inferencelog.info("Rufe TRStart()..."); inferencelog.info("Rufe TRStart()...");
typinferenzLog.debug("Erstellte FiniteClosure: "+supportData); typinferenzLog.debug("Erstellte FiniteClosure: "+supportData, Section.TYPEINFERENCE);
////////////////////////////// //////////////////////////////
// Ab hier ... // Ab hier ...
// @author A10023 - Andreas Stadelmeier: // @author A10023 - Andreas Stadelmeier:
@ -677,7 +677,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
if(gparam instanceof GenericTypeVar)oderConstraints.add(((GenericTypeVar)gparam).TYPE(assumptions)); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen if(gparam instanceof GenericTypeVar)oderConstraints.add(((GenericTypeVar)gparam).TYPE(assumptions)); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
} }
typinferenzLog.debug("Erstellte Assumptions: "+assumptions); typinferenzLog.debug("Erstellte Assumptions: "+assumptions, Section.TYPEINFERENCE);
/* /*
//Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden. //Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden.
Vector<Expr> fieldInitializers = new Vector<Expr>(); Vector<Expr> fieldInitializers = new Vector<Expr>();
@ -696,7 +696,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
for(Field f:this.getFields()){ for(Field f:this.getFields()){
oderConstraints.add(f.TYPE(assumptions)); oderConstraints.add(f.TYPE(assumptions));
} }
typinferenzLog.debug("Erstellte Constraints: "+oderConstraints); typinferenzLog.debug("Erstellte Constraints: "+oderConstraints, Section.TYPEINFERENCE);
return oderConstraints; return oderConstraints;

View File

@ -11,6 +11,7 @@ import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.bytecode.ClassFile; import de.dhbwstuttgart.bytecode.ClassFile;
import de.dhbwstuttgart.core.AClassOrInterface; import de.dhbwstuttgart.core.AClassOrInterface;
import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompiler;
@ -673,12 +674,12 @@ public class SourceFile
//Assumptions der importierten Klassen sammeln: //Assumptions der importierten Klassen sammeln:
TypeAssumptions importAssumptions = this.makeBasicAssumptionsFromJRE(imports, true); TypeAssumptions importAssumptions = this.makeBasicAssumptionsFromJRE(imports, true);
globalAssumptions.add(importAssumptions); globalAssumptions.add(importAssumptions);
typinferenzLog.debug("Von JRE erstellte Assumptions: "+importAssumptions); typinferenzLog.debug("Von JRE erstellte Assumptions: "+importAssumptions, Section.TYPEINFERENCE);
//FiniteClosure generieren: //FiniteClosure generieren:
FC_TTO finiteClosure = this.makeFC(globalAssumptions); FC_TTO finiteClosure = this.makeFC(globalAssumptions);
typinferenzLog.debug("FiniteClosure: \n"+finiteClosure); typinferenzLog.debug("FiniteClosure: \n"+finiteClosure, Section.TYPEINFERENCE);
ConstraintsSet oderConstraints = new ConstraintsSet(); ConstraintsSet oderConstraints = new ConstraintsSet();
//Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln: //Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln:
@ -697,7 +698,7 @@ public class SourceFile
return retValue;}; return retValue;};
oderConstraints.filterWrongConstraints(unifier); oderConstraints.filterWrongConstraints(unifier);
oderConstraints.unifyUndConstraints(unifier); oderConstraints.unifyUndConstraints(unifier);
typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n"); typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE);
//Die Constraints in Pair's umwandeln (Karthesisches Produkt bilden): //Die Constraints in Pair's umwandeln (Karthesisches Produkt bilden):
Vector<Vector<Pair>> xConstraints = new Vector<Vector<Pair>>();// = oderConstraints.getConstraints(); Vector<Vector<Pair>> xConstraints = new Vector<Vector<Pair>>();// = oderConstraints.getConstraints();
for(Vector<UndConstraint> uC : oderConstraints.getConstraints()){ //mit dem getConstraints-Aufruf wird das Karthesische Produkt erzeugt. for(Vector<UndConstraint> uC : oderConstraints.getConstraints()){ //mit dem getConstraints-Aufruf wird das Karthesische Produkt erzeugt.
@ -707,7 +708,7 @@ public class SourceFile
} }
xConstraints.add(cons); xConstraints.add(cons);
} }
typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints); typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints, Section.TYPEINFERENCE);
finiteClosure.generateFullyNamedTypes(globalAssumptions); finiteClosure.generateFullyNamedTypes(globalAssumptions);
@ -781,7 +782,7 @@ public class SourceFile
result.addAll(unifyResult); result.addAll(unifyResult);
// Debugoutput:Vector<Vector<Pair>> // Debugoutput:Vector<Vector<Pair>>
typinferenzLog.debug("Unifiziertes Ergebnis: "+result); typinferenzLog.debug("Unifiziertes Ergebnis: "+result, Section.TYPEINFERENCE);
/* /*
// Prüfe ob eindeutige Lösung: // Prüfe ob eindeutige Lösung:
@ -803,7 +804,7 @@ public class SourceFile
//typinferenzLog.debug(supportData.getFiniteClosure()); //typinferenzLog.debug(supportData.getFiniteClosure());
//typinferenzLog.debug("Typinformationen: \n"+this.getTypeInformation(this.getMethodList(), fieldInitializers)); //typinferenzLog.debug("Typinformationen: \n"+this.getTypeInformation(this.getMethodList(), fieldInitializers));
typinferenzLog.debug("\nJavaFiles:\n"); typinferenzLog.debug("\nJavaFiles:\n", Section.TYPEINFERENCE);
//typinferenzLog.debug(this.printJavaCode(new ResultSet(new Vector<Pair>()))); //typinferenzLog.debug(this.printJavaCode(new ResultSet(new Vector<Pair>())));
@ -818,8 +819,8 @@ public class SourceFile
ret.add(reconstructionResult); ret.add(reconstructionResult);
//ResultSet res = new ResultSet(resultSet); //ResultSet res = new ResultSet(resultSet);
typinferenzLog.debug("JavaFile für ResultSet "+reconstructionResult+"\n"); typinferenzLog.debug("JavaFile für ResultSet "+reconstructionResult+"\n", Section.TYPEINFERENCE);
typinferenzLog.debug(klasse.printJavaCode(reconstructionResult)); typinferenzLog.debug(klasse.printJavaCode(reconstructionResult), Section.TYPEINFERENCE);
} }
} }

View File

@ -56,10 +56,10 @@ public class RefType extends Type implements IMatchable
private boolean primitiveFlag=false; private boolean primitiveFlag=false;
// ino.end // ino.end
// ino.attribute.parserlog.26628.declaration // ino.attribute.parserlog.26628.declaration
protected static Logger parserlog = Logger.getLogger("parser"); //protected static Logger parserlog = Logger.getLogger("parser");
// ino.end // ino.end
// ino.attribute.codegenlog.26631.declaration // ino.attribute.codegenlog.26631.declaration
protected static Logger codegenlog = Logger.getLogger("codegen"); //protected static Logger codegenlog = Logger.getLogger("codegen");
// ino.end // ino.end

View File

@ -6,7 +6,7 @@ package de.dhbwstuttgart.syntaxtree.type;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import java.util.logging.Logger; import de.dhbwstuttgart.logger.*;
import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.parser.JavaClassName;
@ -31,6 +31,7 @@ public class TypePlaceholder extends Type
// ino.end // ino.end
// ino.class.TypePlaceholder.26780.body // ino.class.TypePlaceholder.26780.body
{ {
private static final Logger log = Logger.getLogger(TypePlaceholder.class.getName());
// ino.attribute.strNextName.26785.declaration // ino.attribute.strNextName.26785.declaration
private static String strNextName = "A"; private static String strNextName = "A";
// ino.end // ino.end
@ -55,6 +56,7 @@ public class TypePlaceholder extends Type
{ {
super(parent, -1); super(parent, -1);
this.name = new JavaClassName(typeName); this.name = new JavaClassName(typeName);
if(parent != null)log.debug("Erstelle TPH "+typeName+" für SyntaxTreeNode: "+parent, Section.TYPEINFERENCE);
} }
// ino.end // ino.end

View File

@ -2,10 +2,12 @@ package de.dhbwstuttgart.typeinference;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.*;
import de.dhbwstuttgart.typeinference.unify.Unifier; import de.dhbwstuttgart.typeinference.unify.Unifier;
public class ConstraintsSet implements Iterable<OderConstraint>{ public class ConstraintsSet implements Iterable<OderConstraint>{
private static final Logger log = Logger.getLogger(ConstraintsSet.class.getName());
private Vector<OderConstraint> constraintsSet; private Vector<OderConstraint> constraintsSet;
public ConstraintsSet(){ public ConstraintsSet(){
@ -58,14 +60,26 @@ public class ConstraintsSet implements Iterable<OderConstraint>{
} }
} }
/**
* Nimmt alle UndConstraints und filtert mithilfe dieser die falschen Constraints aus den OderConstraints
* @param unifier
*/
public void unifyUndConstraints(Unifier unifier) { public void unifyUndConstraints(Unifier unifier) {
Vector<UndConstraint> uCons = this.filterUndConstraints(); Vector<UndConstraint> uCons = this.filterUndConstraints();
Vector<Pair> alleUndConstraints = new Vector<>(); Vector<Pair> alleUndConstraints = new Vector<>();
for(UndConstraint undConstraint : uCons){ for(UndConstraint undConstraint : uCons){
alleUndConstraints.addAll(undConstraint.getConstraintPairs()); alleUndConstraints.addAll(undConstraint.getConstraintPairs());
} }
Vector<Vector<Pair>> unifyResult = unifier.apply(alleUndConstraints); this.filterWrongConstraints(
(pairs)->{
Vector<Pair> undConstraintsUndPairs = new Vector<>();
undConstraintsUndPairs.addAll(pairs);
undConstraintsUndPairs.addAll(alleUndConstraints);
log.debug("Versuche Pairs auszusondern:\n"+pairs, Section.TYPEINFERENCE);
log.debug("Unifiziere:\n"+undConstraintsUndPairs, Section.TYPEINFERENCE);
Vector<Vector<Pair>> unifyResult = unifier.apply(undConstraintsUndPairs);
return unifyResult;
});
} }
/** /**

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@ -90,13 +91,16 @@ public class OderConstraint{
if(!unifierResult.isEmpty()){ if(!unifierResult.isEmpty()){
filteredConstraints.add(cons); filteredConstraints.add(cons);
}else{ }else{
logger.debug("Ausgesondertes Constraint: "+cons); logger.debug("Ausgesondertes Constraint: "+cons, Section.TYPEINFERENCE);
} }
} }
this.oderConstraintPairs = filteredConstraints; this.oderConstraintPairs = filteredConstraints;
} }
UndConstraint filterUndConstraints() { UndConstraint filterUndConstraints() {
if(this.oderConstraintPairs.size()==1){
return this.oderConstraintPairs.firstElement();
}
return null; return null;
} }

View File

@ -121,7 +121,7 @@ public class Pair
if(OperatorSmallerExtends()) if(OperatorSmallerExtends())
Operator = "<?"; Operator = "<?";
return "(" + strElement1 + " " + Operator + " " + strElement2 + ")"; return "\n(" + strElement1 + " " + Operator + " " + strElement2 + ")";
/*- Equals: " + bEqual*/ /*- Equals: " + bEqual*/
} }

View File

@ -4,6 +4,7 @@ import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
@ -31,12 +32,7 @@ import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
*/ */
public class TypeAssumptions { public class TypeAssumptions {
/* private static final Logger log = Logger.getLogger( TypeAssumptions.class.getName() );
* Folgende Vorgehensweise:
* -Lokale Variablen werden in einem extra AssumptionSet gespeichert. Das Assumption Set hat nicht die Aufgabe Closures zu verwalten.
* -... genauso verhält es sich für Parameter. Parameter verhalten sich beim Abrufen wie lokale Variablen, werden aber zuerst durchsucht.
*
*/
//private static CTypeAssumptionSet globalAssumptions = new CTypeAssumptionSet(); //private static CTypeAssumptionSet globalAssumptions = new CTypeAssumptionSet();
private JavaClassName thisClassName; private JavaClassName thisClassName;
@ -367,7 +363,7 @@ public class TypeAssumptions {
*/ */
public ConstructorAssumption getConstructorAssumption(String name, int size) { public ConstructorAssumption getConstructorAssumption(String name, int size) {
for(ConstructorAssumption ca : this.constructorAssumptions){ for(ConstructorAssumption ca : this.constructorAssumptions){
System.out.println(ca.getIdentifier().toString() + ca.getParaCount()); log.debug("Durchsuche Assumptions: "+ca.getIdentifier().toString() +" -Anzahl Parameter: "+ ca.getParaCount());
if(ca.getParaCount()==size && ca.getIdentifier().equals(name))return ca; if(ca.getParaCount()==size && ca.getIdentifier().equals(name))return ca;
} }
return null; return null;

View File

@ -23,7 +23,7 @@ import junit.framework.TestCase;
public class TypeInsertTester{ public class TypeInsertTester{
private static Logger inferencelog = Logger.getLogger("Typeinference"); private static Logger inferencelog = Logger.getLogger(TypeInsertTester.class.getName());
static{ static{
{ {
Logger.setStandardOutput(System.out); Logger.setStandardOutput(System.out);