All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.extendj.ast.AbstractClassfileParser Maven / Gradle / Ivy

package org.extendj.ast;

import java.util.ArrayList;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Set;
import beaver.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.LinkedHashSet;
import java.util.*;
import org.jastadd.util.PrettyPrintable;
import org.jastadd.util.PrettyPrinter;
import java.util.zip.*;
import java.io.*;
import org.jastadd.util.*;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
/**
 * @ast class
 * @aspect ClassfileParser
 * @declaredat /home/jesper/git/extendj/java4/frontend/ClassfileParser.jrag:34
 */
public abstract class AbstractClassfileParser extends java.lang.Object {
  

    public static class ClassfileFormatError extends Error {
      public ClassfileFormatError(String message) {
        super(message);
      }
    }

  

    public static final boolean VERBOSE = false;

  

    protected static final int CONSTANT_Class = 7;

  
    protected static final int CONSTANT_FieldRef = 9;

  
    protected static final int CONSTANT_MethodRef = 10;

  
    protected static final int CONSTANT_InterfaceMethodRef = 11;

  
    protected static final int CONSTANT_String = 8;

  
    protected static final int CONSTANT_Integer = 3;

  
    protected static final int CONSTANT_Float = 4;

  
    protected static final int CONSTANT_Long = 5;

  
    protected static final int CONSTANT_Double = 6;

  
    protected static final int CONSTANT_NameAndType = 12;

  
    protected static final int CONSTANT_Utf8 = 1;

  

    private DataInputStream is;

  

    public final String name;

  
    public CONSTANT_Class_Info classInfo;

  
    public CONSTANT_Info[] constantPool = null;

  

    // For Java 5 and later.
    public boolean isInnerClass = false;

  

    public AbstractClassfileParser(InputStream in, String name) {
      this.is = new DataInputStream(new BufferedInputStream(in));
      this.name = name;
    }

  

    public abstract boolean outerClassNameEquals(String name);

  

    public final int next() throws IOException {
      return is.read();
    }

  

    public final int u1() throws IOException {
      return is.readUnsignedByte();
    }

  

    public final int u2() throws IOException {
      return is.readUnsignedShort();
    }

  

    public final int u4() throws IOException {
      return is.readInt();
    }

  

    public final int readInt() throws IOException {
      return is.readInt();
    }

  

    public final float readFloat() throws IOException {
      return is.readFloat();
    }

  

    public final long readLong() throws IOException {
      return is.readLong();
    }

  

    public final double readDouble() throws IOException {
      return is.readDouble();
    }

  

    public final String readUTF() throws IOException {
      return is.readUTF();
    }

  

    public final void skip(int length) throws IOException {
      while (length > 0) {
        length -= is.skip(length);
      }
    }

  

    public void error(String msg) throws ClassfileFormatError {
      throw new ClassfileFormatError(msg);
    }

  

    public final void print(String s) {
    }

  

    public final void println(String s) {
      print(s + "\n");
    }

  

    public final void println() {
      print("\n");
    }

  

    public final void format(String fmt, Object... args) {
      print(String.format(fmt, args));
    }

  

    public final void parseMagic() throws IOException {
      if (next() != 0xca || next() != 0xfe || next() != 0xba || next() != 0xbe) {
        error("magic error");
      }
    }

  

    public final int parseMinor() throws IOException {
      return u2();
    }

  

    public final int parseMajor() throws IOException {
      return u2();
    }

  

    public final String parseThisClass() throws IOException {
      int index = u2();
      CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[index];
      classInfo = info;
      return info.simpleName();
    }

  

    public final Access parseSuperClass() throws IOException {
      int index = u2();
      if (index == 0) {
        return null;
      }
      CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[index];
      return info.access();
    }

  

    public final List parseInterfaces(List list) throws IOException {
      int count = u2();
      for (int i = 0; i < count; i++) {
        CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[u2()];
        list.add(info.access());
      }
      return list;
    }

  

    public void parseFields(TypeDecl typeDecl) throws IOException {
      int count = u2();
      if (VERBOSE) {
        println("Fields (" + count + "):");
      }
      for (int i = 0; i < count; i++) {
        if (VERBOSE) {
          print(" Field nbr " + i + " ");
        }
        FieldInfo fieldInfo = new FieldInfo(this);
        if (!fieldInfo.isSynthetic()) {
          typeDecl.addBodyDecl(fieldInfo.bodyDecl());
        }
      }
    }

  

    public static Modifiers modifiers(int flags) {
      Modifiers m = new Modifiers();
      if ((flags & 0x0001) != 0) {
        m.addModifier(new Modifier("public"));
      }
      if ((flags & 0x0002) != 0) {
        m.addModifier(new Modifier("private"));
      }
      if ((flags & 0x0004) != 0) {
        m.addModifier(new Modifier("protected"));
      }
      if ((flags & 0x0008) != 0) {
        m.addModifier(new Modifier("static"));
      }
      if ((flags & 0x0010) != 0) {
        m.addModifier(new Modifier("final"));
      }
      if ((flags & 0x0020) != 0) {
        m.addModifier(new Modifier("synchronized"));
      }
      if ((flags & 0x0040) != 0) {
        m.addModifier(new Modifier("volatile"));
      }
      if ((flags & 0x0080) != 0) {
        m.addModifier(new Modifier("transient"));
      }
      if ((flags & 0x0100) != 0) {
        m.addModifier(new Modifier("native"));
      }
      if ((flags & 0x0400) != 0) {
        m.addModifier(new Modifier("abstract"));
      }
      if ((flags & 0x0800) != 0) {
        m.addModifier(new Modifier("strictfp"));
      }
      return m;
    }

  

    private void checkLengthAndNull(int index) {
      if (index >= constantPool.length) {
        throw new Error("Trying to access element " + index  + " in constant pool of length "
            + constantPool.length);
      }
      if (constantPool[index] == null) {
        throw new Error("Unexpected null element in constant pool at index " + index);
      }
    }

  

    public boolean validConstantPoolIndex(int index) {
      return index < constantPool.length && constantPool[index] != null;
    }

  

    public CONSTANT_Info getCONSTANT_Info(int index) {
      checkLengthAndNull(index);
      return constantPool[index];
    }

  

    public CONSTANT_Utf8_Info getCONSTANT_Utf8_Info(int index) {
      checkLengthAndNull(index);
      CONSTANT_Info info = constantPool[index];
      if (!(info instanceof CONSTANT_Utf8_Info)) {
        throw new Error("Expected CONSTANT_Utf8_info at " + index + " in constant pool but found "
            + info.getClass().getName());
      }
      return (CONSTANT_Utf8_Info) info;
    }

  

    public CONSTANT_Class_Info getCONSTANT_Class_Info(int index) {
      checkLengthAndNull(index);
      CONSTANT_Info info = constantPool[index];
      if (!(info instanceof CONSTANT_Class_Info)) {
        throw new Error("Expected CONSTANT_Class_info at " + index + " in constant pool but found "
            + info.getClass().getName());
      }
      return (CONSTANT_Class_Info) info;
    }

  

    public void parseConstantPool() throws IOException {
      int count = u2();
      if (VERBOSE) {
        println("constant_pool_count: " + count);
      }
      constantPool = new CONSTANT_Info[count + 1];
      for (int i = 1; i < count; i++) {
        parseConstantPoolEntry(i);
        if (constantPool[i] instanceof CONSTANT_Long_Info
            || constantPool[i] instanceof CONSTANT_Double_Info) {
          i++;
        }
      }
    }

  

    protected abstract void parseConstantPoolEntry(int i) throws IOException;


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy