View Javadoc

    1   /*
    2    * $Id: DummyClassGenerator.java,v 1.7 2006/01/19 00:07:00 blackdrag Exp $
    3    *
    4    * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
    5    *
    6    * Redistribution and use of this software and associated documentation
    7    * ("Software"), with or without modification, are permitted provided that the
    8    * following conditions are met: 1. Redistributions of source code must retain
    9    * copyright statements and notices. Redistributions must also contain a copy
    10   * of this document. 2. Redistributions in binary form must reproduce the above
    11   * copyright notice, this list of conditions and the following disclaimer in
    12   * the documentation and/or other materials provided with the distribution. 3.
    13   * The name "groovy" must not be used to endorse or promote products derived
    14   * from this Software without prior written permission of The Codehaus. For
    15   * written permission, please contact info@codehaus.org. 4. Products derived
    16   * from this Software may not be called "groovy" nor may "groovy" appear in
    17   * their names without prior written permission of The Codehaus. "groovy" is a
    18   * registered trademark of The Codehaus. 5. Due credit should be given to The
    19   * Codehaus - http://groovy.codehaus.org/
    20   *
    21   * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
    22   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    23   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    24   * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
    25   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    27   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    28   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    31   * DAMAGE.
    32   *
    33   */
    34  package org.codehaus.groovy.classgen;
    35
    36  import groovy.lang.GroovyRuntimeException;
    37  import org.codehaus.groovy.ast.*;
    38  import org.objectweb.asm.ClassVisitor;
    39  import org.objectweb.asm.MethodVisitor;
    40
    41  import java.util.*;
    42
    43  /***
    44   * To generate a class that has all the fields and methods, except that fields are not initilized
    45   * and methods are empty. It's intended for being used as a place holder during code generation
    46   * of reference to the "this" class itself.
    47   *
    48   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    49   * @author <a href="mailto:b55r@sina.com">Bing Ran</a>
    50   *
    51   * @version $Revision: 1.7 $
    52   */
    53  public class DummyClassGenerator extends ClassGenerator {
    54
    55      private ClassVisitor cw;
    56      private MethodVisitor cv;
    57      private GeneratorContext context;
    58
    59      private String sourceFile;
    60
    61      // current class details
    62      private ClassNode classNode;
    63      private String internalClassName;
    64      private String internalBaseClassName;
    65
    66
    67      public DummyClassGenerator(
    68          GeneratorContext context,
    69          ClassVisitor classVisitor,
    70          ClassLoader classLoader,
    71          String sourceFile) {
    72          super(classLoader);
    73          this.context = context;
    74          this.cw = classVisitor;
    75          this.sourceFile = sourceFile;
    76      }
    77
    78      // GroovyClassVisitor interface
    79      //-------------------------------------------------------------------------
    80      public void visitClass(ClassNode classNode) {
    81          try {
    82              this.classNode = classNode;
    83              this.internalClassName = BytecodeHelper.getClassInternalName(classNode);
    84
    85              //System.out.println("Generating class: " + classNode.getName());
    86
    87              this.internalBaseClassName = BytecodeHelper.getClassInternalName(classNode.getSuperClass());
    88
    89              cw.visit(
    90                  asmJDKVersion,
    91                  classNode.getModifiers(),
    92                  internalClassName,
    93                  (String)null,
    94                  internalBaseClassName,
    95                  BytecodeHelper.getClassInternalNames(classNode.getInterfaces())
    96                  );
    97
    98              classNode.visitContents(this);
    99
    100             for (Iterator iter = innerClasses.iterator(); iter.hasNext();) {
    101                 ClassNode innerClass = (ClassNode) iter.next();
    102                 ClassNode innerClassType = innerClass;
    103                 String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassType);
    104                 String outerClassName = internalClassName; // default for inner classes
    105                 MethodNode enclosingMethod = innerClass.getEnclosingMethod();
    106                 if (enclosingMethod != null) {
    107                     // local inner classes do not specify the outer class name
    108                     outerClassName = null;
    109                 }
    110                 cw.visitInnerClass(
    111                     innerClassInternalName,
    112                     outerClassName,
    113                     innerClassType.getName(),
    114                     innerClass.getModifiers());
    115             }
    116             cw.visitEnd();
    117         }
    118         catch (GroovyRuntimeException e) {
    119             e.setModule(classNode.getModule());
    120             throw e;
    121         }
    122     }
    123
    124     public void visitConstructor(ConstructorNode node) {
    125
    126         visitParameters(node, node.getParameters());
    127
    128         String methodType = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, node.getParameters());
    129         cv = cw.visitMethod(node.getModifiers(), "<init>", methodType, null, null);
    130         cv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    131         cv.visitInsn(DUP);
    132         cv.visitLdcInsn("not intended for execution");
    133         cv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
    134         cv.visitInsn(ATHROW);
    135         cv.visitMaxs(0, 0);
    136     }
    137
    138     public void visitMethod(MethodNode node) {
    139
    140         visitParameters(node, node.getParameters());
    141
    142         String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), node.getParameters());
    143         cv = cw.visitMethod(node.getModifiers(), node.getName(), methodType, null, null);
    144
    145         cv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    146         cv.visitInsn(DUP);
    147         cv.visitLdcInsn("not intended for execution");
    148         cv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
    149         cv.visitInsn(ATHROW);
    150
    151         cv.visitMaxs(0, 0);
    152     }
    153
    154     public void visitField(FieldNode fieldNode) {
    155
    156         cw.visitField(
    157             fieldNode.getModifiers(),
    158             fieldNode.getName(),
    159             BytecodeHelper.getTypeDescription(fieldNode.getType()),
    160             null, //fieldValue,  //br  all the sudden that one cannot init the field here. init is done in static initilizer and instace intializer.
    161             null);
    162     }
    163
    164     /***
    165      * Creates a getter, setter and field
    166      */
    167     public void visitProperty(PropertyNode statement) {
    168     }
    169
    170     protected CompileUnit getCompileUnit() {
    171         CompileUnit answer = classNode.getCompileUnit();
    172         if (answer == null) {
    173             answer = context.getCompileUnit();
    174         }
    175         return answer;
    176     }
    177
    178     protected void visitParameters(ASTNode node, Parameter[] parameters) {
    179         for (int i = 0, size = parameters.length; i < size; i++ ) {
    180             visitParameter(node, parameters[i]);
    181         }
    182     }
    183
    184     protected void visitParameter(ASTNode node, Parameter parameter) {
    185     }
    186
    187
    188     public void visitAnnotations(AnnotatedNode node) {
    189     }
    190 }