strategy.beh.html

StrategyExpression{
	abstract StrategyGraph toGraph(ClassName source);
}

StrategyGraph{
	init (@ edgeVec = new Vector(); edges = new SGEdge_SList(); @)
	StrategyGraph toGraph(ClassName source)(@
    Enumeration e = edges.elements();
    while (e.hasMoreElements()) {
      edgeVec.addElement(e.nextElement());
    }
    if (sources == null) {
      if (sourceEdges != null) {
	ClassGlobSet set = new ClassGlobSet(new ClassGlob_Commalist());
	Enumeration e2 = sourceEdges.elements();
	while (e2.hasMoreElements()) {
	  Integer i = (Integer) e2.nextElement();
	  SGEdge edge = (SGEdge) edgeVec.elementAt(i.intValue());
	  set.setadd(edge.get_source());
	}
	sources = set;
      } else {
	sources = OneClassGlob.parse(source.toString());
      }
    }
    if (sourceEdges == null) {
      sourceEdges = new Integer_NList();
      sources.allClassNames(new SourceEdgeCollector(this, sourceEdges));
    }
    if (targets == null) {
      ClassGlobCollector c = new ClassGlobCollector();
      allDests(c);
      targets = c.get_spec();
    }	
    return this;
  @)
	void addEdge(SGEdge edge)(@
    edgeVec.addElement(edge);
    edges.addElement(edge);
  @)
}

Integer_NList{
	void setadd(Vector v)(@
    Enumeration e = v.elements();
    while (e.hasMoreElements()) {
      Integer i = (Integer) e.nextElement();
      if (!contains(i)) addElement(i);
    }
  @)
}

SourceEdgeCollector{
	before ClassName (@
    edges.setadd(sg.getOutgoingIndices(host));
  @)
	before AnyClass (@
    // Add every edge in the strategy graph.
    int n = sg.get_edgeVec().size();
    for (int i = 0; i < n; i++) edges.addElement(new Integer(i));
  @)
}

PathDirective{
	StrategyGraph toGraph(ClassName source)to{ NegativeConstraint, PositiveConstraint, To, ToStop }{
		(@ SGEdge edge = new SGEdge(); @)
		before PathDirective (@
      return_val = new StrategyGraph();
      ClassGlobSpec sourcespec = OneClassGlob.parse(source.toString());
      return_val.set_sources(sourcespec);
      return_val.set_sourceEdges(Integer_NList.parse("0"));
      edge.set_source(sourcespec);
    @)
		before NegativeConstraint (@
      edge.set_constraint(host);
    @)
		before PositiveConstraint (@
      GlobSpec glob = host.get_glob();
      ClassGlobSpec cglob = glob.collectClassGlobs();
      GlobSpec eglob = glob.collectEdgeGlobs();
      if (eglob != null) {
	System.err.println("Error: edge globs not yet supported.");
      } else if (cglob != null) {
	edge.set_dest(cglob);
	return_val.addEdge(edge);
	edge = new SGEdge();
	edge.set_source(cglob);
      }
    @)
		before ToStop (@
      // Bypass all outgoing edges from the targets.
      Bypassing constraint = new Bypassing();
      constraint.set_glob(host.get_targets().toOutgoingEdgeSpec());
      edge.set_constraint(constraint.intersectWith(edge.get_constraint()));
    @)
		after TargetDirective (@
      ClassGlobSpec targets = host.get_targets();
      edge.set_dest(targets);
      return_val.addEdge(edge);
      return_val.set_targets(targets);
    @)
	}
}

Bypassing{
	NegativeConstraint intersectWith(NegativeConstraint constraint)(@
    if (constraint == null) return this;
    if (constraint instanceof OnlyThrough) return constraint;
    return new Bypassing(glob.union(constraint.get_glob()));
  @)
}

StrategyVariable{
	StrategyGraph toGraph(ClassName source)(@
    System.err.println("Error: strategy variables not yet implemented.");
    return null;
  @)
}

CompoundStrategy{
	StrategyGraph toGraph(ClassName source)(@
    System.err.println("Error: compound strategies not yet implemented.");
    return null;
  @)
}

StrategyGraph{
	traversal allSources(GlobVisitor) {
		bypassing{ -> *, sources, *, -> *, targets, *, -> *, dest, *, -> *, constraint, * }to ClassGlob;
	}
	traversal allDests(GlobVisitor) {
		bypassing{ -> *, sources, *, -> *, targets, *, -> *, source, *, -> *, constraint, * }to ClassGlob;
	}
}

StrategyGraph{
	public Vector getIncomingIndices(ClassNameI c)allDests(SGEdgeMatcher);
	public Vector getOutgoingIndices(ClassNameI c)allSources(SGEdgeMatcher);
}

SGEdgeMatcher{
	init (@ return_val = new Vector(); @)
	before ClassGlobSpec (@
    if (host.match((ClassName) c)) return_val.addElement(new Integer(index));
    index++;
  @)
}

StrategyGraph{
	void markReachableForwardFromSources(TraversalGraph tg)bypassing{ -> *, edges, *, -> *, targets, * }to{ ClassName, AnyClass }{
		(@ StrategyGraph sg; @)
		before StrategyGraph (@ tg.unmarkAllForward(); sg = host; @)
		before AnyClass (@ tg.markAllForward(); @)
		before ClassName (@ tg.markReachableForwardFrom(host, sg); @)
	}
	void markReachableBackwardFromTargets(TraversalGraph tg)bypassing{ -> *, edges, *, -> *, sources, * }to{ ClassName, AnyClass }{
		(@ StrategyGraph sg; @)
		before StrategyGraph (@ tg.unmarkAllBackward(); sg = host; @)
		before AnyClass (@ tg.markAllBackward(); @)
		before ClassName (@ tg.markReachableBackwardFrom(host, sg); @)
	}
}

StrategyGraph{
	public boolean meetsConstraint(int i, TGEdge edge)(@
    SGEdge sgedge = (SGEdge) edgeVec.elementAt(i);
    return sgedge.checkConstraint(edge);
  @)
}

SGEdge{
	boolean checkConstraint(TGEdge edge)to{ Bypassing, OnlyThrough }{
		init (@ return_val = true; @)
		before Bypassing (@ return_val = !host.get_glob().match(edge); @)
		before OnlyThrough (@ return_val = host.get_glob().match(edge); @)
	}
}

StrategyGraph{
	boolean allSourcesAndTargetsMarked(TraversalGraph tg)bypassing-> *, edges, *to{ ClassName, AnyClass }{
		init (@ return_val = true; @)
		(@ boolean glob_answer = false; @)
		before ClassGlobSpec (@ glob_answer = false; @)
		before AnyClass (@ glob_answer = true; @)
		before ClassName (@
      TGVertex v = tg.findVertex(host, false);
      if (v.is_in_trav()) glob_answer = true;
      else System.err.println("Warning: " + host +
			      " is not in the traversal graph.");
    @)
		after ClassGlobSpec (@ if (glob_answer == false) return_val = false; @)
	}
}

StrategyGraph{
	String startSetCode(String indent, String setname, ClassName start)(@
    if (!sources.match(start)) {
      System.err.println("Error: strategy cannot start at " + start + ".");
      return "";
    }
    String code = "";
    Enumeration e = sourceEdges.elements();
    while (e.hasMoreElements()) {
      Integer i = (Integer) e.nextElement();
      code += indent + setname + ".set(" + i.intValue() + ");\n";
    }
    return code;
  @)
}

StrategyGraph{
	int size()(@ return edges.size(); @)
}