import java.util.*; import Jakarta.util.FixDosOutputStream; import java.io.*; // this class is interesting. It extends the set of nodes that // can appear in a parse tree, but the parser can't generate this // node. It is used to mark the point where inherited constructors // are inserted. // a blank token is added so that addComment routine will still work. // strange case that, if not present, would generate an error. public class ConstructorMarker extends ClassBodyDeclaration { final boolean order[] = { true }; final static String me = "insert_inherited_constructors_here;"; conTable inheritedCons; // points to constructors to inherit public ConstructorMarker( conTable inheritedCons ) { this.inheritedCons = inheritedCons; arg = new AstNode[0]; tok = new AstTokenInterface[1]; tok[0] = new AstToken().setParms( "","",0 ); // blank token } // added to pacify compiler public boolean[] printorder() { return order; } // some standard routines just in case // note: I added the clone method because without it, I was // getting "can't clone errors" or instantiation exceptions. // I have no idea why, so this hack fixes it. public Object clone() { return new ConstructorMarker( inheritedCons ); } public void harvestConstructors( int stage ) {} public String toString() { return me; } public void print() { System.out.println( me ); } public void print( AstProperties props ) { props.print( me ); } // this is the key method: it adds the inherited constructors to // the output -- only if MixinDeclName has been set. It is // set only if we have seen a SoUrCe declaration public void reduce2java( AstProperties props ) { // Step 0: do nothing if we have not seen a SoUrCe decl if ( props.getProperty( "SoUrCe" )==null ) return; // Step 1: add a comment that says we're about to inherit constructors if ( inheritedCons.size()!= 0 ) { props.println( "" ); props.println( " // inherited constructors" ); props.println( "" ); } // Step 2: foreach inherited constructor, change its name // and output it -- there should be no need to reduce. // and actually, if we did reduce, we might get // errors because we're referencing super // note: the addition of constructor refinements adds the // following twist. Previously, we generated constructors // that were always printed. With constructor refinements, // we only print if the constructors were not refined. In // this way we either print a default refinement or a user- // specified refinement, but not both. String className = ( String ) props.getProperty( "MixinDeclName" ); for ( Enumeration e = inheritedCons.keys(); e.hasMoreElements(); ) { String sig = ( String ) e.nextElement(); if ( kernelConstants.globals().j2jbase.refinedSet.contains( sig ) ) continue; ConDecl c = ( ConDecl ) inheritedCons.get( sig ); c.changeNameTo( className ); c.print( props ); } } }