summaryrefslogtreecommitdiff
path: root/src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java')
-rw-r--r--src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java652
1 files changed, 652 insertions, 0 deletions
diff --git a/src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java b/src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java
new file mode 100644
index 0000000..4a5e0f2
--- /dev/null
+++ b/src/main/java/io/devnulllabs/openjava/mop/OJConstructor.java
@@ -0,0 +1,652 @@
+/*
+ * OJConstructor.java
+ *
+ * Jul 28, 1998 by mich
+ */
+package io.devnulllabs.openjava.mop;
+
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Hashtable;
+
+import io.devnulllabs.openjava.ptree.ConstructorDeclaration;
+import io.devnulllabs.openjava.ptree.ConstructorInvocation;
+import io.devnulllabs.openjava.ptree.ExpressionList;
+import io.devnulllabs.openjava.ptree.ModifierList;
+import io.devnulllabs.openjava.ptree.ParameterList;
+import io.devnulllabs.openjava.ptree.ParseTree;
+import io.devnulllabs.openjava.ptree.StatementList;
+import io.devnulllabs.openjava.ptree.TypeName;
+import io.devnulllabs.openjava.ptree.Variable;
+
+
+public final class OJConstructor implements OJMember
+{
+ private OJConstructorImp substance;
+
+ private static Hashtable table = new Hashtable();
+
+ OJConstructor( Constructor m ) {
+ this.substance = new OJConstructorByteCode( m );
+ }
+
+ public OJConstructor( OJClass declarer, OJModifier modif,
+ OJClass[] parameterTypes, OJClass[] exceptionTypes,
+ ConstructorInvocation ci, StatementList body )
+ {
+ this( declarer, modif,
+ Toolbox.generateParameters( parameterTypes ),
+ exceptionTypes, ci, body );
+ }
+
+ public OJConstructor( OJClass declarer, OJModifier modif,
+ OJClass[] parameterTypes, String[] parameterNames,
+ OJClass[] exceptionTypes,
+ ConstructorInvocation ci, StatementList body )
+ {
+ this( declarer, modif,
+ Toolbox.generateParameters( parameterTypes, parameterNames ),
+ exceptionTypes, ci, body );
+ }
+
+ public OJConstructor( OJClass declarer, OJModifier modif,
+ ParameterList params, OJClass[] exceptionTypes,
+ ConstructorInvocation ci, StatementList body )
+ {
+ Environment env = declarer.getEnvironment();
+ ModifierList modiflist = new ModifierList();
+ modiflist.add( modif.toModifier() );
+ ConstructorDeclaration d = new ConstructorDeclaration(
+ modiflist,
+ Environment.toSimpleName( declarer.getName() ),
+ params,
+ Toolbox.TNsForOJClasses( exceptionTypes ),
+ ci,
+ body
+ );
+ this.substance = new OJConstructorSourceCode( env, declarer, d );
+ }
+
+ public OJConstructor( Environment env, OJClass declarer,
+ ConstructorDeclaration d )
+ {
+ this.substance = new OJConstructorSourceCode( env, declarer, d );
+ }
+
+ public static OJConstructor forConstructor( Constructor java_constr ) {
+ if (java_constr == null) return null;
+ OJConstructor constr = (OJConstructor) table.get( java_constr );
+ if (constr == null) {
+ constr = new OJConstructor( java_constr );
+ table.put( java_constr, constr );
+ }
+ return constr;
+ }
+
+ public static OJConstructor[]
+ arrayForConstructors( Constructor[] jconstrs ) {
+ OJConstructor[] result = new OJConstructor[jconstrs.length];
+ for (int i = 0; i < result.length; ++i) {
+ result[i] = forConstructor( jconstrs[i] );
+ }
+ return result;
+ }
+
+ public Signature signature() {
+ return new Signature( this );
+ }
+
+ public OJClass getDeclaringClass() {
+ return substance.getDeclaringClass();
+ }
+
+ public String getName() {
+ /***********/
+ return substance.getName();
+ }
+
+ public String getIdentifiableName() {
+ return substance.getIdentifiableName();
+ }
+
+ public OJModifier getModifiers() {
+ return substance.getModifiers();
+ }
+
+ public OJClass[] getParameterTypes() {
+ return substance.getParameterTypes();
+ }
+
+ public OJClass[] getExceptionTypes() {
+ return substance.getExceptionTypes();
+ }
+
+ public ParseTree getSuffix( String keyword ) {
+ return substance.getSuffix( keyword );
+ }
+
+ /******************/
+ public ExpressionList getParameterVariables()
+ throws CannotAlterException
+ {
+ ConstructorDeclaration d = getSourceCode();
+ ParameterList params = d.getParameters();
+ ExpressionList result = new ExpressionList();
+ for (int i = 0, len = params.size(); i < len; ++i) {
+ result.add( new Variable( params.get( i ).getVariable() ) );
+ }
+ return result;
+ }
+
+ public String[] getParameters()
+ throws CannotAlterException
+ {
+ ConstructorDeclaration d = getSourceCode();
+ ParameterList params = d.getParameters();
+ String[] result = new String[params.size()];
+ for (int i = 0; i < result.length; ++i) {
+ result[i] = params.get( i ).getVariable().toString();
+ }
+ return result;
+ }
+
+ /**
+ * Compares this method against the given object.
+ * The algorithm is borrowed by java.lang.reflect.Constructor.equals().
+ *
+ * @see java.lang.reflect.Constructor#equals
+ */
+ public boolean equals(Object obj) {
+ if (obj != null && obj instanceof OJConstructor) {
+ OJConstructor other = (OJConstructor) obj;
+ return ((getDeclaringClass() == other.getDeclaringClass())
+ && compareParameters( other ));
+ }
+
+ return false;
+ }
+
+ private boolean compareParameters( OJConstructor other ) {
+ return compareParameters( other.getParameterTypes() );
+ }
+
+ private boolean compareParameters( OJClass[] params2 ) {
+ OJClass[] params1 = getParameterTypes();
+ if (params1.length != params2.length) return false;
+ for (int i = 0; i < params1.length; ++i) {
+ if(params1[i] != params2[i]) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Computes a hashcode for this method. The algorithm is borrowed
+ * by java.lang.reflect.Constructor.hashCode().
+ *
+ * @see java.lang.reflect.Constructor#hashCode
+ */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ public String toString() {
+ return substance.toString();
+ }
+
+ public Environment getEnvironment() {
+ return substance.getEnvironment();
+ }
+
+ /**
+ * Creates a new instance of the constructor's declaring class
+ *
+ * @exception CannotExecuteException if the constructor is not
+ * compiled yet.
+ */
+ public Object newInstance(Object[] initargs)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException,
+ InstantiationException, CannotExecuteException
+ {
+ return substance.newInstance( initargs );
+ }
+
+ /* -- methods java.lang.reflect.Constructor does not supply. -- */
+
+ public final boolean isExecutable() {
+ return substance.isExecutable();
+ }
+
+ public final boolean isAlterable() {
+ return substance.isAlterable();
+ }
+
+ public final Constructor getByteCode() throws CannotExecuteException {
+ return substance.getByteCode();
+ }
+
+ public final ConstructorDeclaration getSourceCode()
+ throws CannotAlterException
+ {
+ return substance.getSourceCode();
+ }
+
+ public final StatementList getBody() throws CannotAlterException {
+ return substance.getBody();
+ }
+
+ public final ConstructorInvocation getTransference()
+ throws CannotAlterException
+ {
+ return substance.getTransference();
+ }
+
+ /* -- inner use only -- */
+
+ void setDeclaringClass( OJClass parent ) throws CannotAlterException {
+ substance.setDeclaringClass( parent );
+ }
+
+ /* -- Translation (not overridable) -- */
+
+ final public void setModifiers( int mods ) throws CannotAlterException {
+ substance.setModifiers( mods );
+ }
+
+ public final void setExceptionTypes( OJClass[] types )
+ throws CannotAlterException
+ {
+ substance.setExceptionTypes( types );
+ }
+
+ public final void addExceptionType( OJClass type )
+ throws CannotAlterException
+ {
+ OJClass[] etypes = getExceptionTypes();
+ OJClass[] result = new OJClass[etypes.length + 1];
+ System.arraycopy( etypes, 0, result, 0, etypes.length );
+ result[etypes.length] = type;
+ setExceptionTypes( result );
+ }
+
+ public final ConstructorInvocation
+ setTransference( ConstructorInvocation invocation )
+ throws CannotAlterException
+ {
+ return substance.setTransference( invocation );
+ }
+
+ public final StatementList setBody( StatementList stmts )
+ throws CannotAlterException
+ {
+ return substance.setBody( stmts );
+ }
+
+}
+
+
+/**
+ * The abstract class <code>OJConstructorImp</code> provides an interface to
+ * an implementation of OJConstructor.
+ */
+abstract class OJConstructorImp
+{
+ public abstract String toString();
+ abstract Environment getEnvironment();
+ abstract OJClass getDeclaringClass();
+ abstract String getName();
+ abstract String getIdentifiableName();
+ abstract OJModifier getModifiers();
+ abstract OJClass[] getParameterTypes();
+ abstract OJClass[] getExceptionTypes();
+ abstract ParseTree getSuffix( String keyword );
+
+ abstract Object newInstance( Object[] initargs )
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException,
+ InstantiationException, CannotExecuteException;
+
+ /* -- methods java.lang.reflect.Constructor does not supply. -- */
+
+ abstract boolean isExecutable();
+ abstract boolean isAlterable();
+ abstract Constructor getByteCode() throws CannotExecuteException;
+ abstract ConstructorDeclaration getSourceCode()
+ throws CannotAlterException;
+ abstract StatementList getBody() throws CannotAlterException;
+ abstract ConstructorInvocation getTransference()
+ throws CannotAlterException;
+
+ /* -- inner use only -- */
+ abstract void setDeclaringClass( OJClass parent )
+ throws CannotAlterException;
+
+ /* -- Translation (not overridable) -- */
+
+ abstract void setModifiers( int mods ) throws CannotAlterException;
+ abstract StatementList setBody( StatementList stmts )
+ throws CannotAlterException;
+ abstract void setExceptionTypes( OJClass[] types )
+ throws CannotAlterException;
+ abstract ConstructorInvocation
+ setTransference( ConstructorInvocation invocation )
+ throws CannotAlterException;
+
+}
+
+
+class OJConstructorByteCode extends OJConstructorImp
+{
+
+ private Constructor javaConstructor = null;
+
+ OJConstructorByteCode( Constructor java_constr ) {
+ this.javaConstructor = java_constr;
+ }
+
+ public String toString() {
+ return javaConstructor.toString();
+ }
+
+ Environment getEnvironment() {
+ Environment result
+ = new ClosedEnvironment( getDeclaringClass().getEnvironment() );
+ return result;
+ }
+
+ OJClass getDeclaringClass() {
+ return OJClass.forClass( javaConstructor.getDeclaringClass() );
+ }
+
+ String getName() {
+ return javaConstructor.getName();
+ }
+
+ String getIdentifiableName() {
+ /***********/
+ return getDeclaringClass().getName() + "()";
+ }
+
+ OJModifier getModifiers() {
+ return OJModifier.forModifier( javaConstructor.getModifiers() );
+ }
+
+ OJClass[] getParameterTypes() {
+ return OJClass.arrayForClasses( javaConstructor.getParameterTypes() );
+ }
+
+ OJClass[] getExceptionTypes() {
+ return OJClass.arrayForClasses( javaConstructor.getExceptionTypes() );
+ }
+
+ ParseTree getSuffix( String keyword ) {
+ return null;
+ }
+
+ Object newInstance( Object[] initargs )
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException,
+ InstantiationException
+ {
+ return javaConstructor.newInstance( initargs );
+ }
+
+ /* -- methods java.lang.reflect.Constructor does not supply. -- */
+
+ boolean isExecutable() {
+ return true;
+ }
+
+ boolean isAlterable() {
+ return false;
+ }
+
+ Constructor getByteCode() throws CannotExecuteException {
+ return javaConstructor;
+ }
+
+ ConstructorDeclaration getSourceCode() throws CannotAlterException {
+ throw new CannotAlterException( "getSourceCode()" );
+ }
+
+ StatementList getBody() throws CannotAlterException {
+ throw new CannotAlterException( "getBody()" );
+ }
+
+ ConstructorInvocation getTransference()
+ throws CannotAlterException
+ {
+ throw new CannotAlterException( "getTransference()" );
+ }
+
+ /* -- inner use only -- */
+
+ void setDeclaringClass( OJClass parent ) throws CannotAlterException {
+ throw new CannotAlterException( "setDeclaringClass()" );
+ }
+
+ /* -- Translation (not overridable) -- */
+
+ final void setName( String name ) throws CannotAlterException {
+ throw new CannotAlterException( "setName()" );
+ }
+
+ final void setModifiers( int mods ) throws CannotAlterException {
+ throw new CannotAlterException( "setModifiers()" );
+ }
+
+ final void setExceptionTypes( OJClass[] types )
+ throws CannotAlterException
+ {
+ throw new CannotAlterException( "setExceptionTypes()" );
+ }
+
+ StatementList setBody( StatementList stmts )
+ throws CannotAlterException
+ {
+ throw new CannotAlterException( "setBody()" );
+ }
+
+ ConstructorInvocation setTransference( ConstructorInvocation invocation )
+ throws CannotAlterException
+ {
+ throw new CannotAlterException( "setTransference()" );
+ }
+
+}
+
+
+class OJConstructorSourceCode extends OJConstructorImp
+{
+
+ private static int idCounter = 0;
+ private int id;
+
+ private OJClass declarer;
+ private ConstructorDeclaration definition;
+ private Environment env;
+
+ OJConstructorSourceCode( Environment env, OJClass declarer,
+ ConstructorDeclaration ptree )
+ {
+ this.declarer = declarer;
+ this.definition = ptree;
+ this.env = env;
+ this.id = idCounter++;
+ }
+
+ public String toString() {
+ OJClass declarer = getDeclaringClass();
+ String declarername
+ = (declarer == null) ? "*" + id : declarer.getName();
+
+ StringBuffer buf = new StringBuffer();
+ String modif = getModifiers().toString();
+ if (! modif.equals( "" )) {
+ buf.append( modif );
+ buf.append( " " );
+ }
+ buf.append( getName() );
+ buf.append( "(" );
+ OJClass[] paramtypes = getParameterTypes();
+ if (paramtypes.length != 0) {
+ buf.append( paramtypes[0].getName() );
+ }
+ for (int i = 1; i < paramtypes.length; ++i) {
+ buf.append( "," );
+ buf.append( paramtypes[i].getName() );
+ }
+ buf.append( ")" );
+ return buf.toString();
+ }
+
+ Environment getEnvironment() {
+ Environment result
+ = new ClosedEnvironment( getDeclaringClass().getEnvironment() );
+ OJClass[] ptypes = getParameterTypes();
+ String[] pvars = getParameters();
+ for (int i = 0; i < ptypes.length; ++i) {
+ result.bindVariable( pvars[i], ptypes[i] );
+ }
+ return result;
+ }
+
+ OJClass getDeclaringClass() {
+ return this.declarer;
+ }
+
+ String getName() {
+ OJClass declarer = getDeclaringClass();
+ return (declarer == null) ? null : declarer.getName();
+ }
+
+ String getIdentifiableName() {
+ OJClass declarer = getDeclaringClass();
+ String declarername;
+ if (declarer == null) {
+ declarername = "*" + id;
+ } else {
+ declarername = declarer.getName();
+ }
+ /***************/
+ return declarername + "()";
+ }
+
+ OJModifier getModifiers() {
+ return OJModifier.forParseTree( definition.getModifiers() );
+ }
+
+ OJClass[] getParameterTypes() {
+ return arrayForParameters( definition.getParameters() );
+ }
+
+ String[] getParameters() {
+ ParameterList params = definition.getParameters();
+ String[] result = new String[params.size()];
+ for (int i = 0; i < result.length; ++i) {
+ result[i] = params.get( i ).getVariable().toString();
+ }
+ return result;
+ }
+
+ OJClass[] getExceptionTypes() {
+ return arrayForTypeNames( definition.getThrows() );
+ }
+
+ ParseTree getSuffix( String keyword ) {
+ Hashtable table = definition.getSuffixes();
+ if (table == null) return null;
+ return (ParseTree) table.get( keyword );
+ }
+
+ private final OJClass[] arrayForParameters( ParameterList params ) {
+ OJClass[] result = new OJClass[(params == null) ? 0 : params.size()];
+ for (int i = 0; i < result.length; ++i) {
+ String tname = params.get( i ).getTypeSpecifier().toString();
+ result[i] = Toolbox.forNameAnyway( env, tname );
+ }
+ return result;
+ }
+
+ private final OJClass[] arrayForTypeNames( TypeName[] typenames ) {
+ OJClass[] result
+ = new OJClass[(typenames == null) ? 0 : typenames.length];
+ for (int i = 0; i < result.length; ++i) {
+ String tname = typenames[i].toString();
+ result[i] = Toolbox.forNameAnyway( env, tname );
+ }
+ return result;
+ }
+
+ Object newInstance( Object[] initargs )
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException,
+ InstantiationException, CannotExecuteException
+ {
+ throw new CannotExecuteException( "newInstance()" );
+ }
+
+ /* -- methods java.lang.reflect.Constructor does not supply. -- */
+
+ boolean isExecutable() {
+ return false;
+ }
+
+ boolean isAlterable() {
+ return true;
+ }
+
+ Constructor getByteCode() throws CannotExecuteException {
+ throw new CannotExecuteException( "getByteCode()" );
+ }
+
+ ConstructorDeclaration getSourceCode() throws CannotAlterException {
+ return definition;
+ }
+
+ StatementList getBody() throws CannotAlterException {
+ return definition.getBody();
+ }
+
+ ConstructorInvocation getTransference()
+ throws CannotAlterException
+ {
+ return definition.getConstructorInvocation();
+ }
+
+ /* -- inner use only -- */
+
+ void setDeclaringClass( OJClass parent ) throws CannotAlterException {
+ this.declarer = parent;
+ }
+
+ /* -- Translation (not overridable) -- */
+
+ final void setModifiers( int mods ) throws CannotAlterException {
+ throw new CannotAlterException( "setModifiers()" );
+ }
+
+ final void setExceptionTypes( OJClass[] types )
+ throws CannotAlterException
+ {
+ definition.setThrows( Toolbox.TNsForOJClasses( types ) );
+ }
+
+ StatementList setBody( StatementList stmts )
+ throws CannotAlterException
+ {
+ StatementList result = definition.getBody();
+ definition.setBody( stmts );
+ return result;
+ }
+
+ ConstructorInvocation setTransference( ConstructorInvocation invocation )
+ throws CannotAlterException
+ {
+ ConstructorInvocation result = definition.getConstructorInvocation();
+ definition.setConstructorInvocation( invocation );
+ return result;
+ }
+
+}