// SemanticChecker.beh // // This file defines the SemanticChecker class, which performs // various syntax and semantic checks on the XAspects // language and class dictionary input. SemanticChecker { {{ // the runtime class graph ClassGraph runtimeCg; // the class graph defined by the input class dictionary edu.neu.ccs.demeter.aplib.cd.ClassGraph inputCg; // a pointer to the traversal XAspects component TraversalAspect ta; }} // takes the two aspect types and creates the class graphs we need public void generate(ClassDictionaryAspect cda, TraversalAspect travA) {{ // create the runtime class graph runtimeCg = new ClassGraph(true, false); // create the class graph for the input class dictionary inputCg = ClassGraph.fromString(cda.get_textcd().get_text().toString()); inputCg.normalize(); // assign the pointer to the provided traversal aspect component ta = travA; }} public void check() {{ // make some Traversal XAspects specific checks // i.e., make sure that "nodes" and regular expression declarations // utilize other declarations that are defined check_trav_nodesAndRegExp(); // check in all places for undefined classes // i.e., check used classes in class dictionary, strategy expressions, // and class list declarations checkForUndefinedClasses(); // verify that strategies represent legal paths checkTraversalPaths(); }} // semantic checker for the traversal aspect declaration private void check_trav_nodesAndRegExp() {{ // check that all used Strategy names in "nodes" node set decls are defined List usedNames = runtimeCg.gather(ta, "from TraversalAspect via StrategyName to" + Main.FIdent); List defNames = runtimeCg.gather(ta, "from TraversalAspect via StrategyDeclName to" + Main.FIdent); subset_test(usedNames, defNames); // check that regular expressions reference defined node sets List defNodeSetDecls = runtimeCg.gather(ta, "from TraversalAspect via NodesetDeclName to" + Main.FIdent); List usedNodeSetDecls = runtimeCg.gather(ta, "from TraversalAspect via NodesetIdent to" + Main.FIdent); subset_test(usedNodeSetDecls, defNodeSetDecls); }} // check various places for use of undefined classes private void checkForUndefinedClasses () {{ // get a list of all used classes in input cd, and make sure each used class // is defined by the cd java.util.Collection c = inputCg.getNodes(); checkDefinesClass(c.iterator()); // check that all classes used in strategy expressions are defined List usedClassNames = runtimeCg.gather(ta, "from TraversalAspect via ClassName to" + Main.FIdent); checkDefinesClass(usedClassNames.iterator()); // check classes are all defined in class list node sets List usedClasses = runtimeCg.gather(ta, "from TraversalAspect via ClassListName to" + Main.FIdent); checkDefinesClass(usedClasses.iterator()); }} // this method performs a general subset test on two lists of Idents private void subset_test(List used, List defined) {{ ListIterator usedIterator = used.listIterator(); while (usedIterator.hasNext()) { Ident next = (Ident) usedIterator.next(); if (!defined.contains(next)) { System.out.println(next.toString() + " undefined."); } } }} // create a traversal for each strategy to check the path private void checkTraversalPaths() {{ List test = runtimeCg.gather(ta, "from TraversalAspect to Strategy"); Strategy strat = (Strategy) test.get(0); // We have been unable to implement this portion as of yet. // It seems the best way would be to create a Traversal object // using the Strategy and parsed class graph, and catch the // possible exceptions (TraversalException, ParseException), // but we have been unable to do this due to incompatibilities // between our Strategy defined in our cd, the Traversal object // and our parsed class graph. /* The following code is provided as an example of this semantic * checking process, if the Strategies were stored in String format: * * try { * // create a strategy from the string, * // syntax errors result in StrategyParseException * Strategy strategy = new Strategy(srategyAsString); * * // compute traversal, bad path results in TraversalException * Traversal.compute(strategy, inputCg); * } catch (StrategyParseException spe) { * // invalid strategy syntax * System.out.println("StrategyParseException: " + spe.getMessage()); * } catch (TraversalException te) { * // bad traversal path * System.out.println("TraversalException: " + te.getMessage()); * } catch (Exception e) { * System.out.println(e.getMessage()); * } */ }} // this method takes an iterator and checks that the // input class dictionary defines those classes // (another form of subset test) private void checkDefinesClass(Iterator iter) {{ while (iter.hasNext()) { Object next = iter.next(); if (!inputCg.definesClass(next.toString())) { System.out.println(next.toString() + " undefined."); } } }} }