import java.util.*;
import Jakarta.util.FixDosOutputStream;
import java.io.*;
public class UmInterDecl {
// this method is called on parse tress of the SoUrCe file
// the idea is for this method to propagate the contents of
// this UmInterDecl AST to the file referenced in the SoUrCe file.
public void propagateChanges() {
String myName = null;
String referencedName = null;
// Step 1: fetch the referenced file, parse it, and locate
// the lone ModTypeDecl declaration
UnMixinUtil u = new UnMixinUtil();
// Step 2: do some error checking. The ModTypeDecl must reference
// a UmInterDecl or UmodIntExt with the same QName as
// our parse tree
// note u.location is of type ModTypeDecl, whose first
// argument is an UnmodifiedTypeDeclaration -- in our
// case, it should be a UmInterDecl
if ( kernelConstants.globals().unmixin.base ) {
// testing for UmInterDecl
if ( u.location.arg[1] instanceof UmInterDecl ) {
referencedName = u.location.arg[1].arg[0].tok[0].tokenName();
myName = arg[0].tok[0].tokenName();
if ( !referencedName.equals( myName ) )
AstNode.fatalError( tok[0],
"expecting interface " + myName + " but got "
+ referencedName +
" file " +
kernelConstants.globals().unmixin.fileName +
" not updated" );
}
else
AstNode.fatalError( tok[0],
"expecting UmInterDecl but got " +
u.location.arg[1].getClass().getName() +
" file " + kernelConstants.globals().unmixin.fileName +
" not updated" );
}
else {
// testing for UmodIntExt
if ( u.location.arg[1] instanceof Ute &&
u.location.arg[1].arg[0] instanceof UmodIntExt ) {
referencedName = u.location.arg[1].arg[0].arg[0].tok[0].tokenName();
myName = arg[0].tok[0].tokenName();
if ( !referencedName.equals( myName ) )
AstNode.fatalError( tok[0],
"expecting interface extension" + myName +
" but got " + referencedName +
" file " + kernelConstants.globals().unmixin.fileName +
" not updated" );
}
else
AstNode.fatalError( tok[0],
"expecting Ute (or rather UmodIntExt) but got " +
u.location.arg[1].getClass().getName() +
" file " + kernelConstants.globals().unmixin.fileName +
" not updated" );
}
// Step 3: we're ready to make the changes!
// first, remove the name of the interface from the
// extends list. Remember that it might be there because
// this declaration may have refined (extended) an interface
AST_TypeNameList l = null;
if ( arg[1].arg[0] !=null )
l = ( ( AST_TypeNameList ) arg[1].arg[0].arg[0] ).removeName( myName );
boolean updated = false;
if ( kernelConstants.globals().unmixin.base )
updated = ( ( UmInterDecl ) u.location.arg[1] ).
propagateChanges( l, ( InterfaceMemberDeclarations ) arg[2].arg[0] );
else
updated = ( ( UmodIntExt ) u.location.arg[1].arg[0] ).
propagateChanges( l, ( InterfaceMemberDeclarations ) arg[2].arg[0] );
// Step 4: last thing we do -- propagate the changes back to the file
if ( updated )
u.output();
}
// this method is called on the original AST, not the one with
// SoUrCe declarations
public boolean propagateChanges( AST_TypeNameList l,
InterfaceMemberDeclarations i ) {
// Just replace corresponding extension and body declarations
boolean updated;
updated = pc( arg[1], l, i );
if ( i!=null && ! ( arg[2].toString().trim().equals( i.toString().trim() ) ) ) {
arg[2].Replace( i );
updated = true;
}
return updated;
}
public static boolean pc( AstNode n, // points to [IntExtClauseC]
AST_TypeNameList l,
InterfaceMemberDeclarations i ) {
boolean updated = false;
IntExtClauseC c = null;
if ( l != null ) {
c = new IntExtClauseC().setParms( new AstToken().setParms( " ","extends", 0 ), l );
String com = n.getComment();
if ( com != null )
c.setComment( com );
if ( ! ( c.toString().trim().equals( n.toString().trim() ) ) ) {
n.Replace( c );
updated = true;
}
}
else {
if ( !n.toString().trim().equals( "" ) ) {
n.Delete();
updated = true;
}
}
return updated;
}
}