package platformSpecific.javaTranslation; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; import platformSpecific.inMemoryCompiler.InMemoryJavaCompiler; import platformSpecific.inMemoryCompiler.InMemoryJavaCompiler.CompilationError; import platformSpecific.inMemoryCompiler.InMemoryJavaCompiler.MapClassLoader; import platformSpecific.inMemoryCompiler.InMemoryJavaCompiler.SourceFile; import profiling.Timer; import reduction.Facade; import tools.Assertions; import coreVisitors.From; import coreVisitors.IsCompiled; import facade.Configuration; import facade.L42; import auxiliaryGrammar.Functions; import programReduction.Program; import programReduction.Program.EmptyProgram; import ast.Ast; import ast.Ast.Doc; import ast.Ast.InterfaceHeader; import ast.Ast.NormType; import ast.Ast.Path; import ast.Ast.Stage; import ast.ExpCore; import ast.ExpCore.ClassB; import ast.ExpCore.ClassB.Member; import ast.ExpCore.ClassB.NestedClass; import ast.ExpCore.ClassB.Phase; import ast.Util; import ast.Util.PathMwt; import ast.ExpCore.*; public class Translator { public Object runMap(){ try{return runStringExc();} catch (InvocationTargetException ex) { if (ex.getCause() instanceof RuntimeException) throw (RuntimeException)ex.getCause(); if (ex.getCause() instanceof Error) throw (Error)ex.getCause(); throw new Error(ex.getCause()); } catch(CompilationError| IllegalAccessException| IllegalArgumentException| NoSuchMethodException| SecurityException| ClassNotFoundException e){ throw new Error(e); } } public Object runStringExc() throws CompilationError, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException { List<SourceFile> files =new ArrayList<>(); for(String k :map.keySet()){//"generated.Program42"; files.add(new SourceFile(k,map.get(k))); //try{Files.write(Paths.get("/u/staff/servetto/git/L42/Tests/src/generated/"+k+".java"), map.get(k).getBytes());}catch (IOException _e) {throw new Error(_e);} //try{Files.write(Paths.get("C:/Users/user/git/L42/Tests/src/generated/"+k+".java"), map.get(k).getBytes());}catch (IOException _e) {throw new Error(_e);} } //System.out.println("Compilation Iteration ready to compile"); MapClassLoader cl=((Facade)Configuration.reduction).getLastLoader(); Timer.activate("InMemoryJavaCompiler.compile");try{ cl=InMemoryJavaCompiler.compile(cl==null?ClassLoader.getSystemClassLoader():cl,files);//can throw, no closure possible ((Facade)Configuration.reduction).setLastLoader(cl); }finally{ Timer.deactivate("InMemoryJavaCompiler.compile");} //System.out.println("Compilation Iteration complete compilation, start class loading"); Class<?> cl0 = cl.loadClass("generated."+this.mainName); //System.out.println("Compilation Iteration start method retrival"); Method m0 = cl0.getDeclaredMethod("execute0"); //System.out.println("Compilation Iteration ready to execute"); assert Resources.getP()!=null; Timer.activate("InMemoryJavaCompiler.execute");try{ Object result = m0.invoke(null); //System.out.println("Compilation Iteration execution complete"); return result; }finally{Timer.deactivate("InMemoryJavaCompiler.execute");} } HashMap<String,String> map; String mainName; public static Translator translateProgram(Program p,ExpCore e){ Translator t=new Translator(); t.map=new HashMap<>(); //Resources.clearRes(); Map<String,ClassB> map=new LinkedHashMap<String,ClassB>(); Map<String,ClassB> mapNorm=new LinkedHashMap<String,ClassB>(); addP(0,p,map,p); { StringBuilder res=new StringBuilder(); t.mainName=Functions.freshName("Execute_",L42.usedNames); res.append("package generated;"); res.append("@SuppressWarnings(\"all\")"); res.append("public class "+t.mainName+"{\n"); res.append("public static Object execute0()"); TranslateExpression.of(e, res); res.append("\n"); res.append("}"); t.map.put(t.mainName, res.toString()); } MapClassLoader cl=((Facade)Configuration.reduction).getLastLoader(); for(String s:map.keySet()){ if (cl!=null && cl.map().containsKey("generated."+s)){ continue; //ClassB cb=map.get(s); //if(!cb.getDoc1().getS().contains("##@")){continue;} } if (map.get(s).getPhase()!=Phase.Coherent){continue;} ClassB cbNorm=map.get(s);//Hope it work, it was normalized before assert cbNorm.getPhase()==Phase.Coherent; mapNorm.put(s,cbNorm); } for(String s:mapNorm.keySet()){ StringBuilder resi=new StringBuilder(); resi.append("package generated;"); resi.append("@SuppressWarnings(\"all\")"); ClassB cbNorm = mapNorm.get(s); assert cbNorm.getPhase()==Phase.Coherent; TranslateClass.of(p,s,mapNorm.get(s),resi); String resiS=resi.toString(); t.map.put(s, resiS); } return t; } public static void addP(int level,Program p,Map<String,ClassB> map,Program original){ add(level,Collections.emptyList(),p.top(),map,original); Program popped;try{popped=p.pop();}catch(EmptyProgram ep){return;} addP(level+1,popped,map,original); } public static void add(int level,List<Ast.C> cs,ClassB cb, Map<String,ClassB> map,Program original){ Ast.Path p=Ast.Path.outer(level, cs); if(cb.getPhase()==Phase.Coherent && IsCompiled.of(cb)){//otherwise is "meta" //assert cb.getStage().getInheritedPaths()!=null; ClassB cbUF=useFrom(cb,p); if(!cs.isEmpty()){//ok to ignore empty ones, since not complete? map.put(Resources.nameOf(level,cs),cbUF); } } else{//generate only for metaprogramming //Can be ignored now with typemap /*ExpCore.ClassB cbMP = new ExpCore.ClassB( Doc.factory("##@DebugInfo: is interface since (cb.getStage()!=Stage.Star :" +(cb.getStage().getStage()!=Stage.Star)+") or since !IsCompiled.of(cb) :"+!IsCompiled.of(cb)+")" ),Doc.empty(),true,Collections.emptyList(),Collections.emptyList(),new Util.CachedStage()); cbMP.getStage().setInheritedPaths(Collections.emptyList()); cbMP.getStage().setInherited(Collections.emptyList()); assert cbMP.getStage().getInheritedPaths()!=null; map.put(Resources.nameOf(level,cs),cbMP); */} for(Member m:cb.getMs()){ if (!(m instanceof NestedClass)){continue;} NestedClass nc=(NestedClass)m; if(!(nc.getInner() instanceof ClassB)){continue;} if(cs.isEmpty() &&level>0){ if(nc.getInner()==original.get(level-1)){continue;} //avoid generation of multiple versions of the same thing } ArrayList<Ast.C> newCs=new ArrayList<>(cs); newCs.add(nc.getName()); add(level,newCs,(ClassB) nc.getInner(),map,original); } } //this should take a class, strip out nested and 'from' it so that it is as at top level static ClassB useFrom(ClassB ct, Path p) { ArrayList<Member> ms=new ArrayList<Member>(); for(Member m:ct.getMs()){ m.match(nc->null, mi->{throw Assertions.codeNotReachable();}, mt->ms.add(From.from(mt, p)) ); } //for(PathMwt pmwt:ct.getStage().getInherited()){ for(PathMwt pmwt:Collections.<PathMwt>emptyList()){ if(Functions.getIfInDom(ms,pmwt.getMwt().getMs()).isPresent()){continue;} ms.add(From.from(pmwt.getMwt(), p)); } List<Path> sup = tools.Map.of(ti->(Path)From.fromP(ti.getNT().getPath(),p),ct.getSupertypes()); List<Path> supAll = sup;//tools.Map.of(pi->(Path)From.fromP(pi,p),ct.getStage().getInheritedPaths()); ClassB res= ct.withMs(ms).withSupertypes(tools.Map.of(pi->pi.toImmNT(),sup)); return res; } }