// param.beh -- Parameterization expansion // $Id: param.beh,v 1.2 2002/09/26 05:59:15 dougo Exp $ ClassGraph { /** Replace all parameterized classes by expanding the corresponding definition and replacing the parameters. */ ClassGraph expandParamDefs() to ClassSpec { {{ ClassGraph cg; }} before ClassGraph {{ cg = host; }} after ClassSpec {{ ClassName name = host.get_classname(); ClassSpec_Commalist actuals = host.get_actual_parameters(); if (actuals != null) { // It's a parameterized class; make sure it hasn't already been // defined. ClassName newname = host.expandName(); if (!cg.definesClass(newname)) { // It hasn't; get the parameterized definition, copy it, // replace the parameters with the actual parameters, and add // it to the list of class defs. ClassDef paramdef = cg.findClassDef(name); if (paramdef == null) { System.err.println("Error: no such parameterized class \"" + name + "\""); } else { ClassDef actualdef = paramdef.deepCopy(); ParamClassName pname = ParamClassName.parse(newname.toString()); actualdef.set_paramclassname(pname); actualdef.replaceParams(paramdef.get_parameters(), actuals); cg.addClassDef(actualdef); } } } }} after ClassGraph {{ return_val = host.removeParamDefs(); }} } // Remove the parameterized definitions from the class graph. ClassGraph removeParamDefs() to { ClassGraphEntry, ClassDef } { {{ ClassGraph cg = new ClassGraph(); }} before ClassGraph {{ cg.set_preamble(host.get_preamble()); }} before ClassGraphEntry {{ if (!(host instanceof ClassDef)) cg.addClassGraphEntry(host); }} before ClassDef {{ if (host.get_parameters() == null) cg.addClassDef(host); }} return {{ cg }} } } ClassSpec { /** Concatenate the parameters with "_" in front of the classname. Assumes the parameters have already been expanded. Mutates classname and actual_parameters. */ ClassName expandName() {{ if (actual_parameters != null) { String newname = actual_parameters.concatenateNames() + classname; classname = ClassName.parse(newname); actual_parameters = null; } return classname; }} } ClassSpec_Commalist { String concatenateNames() to ClassName { init {{ return_val = ""; }} before ClassName {{ return_val += host + "_"; }} } } ClassDef { void replaceParams(ClassName_Commalist params, ClassSpec_Commalist actuals) = allParts { before { Part, RepeatedPart } {{ int i = params.indexOf(host.get_classname()); if (i != -1) { ClassSpec actual = actuals.elementAt(i); host.set_classname(actual.get_classname()); } }} } }