PageRenderTime 323ms CodeModel.GetById 141ms app.highlight 9ms RepoModel.GetById 171ms app.codeStats 1ms

/src/org/ooc/middle/hobgoblins/Resolver.java

http://github.com/nddrylliog/ooc
Java | 124 lines | 97 code | 21 blank | 6 comment | 18 complexity | e63d9c46118e606cc59de85bd1fc944d MD5 | raw file
  1package org.ooc.middle.hobgoblins;
  2
  3import java.io.IOException;
  4
  5import org.ooc.frontend.BuildParams;
  6import org.ooc.frontend.model.Module;
  7import org.ooc.frontend.model.Node;
  8import org.ooc.frontend.model.NodeList;
  9import org.ooc.frontend.model.TypeDecl;
 10import org.ooc.frontend.model.interfaces.MustBeResolved;
 11import org.ooc.frontend.model.interfaces.MustBeResolved.Response;
 12import org.ooc.frontend.model.tokens.Token;
 13import org.ooc.middle.Hobgoblin;
 14import org.ooc.middle.OocCompilationError;
 15import org.ooc.middle.walkers.Opportunist;
 16import org.ooc.middle.walkers.SketchyNosy;
 17
 18
 19public class Resolver implements Hobgoblin {
 20
 21	protected static final int MAX = 4, SAFE_MAX = 1024;
 22	boolean running = false;
 23	boolean restarted = false;
 24	public boolean fatal = false;
 25	
 26	static int restartCount = 0;
 27	
 28	public BuildParams params;
 29	public Module module;
 30	private int ghostingCount = 1;
 31	
 32	public boolean process(Module module, final BuildParams params) throws IOException {
 33		
 34		this.module = module;
 35		this.params = params;
 36		
 37		// FIXME this is a hack to allow early removal of ghost type-arguments
 38		// in TypeDecls. see their resolve() method. This is non-optimal, and due
 39		// to the fact that in j/ooc, things are resolved depth-first. It's not
 40		// the same in rock, where each node is responsible of resolving their
 41		// children nodes.
 42		
 43		if(ghostingCount-- > 0) {
 44			NodeList<Node> stack = new NodeList<Node>(Token.defaultToken);
 45			stack.push(module);
 46			for(TypeDecl typeDecl: module.getTypes().values()) {
 47				typeDecl.resolve(stack, this, false);
 48			}
 49			return true;
 50		}
 51		
 52		SketchyNosy nosy = SketchyNosy.get(new Opportunist<Node>() {
 53			public boolean take(Node node, NodeList<Node> stack) throws IOException {
 54				if(node instanceof MustBeResolved) {
 55					MustBeResolved must = (MustBeResolved) node;
 56					if(!must.isResolved()) {
 57						Response res = Response.OK;
 58						try {
 59							res = must.resolve(stack, Resolver.this, fatal);
 60						} catch(OocCompilationError e) {
 61							if(params.veryVerbose) {
 62								e.printStackTrace();
 63							} else {
 64								throw e;
 65							}
 66						}
 67						if(res == Response.LOOP) {
 68							if(fatal) {
 69								System.out.println(must+" has LOOPed in fatal round.");
 70							}
 71							//System.out.println(must+" has LOOPed.");
 72							running = true;
 73						} else if(res == Response.RESTART) {
 74							if(fatal) {
 75								System.out.println(must+" has RESTARTed in fatal round.");
 76							}
 77							if(params.veryVerbose) {
 78								restartCount++;
 79								System.out.println("("+restartCount+") [ "+must.getClass().getSimpleName()+" ]\t\t"+must+" has RESTARTed.");
 80							}
 81								
 82							restarted = true;
 83							running = true;
 84							return false;
 85						}
 86					}
 87				}
 88				return true;
 89			}
 90		});
 91		
 92		int count = 0, safeCount = 0;
 93		running = true;
 94		if(count > MAX || safeCount > SAFE_MAX) {
 95			fatal = true;
 96			nosy.start().visit(module);
 97			throw new OocCompilationError(module, module, "Resolver is running in circles. Abandoning. (count = "
 98					+count+"/"+MAX+", safeCount = "+safeCount+"/"+SAFE_MAX+")");
 99		}
100		
101		running = false;
102		nosy.start().visit(module);
103		
104		safeCount++;
105		if(restarted) {
106			restarted = false;
107		} else {
108			count++;
109		}
110		
111		return running;
112		
113	}
114	
115	@Override
116	public String toString() {
117		return module.getFullName();
118	}
119	
120	public boolean isFatal() {
121		return fatal;
122	}
123	
124}