alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (PEType.java)

This example Scala source code file (PEType.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

arraylist, arraylist, fieldinfo, methodbase, methodinfo, methodinfo, parameterinfo, pemethodinfo, petype, sig, string, string, type, type, util

The Scala PEType.java source code

/*
 * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
 */


package ch.epfl.lamp.compiler.msil;

import ch.epfl.lamp.compiler.msil.PEFile.Sig;

import ch.epfl.lamp.compiler.msil.util.Table;
import ch.epfl.lamp.compiler.msil.util.Table.*;
import ch.epfl.lamp.compiler.msil.util.Signature;
import ch.epfl.lamp.compiler.msil.util.PECustomMod;

import java.util.ArrayList;

/**
 * Represents a type from a .NET assembly
 *
 * @author Nikolay Mihaylov
 * @version 1.0
 */
final class PEType extends Type implements Signature {

    //##########################################################################

    /** The PEFile that holds the description of the type. */
    final PEFile file;

    /** The number of the row in the TypeDef table defining the type. */
    final int definingRow;

    /** The row of the first method in the MethodDef table. */
    final int methodListBeg;

    /** The row of the last method in the MethodDef table + 1. */
    final int methodListEnd;

    /** @param definingRow - the index in the TypeDef table where
     *  the type description is.
     */
    PEType(PEModule module,
	   int attributes,
	   String fullName,
	   Type declType,
	   int auxAttr,
	   PEFile file,
	   int definingRow)
    {
	super(module, attributes, fullName, null, null, declType, auxAttr);
	this.file = file;
	this.definingRow = definingRow;
	methodListBeg = file.TypeDef(definingRow).MethodList;
	methodListEnd = definingRow < file.TypeDef.rows
	    ? file.TypeDef(definingRow + 1).MethodList
	    : file.MethodDef.rows + 1;
    }

    //##########################################################################
    // lazy type construction methods

    protected void loadBaseType() {
	TypeDef type = file.TypeDef(definingRow);
	baseType = type.Extends == 0 ? null
	    : ((PEModule)Module).getTypeDefOrRef(type.Extends);
    }

    protected void loadFields() {
	// the list of the declared fields starts from the
	// FieldList index in the TypeDef table up to the smaller of the:
	//  - the last row of the FieldDef table
	//  - the start of the next list of fields determined by the
	// FieldList index of the next row in the TypeDef table
	final ArrayList fields = new ArrayList();
	int fieldListBeg = file.TypeDef(definingRow).FieldList;
	int fieldListEnd = file.FieldDef.rows + 1;
	if (definingRow < file.TypeDef.rows)
	    fieldListEnd = file.TypeDef(definingRow + 1).FieldList;

	for (int row = fieldListBeg; row < fieldListEnd; row++) {
	    int frow = file.FieldTrans.rows == 0
		? row : file.FieldTrans(row).Field;
	    int attrs = file.FieldDef(frow).Flags;
	    String name = file.FieldDef.getName();
	    //System.out.println("\t-->Loading field: " + name);
	    Sig sig = file.FieldDef.getSignature();
	    PECustomMod pecmod = sig.decodeFieldType();
	    Object val = null;
	    Table.Constant consts = file.Constant;
	    for (int i = 1; i <= consts.rows; i++) {
		consts.readRow(i);
		int tableId = Table.getTableId(Table._HasConstant,consts.Parent);
		int refRow = consts.Parent >> Table.NoBits[Table._HasConstant];
		if (tableId == Table.FieldDef.ID && refRow == frow)
		    val = consts.getValue();
	    }
	    FieldInfo field = new PEFieldInfo(row, name, attrs, pecmod, val);
	    if (field.Name.equals("value__") && field.IsSpecialName()) {
		    assert underlyingType == null : underlyingType.toString();
		    underlyingType = field.FieldType;
		}
	    fields.add(field);
	}
	this.fields = (FieldInfo[])
	    fields.toArray(FieldInfo.EMPTY_ARRAY);
	fields.clear();
    }

    protected MethodBase[] methoddefs;

    protected MethodInfo getMethod(int n) {
        return (MethodInfo)methoddefs[n - methodListBeg];
    }

    protected void loadMethods() {
	methoddefs = new MethodBase[methodListEnd - methodListBeg];

	final ArrayList methods = new ArrayList();
	final ArrayList constrs = new ArrayList();
	PEModule pemodule = (PEModule) Module;
	for (int row = methodListBeg; row < methodListEnd; row++) {
	    int mrow = file.MethodTrans.rows == 0
		? row : file.MethodTrans(row).Method;
	    int attrs = file.MethodDef(mrow).Flags;
	    String name = file.MethodDef.getName();
	    Sig sig = file.MethodDef.getSignature();
            /* we're about to parse a MethodDefSig, defined in Sec. 23.2.1 of Partition II ()  */

	    int callConv = sig.readByte();
            // TODO decode HASTHIS from high byte of calling convention
            // TODO decode EXPLICITTHIS from high byte of calling convention
            // TODO handle VARARG calling convention (not CLS but may show up )
            if((callConv & 0x1F) == Signature.GENERIC) {
                int genParamCount = sig.decodeInt();
                /* genParamCount is ignored because the method's type params will be obtained below
                (see: file.GenericParam.getMVarIdxes(row) ) */
            }
	    int paramCount = sig.decodeInt();
	    Type retType = sig.decodeRetType();
	    Type[] paramType = new Type[paramCount];
	    for (int i = 0; i < paramCount; i++)
		paramType[i] = sig.decodeParamType();

	    ParameterInfo[] params = new ParameterInfo[paramCount];
	    int paramListBeg = file.MethodDef.ParamList;
            int paramListEnd = paramListBeg + paramCount;
            if (paramListEnd > file.ParamDef.rows) {
                /* don't try to read param names past ParamDef's row count
                   Some assembly-writers don't bother to give names for all params. */
                paramListEnd = file.ParamDef.rows + 1;
	    }
	    for (int i = paramListBeg; i < paramListEnd; i++) {
		int pattr = file.ParamDef(i).Flags;
		String paramName = file.ParamDef.getName();
		int seq = file.ParamDef.Sequence;
		if (seq == 0) {
		    //System.out.println("Retval attributes 0x" +
		    //		       PEFile.short2hex(pattr));
		} else {
		    params[seq - 1] = new ParameterInfo(paramName, paramType[seq - 1], pattr, seq - 1);
		}
	    }
	    for (int i = 0; i < params.length; i++) {
		if (params[i] == null)
		    params[i] = new ParameterInfo(null, paramType[i], 0, 0);
	    }
	    MethodBase method = null;
	    if ((attrs & MethodAttributes.SpecialName) != 0
		&& (attrs & MethodAttributes.RTSpecialName) != 0
		&& (name.equals(ConstructorInfo.CTOR)
		    || name.equals(ConstructorInfo.CCTOR)))
            {
		method = new PEConstructorInfo(row, attrs, params);
            }
            else {
		method = new PEMethodInfo(row, name, attrs, retType, params);
                int[] mvarIdxes = file.GenericParam.getMVarIdxes(row);
                // if(mvarIdxes.length > 0) { System.out.println("Method: " + method); }
                for(int i = 0; i < mvarIdxes.length; i++) {
                    GenericParamAndConstraints mvarAndConstraints = pemodule.getTypeConstraints(mvarIdxes[i]);
                    // add mvarAndConstraints as i-th MVar in method
                    ((PEMethodInfo)method).addMVar(mvarAndConstraints);
                }
            }
	    (method.IsConstructor() ? constrs : methods).add(method);
	    methoddefs[row - methodListBeg] = method;
	}

	this.constructors = (ConstructorInfo[])
	    constrs.toArray(ConstructorInfo.EMPTY_ARRAY);
	this.methods = (MethodInfo[])
	    methods.toArray(MethodInfo.EMPTY_ARRAY);
	constrs.clear(); methods.clear();
    }

    protected void loadProperties() {
	final PropertyMap pmap = file.PropertyMap;
	if (pmap == null) {
	    properties = PropertyInfo.EMPTY_ARRAY;
	    return;
	}

        final PropertyDef pdef = file.PropertyDef;
        int propListBeg =  -1;
        int propListEnd = pdef.rows + 1;
	for (int i = 1; i <= pmap.rows; i++) {
	    pmap.readRow(i);
	    if (pmap.Parent == this.definingRow) {
                propListBeg = pmap.PropertyList;
                if (i < pmap.rows) {
                    pmap.readRow(i + 1);
                    propListEnd = pmap.PropertyList;
                }
                break;
            }
        }
	if (propListBeg < 0) {
	    properties = PropertyInfo.EMPTY_ARRAY;
	    return;
	}

	final ArrayList properties = new ArrayList();
        for (int i = propListBeg; i < propListEnd; i++) {
            pdef.readRow(i);
            Sig sig = pdef.getSignature();
            int b = sig.readByte();
            b &= ~HASTHIS;
            int paramCount = sig.readByte();
            assert b == PROPERTY;
            Type propType = sig.decodeType();
            int index = Table.encodeIndex(i, Table._HasSemantics,
                                          Table.PropertyDef.ID);
            MethodSemantics msem = file.MethodSemantics;
            MethodInfo getter = null, setter = null;
            for (int j = 1; j <= msem.rows; j++) {
                msem.readRow(j);
                if (msem.Association != index)
                    continue;
                if (msem.isGetter())
                    getter = getMethod(msem.Method);
                else if (msem.isSetter())
                    setter = getMethod(msem.Method);
                else
                    System.err.println("PEType.loadProperties(): !?!");
            }
            properties.add
                (new PEPropertyInfo(i, pdef.getName(), (short)pdef.Flags,
                                    propType, getter, setter));
	}
	this.properties = (PropertyInfo[]) properties
	    .toArray(PropertyInfo.EMPTY_ARRAY);
    }

    protected void loadEvents() {
        EventMap emap = file.EventMap;
        if (emap == null) {
            this.events = EventInfo.EMPTY_ARRAY;
            return;
        }

        final EventDef edef = file.EventDef;
        int eventListBeg = -1;
        int eventListEnd = edef.rows + 1;
        for (int i = 1; i <= emap.rows; i++) {
            emap.readRow(i);
            if (emap.Parent == this.definingRow) {
                eventListBeg = emap.EventList;
                if (i < emap.rows) {
                    emap.readRow(i + 1);
                    eventListEnd = emap.EventList;
                }
                break;
            }
        }
        if (eventListBeg < 0) {
            this.events = EventInfo.EMPTY_ARRAY;
            return;
        }

        final ArrayList events = new ArrayList();
        final MethodSemantics msem = file.MethodSemantics;
        for (int i = eventListBeg; i < eventListEnd; i++) {
            edef.readRow(i);
            final Type handler =
                ((PEModule)Module).getTypeDefOrRef(edef.EventType);
            int index =
                Table.encodeIndex(i, Table._HasSemantics, Table.EventDef.ID);
            MethodInfo add = null, remove = null;
            for (int j = 1; j <= msem.rows; j++) {
                msem.readRow(j);
                if (msem.Association != index)
                    continue;
                if (msem.isAddOn())
                    add = getMethod(msem.Method);
                else if (msem.isRemoveOn())
                    remove = getMethod(msem.Method);
                else {
                }
            }
            events.add(new PEEventInfo(i, edef.getName(),
                                       (short)edef.EventFlags,
                                       handler, add, remove));
        }
        this.events = (EventInfo[]) events
            .toArray(EventInfo.EMPTY_ARRAY);
    }

    protected void loadNestedTypes() {
	final ArrayList nested = new ArrayList();
	for (int i = 1; i <= file.NestedClass.rows; i++) {
	    file.NestedClass.readRow(i);
	    if (file.NestedClass.EnclosingClass == this.definingRow)
		nested.add(((PEModule)Module)
			   .getTypeDef(file.NestedClass.NestedClass));
	}
	this.nestedTypes = (Type[]) nested.toArray(Type.EmptyTypes);
    }

    protected void loadInterfaces() {
	// get the interfaces implemented by this class
	interfaces = Type.EmptyTypes;
	int index = file.InterfaceImpl.findType(definingRow);
	if (index > 0) {
	    ArrayList ifaces = new ArrayList();
	    for (int i = index; i <= file.InterfaceImpl.rows; i++) {
		file.InterfaceImpl.readRow(i);
		if (file.InterfaceImpl.Class != definingRow)
		    break;
		ifaces.add(((PEModule)Module)
			   .getTypeDefOrRef(file.InterfaceImpl.Interface));
	    }
	    interfaces = (Type[]) ifaces.toArray(new Type[ifaces.size()]);
	}
    }

    protected void loadCustomAttributes(Type attributeType) {
	initAttributes(this, definingRow, Table.TypeDef.ID, attributeType);
    }

    private void initAttributes(CustomAttributeProvider cap, int definingRow,
                                 int sourceTableId, Type attributeType)
    {
        ((PEModule)this.Module).initAttributes
            (cap, definingRow, sourceTableId, attributeType);
    }

    //##########################################################################

    private class PEFieldInfo extends FieldInfo {
	private final int definingRow;
	public PEFieldInfo(int definingRow, String name,
                       int attrs, PECustomMod pecmod, Object value)
	{
	    super(name, PEType.this, attrs, pecmod, value);
	    this.definingRow = definingRow;
	}
	protected void loadCustomAttributes(Type attributeType) {
	    PEType.this.initAttributes
                (this, definingRow, Table.FieldDef.ID, attributeType);
	}
    }

    private class PEMethodInfo extends MethodInfo {
	private final int definingRow;
	public PEMethodInfo(int row, String name,
                            int attrs, Type retType, ParameterInfo[] params)
	{
	    super(name, PEType.this, attrs, retType, params);
	    this.definingRow = row;
	}
	protected void loadCustomAttributes(Type attributeType) {
	    PEType.this.initAttributes
                (this, definingRow, Table.MethodDef.ID, attributeType);
	}
    }

    private class PEConstructorInfo extends ConstructorInfo {
	private final int definingRow;
	public PEConstructorInfo(int row, int attrs, ParameterInfo[] params) {
	    super(PEType.this, attrs, params);
	    this.definingRow = row;
	}
	protected void loadCustomAttributes(Type attributeType) {
	    PEType.this.initAttributes
                (this, definingRow, Table.MethodDef.ID, attributeType);
	}
    }

    private class PEPropertyInfo extends PropertyInfo {
	private final int definingRow;
	public PEPropertyInfo(int row, String name, short attrs, Type propType,
                              MethodInfo getter, MethodInfo setter)
	{
	    super(name, PEType.this, attrs, propType, getter, setter);
	    this.definingRow = row;
	}
	protected void loadCustomAttributes(Type attributeType) {
	    PEType.this.initAttributes
                (this, definingRow, Table.PropertyDef.ID, attributeType);
	}
    }

    private class PEEventInfo extends EventInfo {
        private final int definingRow;
        public PEEventInfo(int row, String name, short attrs, Type handler,
                           MethodInfo add, MethodInfo remove)
        {
            super(name, PEType.this, attrs, handler, add, remove);
            this.definingRow = row;
        }
        protected void loadCustomAttributes(Type attributeType) {
            PEType.this.initAttributes
                (this, definingRow, Table.EventDef.ID, attributeType);
        }
    }

    //##########################################################################

}  // class PEType

Other Scala examples (source code examples)

Here is a short list of links related to this Scala PEType.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.