// utils.beh -- Utility traversals and functions // $Id: utils.beh,v 1.12 2003/01/30 23:29:41 dougo Exp $ // Long getters & setters for class and part names. ClassNameAccessor { before ClassSpec {{ }} before ParamClassName {{ }} before ClassName {{ }} } ClassDef { traversal toClassName(ClassNameAccessor v) { bypassing { ClassParts, -> *,parameters,* } to ClassName; } } { Subclass, Superclass, Part, RepeatedPart, Interface } { traversal toClassName(ClassNameAccessor v) { bypassing { ClassDef, -> *,actual_parameters,* } to ClassName; } } // { ClassDef, Subclass, Superclass, Part, RepeatedPart, Interface } { // ClassName get_classname() = toClassName { // before ClassName {{ return_val = host; }} // } // } ClassDef { public ClassName get_classname() {{ return paramclassname.classname; }} } { Part, Subclass, Superclass, Interface } { public ClassName get_classname() {{ return classspec.classname; }} } RepeatedPart { public boolean mayBeEmpty() {{ return nonempty == null; }} public ClassName get_classname() {{ return repeated.inner.classspec.classname; }} } { ClassDef, Part, RepeatedPart } { void set_classname(ClassName classname) = toClassName { before { ParamClassName, ClassSpec } {{ host.set_classname(classname); }} } } ClassDef { ClassName_Commalist get_parameters() bypassing ClassParts to ClassName_Commalist { before ClassName_Commalist {{ return_val = host; }} } } ClassGraph { traversal allClassDefs(ClassDefVisitor v) { to-stop ClassDef; } } ClassDefVisitor { before { ClassGraph, ClassDef } {{ }} after { ClassGraph } {{ }} } ClassGraph { {{ // String -> ClassDef Map defmap = new LinkedHashMap(); }} void buildClassDefTable() = allClassDefs { {{ Map defmap; }} before ClassGraph {{ defmap = new HashMap(); }} before ClassDef {{ String name = host.get_classname().toString(); defmap.put(name, host); }} after ClassGraph {{ host.defmap = defmap; }} } ClassDef findClassDef(ClassName name) {{ return findClassDef(name.toString()); }} ClassDef findClassDef(String name) {{ return (ClassDef) defmap.get(name); }} boolean definesClass(ClassName name) {{ return definesClass(name.toString()); }} public boolean definesClass(String name) {{ return defmap.containsKey(name); }} void addClassGraphEntry(ClassGraphEntry cge) {{ if (classes == null) classes = new ClassGraphEntry_SList(); classes.addElement(cge); }} void addClassDef(ClassDef def) {{ String name = def.get_classname().toString(); defmap.put(name, def); addNode(name); def.set_cg(this); addClassGraphEntry(def); }} } Part { boolean isTerminal() {{ return def.isInterface(); }} } ClassName { {{ private static String builtinTypes[] = { "boolean", "char", "byte", "short", "int", "long", "float", "double" }; private static String terminalClasses[] = { // from java.lang.*: "Boolean", "Character", "Integer", "Long", "Float", "Double", "Number", "String", "StringBuffer", // from demeter.*: "Ident", "Text", "Line", "Word" }; }} boolean isBuiltinType() {{ String s = toString(); for (int i = 0; i < builtinTypes.length; i++) { if (builtinTypes[i].equals(s)) return true; } return false; }} boolean isTerminalClass() {{ String s = toString(); for (int i = 0; i < terminalClasses.length; i++) { if (terminalClasses[i].equals(s)) return true; } return false; }} boolean isKnownTerminal() {{ return isBuiltinType() || isTerminalClass(); }} } { ClassGraph, ClassDef } { traversal allParts(PartVisitor v) { to { Part, RepeatedPart }; } } PartVisitor { before { ClassDef, Part, RepeatedPart } {{ }} around ClassDef {{ subtraversal.apply(); }} after { ClassDef, Part, RepeatedPart } {{ }} } ClassDef { traversal allSyntax(SyntaxVisitor) { to { Part, Subclass, Superclass, Interface, RepeatedElement, Syntax, EOFtoken }; } } SyntaxVisitor { before { ConstructionClass, AlternationClass, Subclass, Superclass, Part, OptionalPart, RepeatedPart, RepeatedElement, PlainSyntax, PrintIndent, PrintUnindent, PrintSkip, PrintSpace, EOFtoken } {{ }} after { ConstructionClass, AlternationClass, Subclass, Superclass, Part, OptionalPart, RepeatedPart, RepeatedElement, PlainSyntax, PrintIndent, PrintUnindent, PrintSkip, PrintSpace, EOFtoken } {{ }} } ClassDef { traversal allEdges(EdgeVisitor v) { to { Part, Subclass, Superclass, Interface }; } } EdgeVisitor { around ClassDef {{ subtraversal.apply(); }} before { Part, Subclass, Superclass, Interface } {{ }} before { ClassGraph, ConstOrAltClass, ConstructionClass, AlternationClass, ClassParents, OptionalPart, ClassDef } {{ }} after { Part, Subclass, Superclass, Interface, ConstructionClass, ClassDef, OptionalPart } {{ }} } VisitorClass { {{ static VisitorClass instance = new VisitorClass(); }} } NotParsedClass { {{ static NotParsedClass instance = new NotParsedClass(); }} } DerivedPart { {{ static DerivedPart instance = new DerivedPart(); }} } ClassDef { public boolean isConstructionClass(){{ return getClassType().get_is_con(); }} public boolean isAlternationClass() {{ return getClassType().get_is_alt(); }} public boolean isRepetitionClass() {{ return getClassType().get_is_rep(); }} public boolean isPublic() {{ return getClassType().get_is_public(); }} public boolean isFinal() {{ return getClassType().get_is_final(); }} public boolean isInterface(){{ return getClassType().get_is_interface(); }} public boolean isNotParsed(){{ return getClassType().get_is_not_parsed();}} public boolean isVisitor() {{ return getClassType().get_is_visitor(); }} ClassType getClassType() to { ConstructionClass, AlternationClass, RepetitionClass, PublicClass, FinalClass, InterfaceClass, VisitorClass, NotParsedClass } { init {{ return_val = new ClassType(); }} before ConstructionClass {{ return_val.set_is_con(true); }} before AlternationClass {{ return_val.set_is_alt(true); }} before RepetitionClass {{ return_val.set_is_rep(true); }} before PublicClass {{ return_val.set_is_public(true); }} before FinalClass {{ return_val.set_is_final(true); }} before InterfaceClass {{ return_val.set_is_interface(true); }} before VisitorClass {{ return_val.set_is_visitor(true); }} before NotParsedClass {{ return_val.set_is_not_parsed(true); }} } void markVisitor() {{ keywords.addElement(VisitorClass.instance); }} void markNotParsed() {{ keywords.addElement(NotParsedClass.instance); }} } Part { public boolean isFinal() {{ return getPartType().get_is_final(); }} public boolean isStatic() {{ return getPartType().get_is_static(); }} public boolean isDerived() {{ return getPartType().get_is_derived(); }} public boolean hasGetter() {{ return getPartType().get_has_getter(); }} public boolean hasSetter() {{ return getPartType().get_has_setter(); }} PartType getPartType() to { FinalPart, StaticPart, ReadOnlyPart, PrivatePart, DerivedPart } { init {{ return_val = new PartType(); return_val.set_has_getter(true); return_val.set_has_setter(true); }} before FinalPart {{ return_val.set_is_final(true); return_val.set_has_setter(false); }} before StaticPart {{ return_val.set_is_static(true); }} before PrivatePart {{ return_val.set_has_getter(false); return_val.set_has_setter(false); }} before ReadOnlyPart {{ return_val.set_has_setter(false); }} before DerivedPart {{ return_val.set_is_derived(true); }} } public void markDerived() {{ keywords.addElement(DerivedPart.instance); }} } ClassDef { public ClassDef get_superclass_def() {{ ClassName super_name = get_superclass_name(); return super_name == null ? null : get_cg().findClassDef(super_name); }} ClassName get_superclass_name() via Superclass to ClassName { before ClassName {{ return_val = host; }} } } //////////////////////////////////////////////////////////////// // Everything below here ought to be automatically generated... //////////////////////////////////////////////// // String representations. ParseIdent { public String toString() {{ return "parse"; }} } NoParseIdent { public String toString() {{ return "noparse"; }} } VisitorsIdent { public String toString() {{ return "visitors"; }} } EndVisitorsIdent{ public String toString() {{ return "endvisitors"; }} } VisitorIdent { public String toString() {{ return "visitor"; }} } NotParsedIdent { public String toString() {{ return "notparsed"; }} } DerivedIdent { public String toString() {{ return "derived"; }} } InitIdent { public String toString() {{ return "init"; }} } CommonIdent { public String toString() {{ return "common"; }} } LookaheadIdent { public String toString() {{ return "lookahead"; }} } OtherIdent { public String toString() {{ return id.toString(); }} } FinalPart { public String toString() {{ return "final"; }} } StaticPart { public String toString() {{ return "static"; }} } ReadOnlyPart { public String toString() {{ return "read-only"; }} } PrivatePart { public String toString() {{ return "private"; }} } DerivedPart { public String toString() {{ return "derived"; }} } PartInitKeyword { public String toString() {{ return "init"; }} } ExtendsKeyword { public String toString() {{ return "extends"; }} } ImplementsKeyword{ public String toString() {{ return "implements"; }} } CommonKeyword { public String toString() {{ return "\n\tcommon"; }} } Name { public String toString() {{ return first.toString(); }} } Nonempty_Name { public String toString() {{ return it + (next == null ? "" : "." + next); }} } { ClassName, PartName } { {{ String string; }} public String toString() {{ return string == null ? (string = name.toString()) : string; // return name.toString(); }} } Part { public String toString() {{ return "<" + partname + "> " + keywords + (keywords.isEmpty() ? "" : " ") + classspec; }} } { Subclass, Superclass, Interface, RepeatedElement } { public String toString() {{ return classspec.toString(); }} } ClassSpec { public String toString() {{ return classname.toString(); }} } JavaCode { public String toString() {{ return Text.begin + code + Text.end; }}} PlainSyntax { public String toString() {{ return "\"" + string + "\""; }} } PrintIndent { public String toString() {{ return "+"; }} } PrintUnindent { public String toString() {{ return "-"; }} } PrintSkip { public String toString() {{ return "*l"; }} } PrintSpace { public String toString() {{ return "*s"; }} } LocalLookahead{ public String toString() {{ return "lookahead "+javacode; }}} { ClassName_Commalist, Superclass_Commalist, Interface_Commalist, PartKeyword_List } { public String toString() {{ return (first == null ? "" : first.toString()); }} } { Nonempty_ClassName_Commalist, Nonempty_Superclass_Commalist, Nonempty_Interface_Commalist } { public String toString() {{ return it + (next == null ? "" : ", " + next); }} } Nonempty_PartKeyword_List { public String toString() {{ return it + (next == null ? "" : " " + next); }} } ClassDef { public String toString() {{ return get_classname().toString(); }} } { ClassGraph, Preamble } { public String toString() {{ StringWriter w = new StringWriter(); PrintWriter pw = new PrintWriter(w); universal_trv0(new PrintVisitor(pw)); pw.flush(); return w.toString(); }} } //////////////////////////////////////////////// // Equality predicates. Part { {{ String key; }} String key() {{ if (key == null) key = "-> " + def.get_classname() + "," + partname + "," + classspec; return key; }} } Subclass { {{ String key; }} String key() {{ if (key == null) key = "=> " + def.get_classname() + "," + classspec; return key; }} } { Superclass, Interface } { {{ String key; }} String key() {{ if (key == null) key = ":> " + def.get_classname() + "," + classspec; return key; }} } Part { public boolean equals(Object obj) {{ return obj instanceof Part && key().equals(((Part) obj).key()); }} } Subclass { public boolean equals(Object obj) {{ return obj instanceof Subclass && key().equals(((Subclass) obj).key()); }} } Superclass { public boolean equals(Object obj) {{ return obj instanceof Superclass && key().equals(((Superclass) obj).key()); }} } Interface { public boolean equals(Object obj) {{ return obj instanceof Interface && key().equals(((Interface) obj).key()); }} } { ClassName, PartName, Name, IdentOrKeyword } { public boolean equals(Object obj) {{ return toString().equals(obj.toString()); }} } //////////////////////////////////////////////// // Deep copying functions. ClassDef { ClassDef deepCopy() {{ CopyVisitor c = new CopyVisitor(getClass()); toAll(c); // universal_trv0(c); return (ClassDef) c.get_copy(); }} traversal toAll(UniversalVisitor v) { to *; } } //////////////////////////////////////////////// // Hash code functions. { Part, Subclass, Superclass, Interface } { public int hashCode() {{ return key().hashCode(); }} } { ClassName, PartName, Name, IdentOrKeyword } { public int hashCode() {{ return toString().hashCode(); }} } //////////////////////////////////////////////// // List functions. ClassName_Commalist { /** The index of name in the list, or -1 if it's not in the list. */ public int indexOf(ClassName name) {{ Enumeration e = elements(); int i = 0; while (e.hasMoreElements()) { if (((ClassName) e.nextElement()).equals(name)) return i; i++; } return -1; }} } ClassSpec_Commalist { /** The ith element in the list, or null if the list isn't that long. */ public ClassSpec elementAt(int i) {{ Enumeration e = elements(); while (e.hasMoreElements()) { ClassSpec spec = (ClassSpec) e.nextElement(); if (i == 0) return spec; i--; } return null; }} }