import java.util.*;
import java.io.*;
import Jakarta.util.*;
//------------------------ j2jClassx layer -------------------
// encapsulates refinement of classes and anything
// to do with their composition. in this case, the j2j tool
// requires some rewrites of classes *prior* to their
// reduction. Also, the j2j tool will be able to parse extensions
// to classes, but will flag them as errors.
public class UmodClassDecl {
String previous = "";
public void harvestConstructors( int stage ) {
// Step 0: do nothing if we are inside quoted text
if ( stage != 0 ) {
super.harvestConstructors( stage );
return;
}
// Step 1: copy the inheritedCons of kernelConstants.j2jbase -- all the
// constructors we have seen up until now are
// the constructors that we want to inherit
copyConstructors();
// Step 2: now harvest the constructors of the classBody
// this is where propagations of constructors UP
// the hierarchy can take place
arg[3].harvestConstructors( stage );
// Step 3: add reference to this type declaration
kernelConstants.globals().j2jbase.previousTypeDecls.add( this );
}
private void finishReduction( AstProperties props ) {
super.reduce2java( props );
props.setProperty( "MixinDeclName", "" );
props.setProperty( "SuperName", "" );
props.setProperty( "ThisName", previous );
}
public void reduce2java( AstProperties props ) {
// Step 1: remember the name of the class that is being extended
// this is needed for correctly expanding Super() constructs
// inside static methods.
String extendsName = "";
ExtendsClause ec = ( ExtendsClause ) arg[1].arg[0];
if ( ec != null )
extendsName = ec.GetName();
props.setProperty( "SuperName", extendsName );
// Step 2: do a normal reduction if we haven't seen SoUrCe decls
if ( props.getProperty( "SoUrCe" ) == null ) {
finishReduction( props );
return;
}
// Step 3: we could be reaching this reduction method because
// we have translated state machines or whatever into
// a class. We don't perform double harvesting and
// rewriting, because this will generate errors.
// So if a non-null MixinDeclName is returned, we do
// nothing except a normal reduction
//
String name = ( String ) props.getProperty( "MixinDeclName" );
if ( ! (name == null || name.equals( "" )
|| (up instanceof NClassDecl) ) ) {
finishReduction( props );
return;
}
// Step 4: remember the name of the class that is being reduced
String className = arg[0].tok[0].tokenName();
props.setProperty( "MixinDeclName", className );
previous = (String) props.getProperty( "ThisName" );
if (previous == null) previous = "";
props.setProperty( "ThisName", Util2.unmangleId(className) );
// Step 5: make sure that an FieldDecl is present
if ( arg[3].arg[0].arg[0] == null ) {
// can't set it because there is an empty ClassBody
// so here's the hack -- we'll add an empty AST_FieldDecl
// so that we can set its boolean
arg[3].arg[0].Replace( new AST_FieldDecl() );
}
// Step 6: add the ConstructorMarker
AST_FieldDecl f = ( AST_FieldDecl ) arg[3].arg[0].arg[0];
f.addMarker( inheritedCons );
// Step 7: now reduce normally. Clear refineSet as this
// keeps track of constructor refinements in this class.
kernelConstants.globals().j2jbase.refinedSet.clear();
// Step 8: finish the reduction
finishReduction( props );
}
}