summaryrefslogtreecommitdiff
path: root/sources/scalac/backend/msil/TypeCreator.java
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/backend/msil/TypeCreator.java')
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java1449
1 files changed, 0 insertions, 1449 deletions
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
deleted file mode 100644
index de0bd4a264..0000000000
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ /dev/null
@@ -1,1449 +0,0 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-\* */
-
-// $Id$
-
-package scalac.backend.msil;
-
-import scalac.Global;
-import scalac.Phase;
-import scalac.CompilationUnit;
-import scalac.ApplicationError;
-import scalac.ast.Tree;
-import scalac.ast.Traverser;
-import scalac.atree.AConstant;
-import scalac.util.Debug;
-import scalac.util.Name;
-import scalac.util.Names;
-import scalac.util.SourceRepresentation;
-import scalac.symtab.Kinds;
-import scalac.symtab.TypeTags;
-import scalac.symtab.Symbol;
-import scalac.symtab.Scope;
-import scalac.symtab.Modifiers;
-import scalac.symtab.Definitions;
-import scalac.symtab.AttributeInfo;
-import scalac.symtab.classfile.CLRTypes;
-import scala.tools.util.Position;
-import scala.tools.util.SourceFile;
-
-import Tree.*;
-
-import ch.epfl.lamp.compiler.msil.*;
-import ch.epfl.lamp.compiler.msil.emit.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-
-/**
- * Creates System.Reflection objects corresponding to
- * Scala symbols
- *
- * @author Nikolay Mihaylov
- * @version 1.1
- */
-
-final class TypeCreator {
-
- //private final GenMSIL gen;
- private final Global global;
- private final Definitions defs;
-
- private final ArrayList typeBuilders = new ArrayList();
-
- // for every method of an object give the corresponding static method
- // of the accompanying class
- private final Map/*<Symbol, MethodBuilder>*/ syms2staticMethods = new HashMap();
-
- private final Map types2symbols = new HashMap();
- private final Map symbols2types = new HashMap();
- private final Map symbols2fields = new HashMap();
- private final Map symbols2methods = new HashMap();
- private final Map symbols2moduleFields = new HashMap();
- private final Set specialAttrs = new HashSet();
-
- public static final String MODULE_S = "$MODULE";
-
- public final Type BYTE;
- public final Type CHAR;
- public final Type SHORT;
- public final Type INT;
- public final Type LONG;
- public final Type FLOAT;
- public final Type DOUBLE;
- public final Type BOOLEAN;
- public final Type VOID;
- public final Type ENUM;
-
- public final Type OBJECT;
- public final Type STRING;
- public final Type STRING_ARRAY;
- public final Type ICLONEABLE;
-
- private final Type MONITOR;
-
- public final MethodInfo CONCAT_OBJECT_OBJECT;
- public final MethodInfo OBJECT_EQUALS;
- public final MethodInfo MONITOR_ENTER;
- public final MethodInfo MONITOR_EXIT;
- public final MethodInfo MEMBERWISE_CLONE;
-// private final MethodInfo MONITOR_PULSE;
-// private final MethodInfo MONITOR_PULSE_ALL;
-// private final MethodInfo MONITOR_WAIT;
-// private final MethodInfo MONITOR_WAIT_TIMEOUT;
-
- public final Type SCALA_BYTE;
- public final Type SCALA_SHORT;
- public final Type SCALA_INT;
- public final Type SCALA_LONG;
- public final Type SCALA_FLOAT;
- public final Type SCALA_DOUBLE;
- public final Type SCALA_CHAR;
- public final Type SCALA_BOOLEAN;
- public final Type SCALA_UNIT;
-
- public final MethodInfo RUNTIME_BOX_UNIT ;
-
- public Symbol SYM_SUBSTRING_INT_INT;
- public MethodInfo SUBSTRING_INT_INT;
- public Symbol SYM_COMPARE_TO_IGNORE_CASE;
- public MethodInfo COMPARE_TO_IGNORE_CASE;
-
- public ConstructorInfo SYMTAB_CONSTR;
- public ConstructorInfo SYMTAB_DEFAULT_CONSTR;
-
- private scalac.symtab.Type MAIN_METHOD_TYPE;
-
- private final Symbol SYSTEM_SERIALIZABLE_CONSTR;
- private final Symbol SYSTEM_NONSERIALIZED_CONSTR;
-
- private final CLRTypes ti;
-
- private final Phase backPhase;
-
- //##########################################################################
-
- TypeCreator(Global global) {
- this.global = global;
- this.defs = global.definitions;
- this.backPhase = global.PHASE.ADDINTERFACES.phase();
-
- ti = CLRTypes.instance();
-
- BYTE = ti.BYTE;
- CHAR = ti.CHAR;
- SHORT = ti.SHORT;
- INT = ti.INT;
- LONG = ti.LONG;
- FLOAT = ti.FLOAT;
- DOUBLE = ti.DOUBLE;
- BOOLEAN = ti.BOOLEAN;
- VOID = ti.VOID;
- ENUM = ti.ENUM;
-
- OBJECT = ti.OBJECT;
- STRING = ti.STRING;
- STRING_ARRAY = Type.GetType("System.String[]");
- ICLONEABLE = Type.GetType("System.ICloneable");
- MONITOR = Type.GetType("System.Threading.Monitor");
-
- final Type[] sObject1 = new Type[] {OBJECT};
-
- //CONCAT_OBJECT = STRING.GetMethod("Concat", new Type[] {OBJECT});
- //CONCAT_STRING_STRING = STRING.GetMethod("Concat", new Type[] {STRING, STRING});
- CONCAT_OBJECT_OBJECT =
- STRING.GetMethod("Concat", new Type[] {OBJECT, OBJECT});
- OBJECT_EQUALS = OBJECT.GetMethod("Equals", sObject1);
-// MONITOR_PULSE = MONITOR.GetMethod("Pulse", sObject1);
-// MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", sObject1);
-// MONITOR_WAIT = MONITOR.GetMethod("Wait", sObject1);
-// MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT});
- MONITOR_ENTER = MONITOR.GetMethod("Enter", sObject1);
- MONITOR_EXIT = MONITOR.GetMethod("Exit", sObject1);
- MEMBERWISE_CLONE = ti.MEMBERWISE_CLONE;
-
- SCALA_BYTE = getType("scala.Byte");
- SCALA_SHORT = getType("scala.Short");
- SCALA_INT = getType("scala.Int");
- SCALA_LONG = getType("scala.Long");
- SCALA_FLOAT = getType("scala.Float");
- SCALA_DOUBLE = getType("scala.Double");
- SCALA_CHAR = getType("scala.Char");
- SCALA_BOOLEAN = getType("scala.Boolean");
- SCALA_UNIT = getType("scala.Unit");
-
- RUNTIME_BOX_UNIT = getType("scala.runtime.RunTime")
- .GetMethod("box_uvalue", Type.EmptyTypes);
- ti.map(defs.OBJECT_CLONE, MEMBERWISE_CLONE);
-
- SYSTEM_SERIALIZABLE_CONSTR = defs.getClass("System.SerializableAttribute")
- .primaryConstructor();
- SYSTEM_NONSERIALIZED_CONSTR = defs.getClass("System.NonSerializedAttribute")
- .primaryConstructor();
-
- }
-
- private boolean initialized = false;
-
- /*
- * Called from GenMSILPhase
- */
- public void init() {
- if (initialized)
- return;
- final Symbol JOBJECT = defs.OBJECT_CLASS; //defs.getClass("java.lang.Object");
- final Symbol JSTRING = defs.STRING_CLASS;
-
- // initialize type mappings
- map(defs.ANY_CLASS, OBJECT);
- map(defs.ANYREF_CLASS, OBJECT);
- map(JOBJECT, OBJECT);
- map(JSTRING, STRING);
-
- // constants useful for method mappings
- final scalac.symtab.Type UNBOXED_LONG =
- new scalac.symtab.Type.UnboxedType(TypeTags.LONG);
- final scalac.symtab.Type UNBOXED_INT =
- new scalac.symtab.Type.UnboxedType(TypeTags.INT);
- final scalac.symtab.Type UNBOXED_CHAR =
- new scalac.symtab.Type.UnboxedType(TypeTags.CHAR);
-
- final scalac.symtab.Type[] jEmpty = scalac.symtab.Type.EMPTY_ARRAY;
- final scalac.symtab.Type[] jString1 = new scalac.symtab.Type[]
- {defs.STRING_TYPE()};
- final scalac.symtab.Type[] jInt1 = new scalac.symtab.Type[]
- {UNBOXED_INT};
- final scalac.symtab.Type[] jInt2 = new scalac.symtab.Type[]
- {UNBOXED_INT, UNBOXED_INT};
- final scalac.symtab.Type[] jStringInt = new scalac.symtab.Type[]
- {defs.STRING_TYPE(), UNBOXED_INT};
- final scalac.symtab.Type[] jChar2 = new scalac.symtab.Type[]
- {UNBOXED_CHAR, UNBOXED_CHAR};
-
- final Type[] sObject1 = new Type[] {OBJECT};
- final Type[] sString1 = new Type[] {STRING};
- final Type[] sString2 = new Type[] {STRING, STRING};
- final Type[] sChar1 = new Type[] {CHAR};
- final Type[] sCharInt2 = new Type[] {CHAR, INT};
-
- final Type ObjectImpl = Type.GetType("com.ms.vjsharp.lang.ObjectImpl");
-
- // map methods of java.lang.Object
- translateMethod(JOBJECT, "equals", OBJECT, "Equals");
- translateMethod(JOBJECT, "hashCode", OBJECT, "GetHashCode");
- translateMethod(JOBJECT, "toString", OBJECT, "ToString");
- translateMethod(JOBJECT, "finalize", OBJECT, "Finalize");
- translateMethod(JOBJECT, "wait", jEmpty, MONITOR, "Wait", sObject1);
- translateMethod(JOBJECT, "wait", new scalac.symtab.
- Type[] {UNBOXED_LONG}, // defs.LONG_TYPE
- MONITOR, "Wait",
- new Type[] {OBJECT, INT});
- translateMethod(JOBJECT, "notify", jEmpty, MONITOR, "Pulse", sObject1);
- translateMethod(JOBJECT, "notifyAll", jEmpty, MONITOR, "PulseAll", sObject1);
- //translateMethod(JOBJECT, "getClass", jEmpty, ObjectImpl, "getClass", sObject1);
-
- // map methods of java.lang.String
- //translateMethod(JSTRING, "equals", STRING, "Equals");
- //translateMethod(JSTRING, "toString", STRING, "ToString");
- translateMethod(JSTRING, "compareTo", STRING, "CompareTo");
- translateMethod(JSTRING, "length", STRING, "get_Length");
- translateMethod(JSTRING, "charAt", STRING, "get_Chars");
- translateMethod(JSTRING, "concat", jString1, STRING, "Concat", sString2);
- translateMethod(JSTRING, "indexOf", jInt1, STRING, "IndexOf", sChar1);
- translateMethod(JSTRING, "indexOf", jInt2, STRING, "IndexOf", sCharInt2);
- translateMethod(JSTRING, "indexOf", jString1, STRING, "IndexOf");
- translateMethod(JSTRING, "indexOf", jStringInt, STRING, "IndexOf");
- translateMethod(JSTRING, "lastIndexOf", jInt1, STRING, "LastIndexOf", sChar1);
- translateMethod(JSTRING, "lastIndexOf", jInt2, STRING, "LastIndexOf", sCharInt2);
- translateMethod(JSTRING, "lastIndexOf", jString1, STRING, "LastIndexOf");
- translateMethod(JSTRING, "lastIndexOf", jStringInt, STRING, "LastIndexOf");
- translateMethod(JSTRING, "toLowerCase", jEmpty, STRING, "ToLower");
- translateMethod(JSTRING, "toUpperCase", jEmpty, STRING, "ToUpper");
- translateMethod(JSTRING, "startsWith", jString1, STRING, "StartsWith");
- translateMethod(JSTRING, "endsWith", jString1, STRING, "EndsWith");
- translateMethod(JSTRING, "substring", jInt1, STRING, "Substring");
- translateMethod(JSTRING, "intern", jEmpty, STRING, "Intern", sString1);
- translateMethod(JSTRING, "replace", jChar2, STRING, "Replace");
- translateMethod(JSTRING, "toCharArray", STRING, "ToCharArray");
-
-// translateMethod(defs.getModule("java.lang.Byte").moduleClass()
-// , "parseByte", jString1, BYTE, "Parse");
-// translateMethod(defs.getModule("java.lang.Short").moduleClass()
-// , "parseShort", jString1, SHORT, "Parse");
-// translateMethod(defs.getModule("java.lang.Integer").moduleClass()
-// , "parseInt", jString1, INT, "Parse");
-// translateMethod(defs.getModule("java.lang.Long").moduleClass()
-// , "parseLong", jString1, LONG, "Parse");
-// translateMethod(defs.getModule("java.lang.Float").moduleClass()
-// , "parseFloat", jString1, FLOAT, "Parse");
-// translateMethod(defs.getModule("java.lang.Double").moduleClass()
-// , "parseDouble", jString1, DOUBLE, "Parse");
-
- SYM_SUBSTRING_INT_INT = lookupMethod(JSTRING, "substring", jInt2);
- SUBSTRING_INT_INT =
- STRING.GetMethod("Substring", new Type[]{INT,INT});
- SYM_COMPARE_TO_IGNORE_CASE =
- lookupMethod(JSTRING, "compareToIgnoreCase", jString1);
- COMPARE_TO_IGNORE_CASE =
- STRING.GetMethod("Compare", new Type[]{STRING, STRING, BOOLEAN});
- initialized = true;
-
- SYMTAB_CONSTR = ti.SYMTAB_CONSTR;
- SYMTAB_DEFAULT_CONSTR = ti.SYMTAB_DEFAULT_CONSTR;
-
- scalac.symtab.Type argument = defs.array_TYPE(defs.STRING_TYPE());
- scalac.symtab.Type result = defs.void_TYPE();
- Symbol formal = Symbol.NONE.newTerm // !!! should be newVParam
- (Position.NOPOS, Modifiers.PARAM, Name.fromString("args"));
- formal.setInfo(argument);
- MAIN_METHOD_TYPE =
- scalac.symtab.Type.MethodType(new Symbol[] {formal}, result);
-
- specialAttrs.add(defs.SCALA_SERIALIZABLE_CONSTR);
- specialAttrs.add(defs.SCALA_TRANSIENT_CONSTR);
- specialAttrs.add(SYSTEM_SERIALIZABLE_CONSTR);
- specialAttrs.add(SYSTEM_NONSERIALIZED_CONSTR);
- specialAttrs.add(defs.SCALA_CLONEABLE_CONSTR);
- specialAttrs.add(defs.SCALA_VOLATILE_CONSTR);
- specialAttrs.add(defs.getClass("scala.SerialVersionUID")
- .primaryConstructor());
- specialAttrs.add(defs.getClass("scala._trait_")
- .primaryConstructor());
- } // init()
-
- /*
- * Looks up the method with the corresponding signature
- */
- private Symbol lookupMethod(Symbol clazz, String name,
- scalac.symtab.Type[] paramTypes)
- {
- Symbol[] methods = clazz.members().
- lookup(Name.fromString(name)).alternativeSymbols();
- search:
- for (int i = 0; i < methods.length; i++) {
- switch (methods[i].info()) {
- case MethodType(Symbol[] vparams, _):
- if (paramTypes.length != vparams.length)
- continue;
- for (int j = 0; j < vparams.length; j++) {
- if (!paramTypes[j].isSameAs(vparams[j].info()))
- continue search;
- }
- return methods[i];
- default:
- continue;
- }
- }
- return null;
- } // Symbol lookupMethod(...)
-
- /*
- * Format the signature of a method for better diagnostic printing.
- */
- private static String methodSignature(Symbol sym) {
- switch (sym.info()) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- StringBuffer s = new StringBuffer();
- s.append(result); s.append(' ');
- s.append(Debug.show(sym.owner())); s.append('.');
- s.append(sym.name.toString());s.append('(');
- for (int i = 0; i < vparams.length; i++) {
- if (i > 0) s.append(", ");
- //s.append(Debug.show(vparams[i].info()));
- s.append(vparams[i].info());
- }
- s.append(")");
- return s.toString();
- default:
- return "Symbol doesn't have a method type: " + Debug.show(sym);
- }
- }
-
- private static String methodSignature(Type[] params) {
- StringBuffer s = new StringBuffer();
- s.append('(');
- for (int i = 0; i < params.length; i++) {
- if (i > 0)
- s.append(", ");
- s.append(params[i]);
- }
- s.append(')');
- return s.toString();
- }
-
- /**
- * Create a mapping from method with symbol 'sym'
- * to the method newClazz.newName(params)
- */
- private void mapMethod(Symbol sym, Type newClazz, String name, Type[] params) {
- MethodInfo method = newClazz.GetMethod(name, params);
- assert method != null : "Cannot find translation for: "
- + methodSignature(sym) + "->" + newClazz
- + "::" + name + methodSignature(params);
- symbols2methods.put(sym, method);
- }
-
- /**
- * Create mapping between the specified two methods only
- */
- private void translateMethod(Symbol clazz, String name,
- scalac.symtab.Type[] paramTypes,
- Type newClazz, String newName, Type[] newParamTypes)
- {
- Symbol sym = lookupMethod(clazz, name, paramTypes);
- assert sym != null : "Cannot find method: " + name + " in class " +
- Debug.show(clazz) + "; scope = " + Debug.show(clazz.members());
- mapMethod(sym, newClazz, newName, newParamTypes);
- }
-
- /**
- * Lookup the method and create mapping for all overloaded alternatives
- * to the corresponding methods in 'newClazz'
- */
- private void translateMethod(Symbol clazz, String name,
- Type newClazz, String newName)
- {
- Symbol sym = clazz.lookup(Name.fromString(name));
- assert sym != null : "Cannot find method: " + name;
- translateMethod(sym, newClazz, newName);
- }
-
- /**
- *
- */
- private void translateMethod(Symbol clazz, String name,
- scalac.symtab.Type[] paramTypes,
- Type newClazz, String newName)
- {
- Type[] newParamTypes = new Type[paramTypes.length];
- for (int i = 0; i < paramTypes.length; i++)
- newParamTypes[i] = getType(paramTypes[i]);
- translateMethod(clazz, name, paramTypes,
- newClazz, newName, newParamTypes);
- }
-
- /*
- * Create a mapping for the two methods.
- */
- private void translateMethod(Symbol sym, Type newClazz, String newName) {
- switch (sym.info()) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- Type[] params = new Type[vparams.length];
- for (int i = 0; i < params.length; i++)
- params[i] = getType(vparams[i]);
- mapMethod(sym, newClazz, newName, params);
- break;
- case OverloadedType(Symbol[] alts, _):
- for (int i = 0; i < alts.length; i++)
- translateMethod(alts[i], newClazz, newName);
- return;
- default:
- throw Debug.abort(Debug.show(sym, sym.info()));
- }
- }
-
- //##########################################################################
- // tree treversal
-
- private static final Name MAIN_N = Name.fromString("main");
-
- private final Set types2create = new LinkedHashSet();
-
- private String assemName;
-
- private File outDir;
-
- private Symbol entryPoint;
-
- private boolean moreThanOneEntryPoint;
- public boolean moreThanOneEntryPoint() {
- return moreThanOneEntryPoint;
- }
-
- private CompilationUnit entryPointUnit;
-
- private int entryPointPos;
-
- /** - collects the symbols of all classes defined in the program
- * - collects all entry points
- * - gives the name of the new assembly
- */
- public void collectSymbols(CompilationUnit[] units) {
- types2create.clear();
- entryPoint = null;
- new CollectSymbols().traverse(units);
-
- // the assembly name supplied with the -o option (or null)
- assemName = global.args.assemname.value;
-
- if (assemName == null) {
- // assembly name not supplied with the -o option
- if (entryPoint != null) {
- // assume the name of the object defining the first entry point
- assemName = entryPoint.owner().name.toString();
- } else {
- // assume the name of the first source file
- assemName = entryPointUnit.source.getFile().getName();
- assert assemName.endsWith(".scala") : assemName;
- assemName = assemName.substring(0, assemName.length() - 6);
- }
- } else {
- File f = new File(assemName);
- outDir = f.getParentFile();
- assemName = f.getName();
- }
- if (outDir == null)
- outDir = new File(".");
- }
-
- /** Determines if the given symbol is an entry point:
- * - the name is "main"
- * - belongs to a top-level class
- * - the type is Array[String] => Unit
- */
- public boolean isEntryPoint(Symbol main) {
- return main.name == MAIN_N
- && main.owner().isModuleClass()
- && main.owner().owner().isPackageClass()
- && MAIN_METHOD_TYPE.isSameAs(main.info());
- }
-
- /** A traverser that collects the symbols of all classes defined
- * in the program and all entry points.
- */
- private final class CollectSymbols extends Traverser {
- private CompilationUnit currUnit;
- public void traverse(CompilationUnit unit) {
- currUnit = unit;
- if (entryPointUnit == null)
- entryPointUnit = unit;
- super.traverse(unit);
- }
- public void traverse(Tree tree) {
- switch (tree) {
- case ClassDef(_, _, _, _, _, Template impl):
- types2create.add(tree.symbol());
- traverse(impl);
- return;
- case DefDef(_, _, _, _, _, _):
- Symbol sym = tree.symbol();
- if (isEntryPoint(sym)) {
- if (entryPoint == null) {
- entryPoint = sym;
- entryPointUnit = currUnit;
- entryPointPos = tree.pos;
- } else
- moreThanOneEntryPoint = true;
- }
- return;
- case ValDef(_, _, _, _):
- return;
- default:
- super.traverse(tree);
- }
- }
- }
-
- //##########################################################################
-
- // the Assembly the program is compiled into.
- private AssemblyBuilder msilAssembly;
-
- // the main module of the assembly
- private ModuleBuilder msilModule;
-
- /** Create the output assembly
- */
- void initAssembly() {
- AssemblyName an = new AssemblyName();
- an.Name = assemName;
- String moduleName = assemName + (entryPoint == null ? ".dll" : ".exe");
- msilAssembly = AssemblyBuilder.DefineDynamicAssembly(an);
- msilModule = msilAssembly.DefineDynamicModule
- (moduleName, new File(outDir, moduleName).getAbsolutePath());
-
- for (Iterator classes = types2create.iterator(); classes.hasNext();) {
- Symbol clazz = (Symbol)classes.next();
- createType(clazz);
- }
- }
-
- /** Finilize the code generation. Called from GenMSILPhase
- * after processing all compilation units.
- */
- public void saveAssembly() {
- if (entryPoint != null) {
- MethodInfo mainMethod = (MethodInfo)getMethod(entryPoint);
- assert mainMethod != null : Debug.show(entryPoint);
- FieldInfo moduleField = getModuleField(entryPoint.owner());
- assert moduleField != null : Debug.show(entryPoint.owner());
- MethodBuilder main = msilModule.DefineGlobalMethod
- ("Main", MethodAttributes.Public | MethodAttributes.Static,
- VOID, new Type[] {STRING_ARRAY} );
- main.DefineParameter(0, 0, "args");
- msilAssembly.SetEntryPoint(main);
- ILGenerator code = main.GetILGenerator();
- if (global.args.debuginfo.value) {
- String fname = SourceRepresentation
- .escape(entryPointUnit.source.getFile().getPath());
- code.setPosition(Position.line(entryPointPos), fname);
- }
-
- code.Emit(OpCodes.Ldsfld, moduleField);
- code.Emit(OpCodes.Ldarg_0);
- code.Emit(OpCodes.Callvirt, mainMethod);
- code.Emit(OpCodes.Ret);
- }
- createTypes();
- File fassem = new File(outDir, assemName + ".il");
- String assemblyFilename = fassem.getPath();
- try {
- msilAssembly.Save(assemblyFilename);
- if (moreThanOneEntryPoint())
- global.warning("Setting " + Debug.show(entryPoint) +
- " as an entry point");
- } catch (IOException e) {
- global.error("Could not save " + assemblyFilename);
- }
- }
-
- /**
- * Finalizes ('bakes') the newly created types
- */
- private void createTypes() {
- Iterator iter = typeBuilders.iterator();
- while (iter.hasNext())
- ((TypeBuilder)iter.next()).CreateType();
- }
-
- //##########################################################################
- /**
- * Creates bidirectional mapping from symbols to types.
- */
- private Type map(Symbol sym, Type type) {
- symbols2types.put(sym, type);
- if (sym.isClass())
- types2symbols.put(type, sym);
- return type;
- }
-
- /**
- * Return the System.Type object with the given name.
- */
- private Type getType(String name) {
- return ti.getType(name);
- }
-
- /**
- * Return the System.Type object corresponding to the type of the symbol
- */
- public Type getType(Symbol sym) {
- if (sym == null) return null; // FIXME: assert sym != null ?
- if (sym == defs.ANY_CLASS || sym == defs.ANYREF_CLASS || sym == defs.OBJECT_CLASS)
- return OBJECT;
- if (sym == defs.STRING_CLASS)
- return STRING;
-
- Type type = (Type) symbols2types.get(sym);
- if (type != null) {
- if (sym.isExternal()) {
- assert !(type instanceof TypeBuilder)
- : Debug.show(sym) + " -> " + type.toString();
- return type;
- } else if (types2create.contains(sym) && type instanceof TypeBuilder)
- return type;
- } else if (types2create.contains(sym))
- type = createType(sym);
- if (type != null)
- return type;
-
- type = (Type)ti.getMember(sym);
- if (type != null)
- return map(sym, type);
-
- if (sym.isClass()) {
- final Symbol owner = sym.owner();
- if (owner.isClass()) {
- Type ownerType = getType(owner);
- assert ownerType != null : Debug.show(owner);
- type = ownerType.GetNestedType(sym.name.toString());
- } else {
- String name = global.primitives.getCLRClassName(sym);
- type = getType(sym.isModuleClass() && !sym.isJava()
- ? name + "$" : name);
- }
- } else {
- type = getType(sym.info());
- }
- if (type != null)
- return map(sym, type);
-
- throw Debug.abort("Type resolution failed for " + Debug.show(sym));
- }
-
- /** Retrieve the System.Type from the scala type.
- */
- public Type getType(scalac.symtab.Type type) {
- switch (type) {
- case ThisType(Symbol s):
- return getType(s);
- case TypeRef(_, Symbol s, _):
- return getType(s);
- case CompoundType(_, _):
- return getType(type.symbol());
- case UnboxedType(int kind):
- return getTypeFromKind(kind);
- case UnboxedArrayType(scalac.symtab.Type elemtp):
- return ti.mkArrayType(getType(elemtp));
- case NoType:
- return VOID;
- default:
- throw Debug.abort(Debug.show(type));
- }
- }
-
- /** Retrieves the primitive datatypes given their kind
- */
- private Type getTypeFromKind(int kind) {
- switch (kind) {
- case TypeTags.CHAR: return CHAR;
- case TypeTags.BYTE: return BYTE;
- case TypeTags.SHORT: return SHORT;
- case TypeTags.INT: return INT;
- case TypeTags.LONG: return LONG;
- case TypeTags.FLOAT: return FLOAT;
- case TypeTags.DOUBLE: return DOUBLE;
- case TypeTags.BOOLEAN: return BOOLEAN;
- case TypeTags.UNIT: return VOID;
- case TypeTags.STRING: return STRING;
- default:
- throw new ApplicationError("Unknown kind: " + kind);
- }
- }
-
- public Symbol getSymbol(Type type) {
- return (Symbol) types2symbols.get(type);
- }
-
- public Type createType(Symbol clazz) {
- try { return createType0(clazz); }
- catch (Error e) {
- throw Debug.abort(Debug.show(clazz), e);
- }
- }
-
- /**
- * Creates the TypeBuilder for a class.
- */
- public Type createType0(Symbol clazz) {
- assert types2create.contains(clazz) : Debug.show(clazz);
- Type type = (Type)symbols2types.get(clazz);
- if (type != null && type instanceof TypeBuilder)
- return type;
-
- TypeBuilder staticType = null;
- final Symbol owner = clazz.owner();
- final String staticTypeName = owner.isClass()
- ? clazz.nameString()
- : global.primitives.getCLRClassName(clazz);
- final String typeName =
- staticTypeName + (clazz.isModuleClass() ? "$" : "");
- final scalac.symtab.Type classType = clazz.info();
- switch (classType) {
- case CompoundType(scalac.symtab.Type[] baseTypes, _):
- Type superType = null;
- Type[] interfaces = null;
- int inum = baseTypes.length;
- if (clazz.isInterface()) {
- int baseIndex = 0;
- if (baseTypes[0].symbol() == defs.ANY_CLASS) {
- --inum;
- baseIndex = 1;
- }
- interfaces = new Type[inum];
- for (int i = 0; i < inum; i++) {
- assert baseTypes[i + baseIndex].symbol().isInterface();
- interfaces[i] = getType(baseTypes[i + baseIndex].symbol());
- }
- } else {
- boolean cloneable = isCloneable(clazz);
- superType = getType(baseTypes[0].symbol());
- assert inum > 0;
- interfaces = new Type[inum - 1 + (cloneable ? 1 : 0)];
- for (int i = 1; i < inum; i++)
- interfaces[i - 1] = getType(baseTypes[i].symbol());
- if (cloneable)
- interfaces[inum - 1] = ICLONEABLE;
- }
-
- type = (TypeBuilder) symbols2types.get(clazz);
- if (type != null)
- return type;
-
- if (owner.isPackageClass()) { // i.e. top level class
- type = msilModule.DefineType
- (typeName, translateTypeAttributes(clazz, false),
- superType, interfaces);
- if (clazz.isModuleClass()) {
- Symbol module = owner.members().lookup(clazz.name.toTermName());
- Symbol linkedClass = module.linkedClass();
-
- if (linkedClass == null || linkedClass.info().isError()) {
- staticType = msilModule.DefineType
- (staticTypeName,
- translateTypeAttributes(clazz, false),
- OBJECT, Type.EmptyTypes);
- }
- }
- } else {
- final Type outerType = (Type) getType(owner);
- // check if the type have not been created by
- // the (possible) creation of the outer type
- type = (TypeBuilder) symbols2types.get(clazz);
- if (type != null)
- return type;
-
- assert outerType instanceof TypeBuilder : Debug.show(clazz);
- type = ((TypeBuilder)outerType).DefineNestedType
- (typeName, translateTypeAttributes(clazz, true),
- superType, interfaces);
- }
- break;
-
- default:
- throw Debug.abort("Symbol does not have a CompoundType", clazz);
- }
- typeBuilders.add(type);
- map(clazz, type);
- if (clazz.isModuleClass() && staticType != null) {
- syms2staticTypes.put(clazz, staticType);
- }
- for (Scope.SymbolIterator syms = clazz.members().iterator();
- syms.hasNext(); )
- {
- Symbol member = syms.next();
- if (member.isMethod()) {
- MethodBase m = createMethod(member);
- if (staticType != null && m.IsPublic() && !m.IsConstructor()) {
- MethodBase sm = createMethod(staticType, member, true);
- syms2staticMethods.put(member, sm);
- }
- }
- else if (!member.isClass() && !member.isModule()
- && !member.isType())
- createField(member);
- }
-
- // adapted from Erasure; creates abstract method declarations
- // for the interface methods for which the class doesn't provide
- // implementation (requirement of the CLR)
- if (clazz.isClass() && !clazz.isInterface()) {
- Set ifaces = new HashSet(getInterfacesOf(clazz));
- Symbol svper = clazz.parents()[0].symbol();
- ifaces.removeAll(getInterfacesOf(svper));
- for (Iterator i = ifaces.iterator(); i.hasNext(); ) {
- Symbol iface = (Symbol)i.next();
- for (Scope.SymbolIterator members =
- iface.members().iterator();
- members.hasNext(); )
- {
- Symbol method = members.next();
- if (!method.isTerm() || !method.isDeferred()) continue;
- Symbol overriding =
- method.overridingSymbol(clazz.info(), true);
- if (overriding != method) continue;
- Symbol overridden = method
- .overriddenSymbol(clazz.parents()[0], clazz, true);
- if (overridden.isNone()) {
- Symbol newMethod = method.cloneSymbol(clazz);
- newMethod.flags = (newMethod.flags & ~Modifiers.JAVA)
- | Modifiers.SYNTHETIC | Modifiers.DEFERRED;
- createMethod(newMethod);
- }
- }
- }
- }
- setAttributes((TypeBuilder)type, global.getAttributes(clazz));
- return type;
- } // createType()
-
- private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap();
-
- /** Adapted from Erasure. Returns a set of the interfaces
- * implemented by the class.
- */
- private Set getInterfacesOf(Symbol clasz) {
- assert clasz.isClass(): Debug.show(clasz);
- Set set = (Set)interfaces.get(clasz);
- if (set == null) {
- set = new HashSet();
- interfaces.put(clasz, set);
- scalac.symtab.Type parents[] = clasz.parents();
- for (int i = 0; i < parents.length; i++)
- set.addAll(getInterfacesOf(parents[i].symbol()));
- if (clasz.isInterface()) set.add(clasz);
- }
- return set;
- }
-
- public boolean isCloneable(Symbol clazz) {
- return global.getAttrArguments(clazz, defs.SCALA_CLONEABLE_CONSTR)
- != null;
- }
-
- //##########################################################################
- // find/create methods
-
- public MethodBase getMethod(Symbol sym) {
- MethodBase method = null;
- try {
- method = getMethod0(sym);
- } catch (Throwable e) {
- printMapping(sym, symbols2methods);
- throw Debug.abort(Debug.show(sym), e);
- }
- return method;
- }
-
- private static String dumpSymbol(Symbol sym) {
- return Debug.show(sym) + " : " + Integer.toHexString(sym.flags);
- }
- private void printMapping(Symbol sym, Map map) {
- System.out.println("For symbol " + dumpSymbol(sym));
- for (Iterator entries = map.entrySet().iterator();
- entries.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)entries.next();
- Symbol sentry = (Symbol)entry.getKey();
- if (sentry.owner() == sym.owner()
- && sentry.name == sym.name)
- {
- System.out.println("Existing mapping "
- + dumpSymbol(sentry) + " => "
- + entry.getValue());
- }
- }
- System.out.println("Scope of owner: " + sym.owner().members());
- }
-
- /**
- * Returns the MethodBase object corresponding to the symbol.
- */
- public MethodBase getMethod0(Symbol sym) {
- MethodBase method = (MethodBase) symbols2methods.get(sym);
- if (method != null)
- return method;
- MemberInfo m = ti.getMember(sym);
- if (m != null && m instanceof MethodBase) {
- method = (MethodBase) m;
- } else {
- // force the creation of the declaring type
- Type owner = getType(sym.owner());
- assert owner != null : Debug.show(sym);
- method = (MethodBase) symbols2methods.get(sym);
- if (method != null)
- return method;
- switch (sym.info()) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- Type[] params = new Type[vparams.length];
- Type resType = getType(result);
- for (int i = 0; i < params.length; i++)
- params[i] = getType(vparams[i]);
- if (sym.isInitializer()) {
- // The owner of a constructor is the outer class
- // so get the result type of the constructor
- method = owner.GetConstructor(params);
- assert method != null : "cannot find " + owner
- + "::.ctor" + methodSignature(params);
- } else {
- method = owner instanceof TypeBuilder
- ? findMethod(sym.owner(), sym)
- : owner.GetMethod
- (getMethodName(sym.name, params), params, resType);
- }
- break;
- default:
- throw Debug.abort("Symbol doesn't have a method type", sym);
- }
- assert method != null
- : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym);
- }
- symbols2methods.put(sym, method);
-
- return method;
- }
-
- /**
- * Returns all MethodBase objects corresponding to the symbol.
- */
- private MethodBase[] getMethods(Symbol sym) {
- MethodBase method = (MethodBase) symbols2methods.get(sym);
- if (method != null)
- return new MethodBase[]{method};
- MemberInfo m = ti.getMember(sym);
- if (m != null && m instanceof MethodBase) {
- method = (MethodBase) m;
- } else {
- // force the creation of the declaring type
- Type owner = getType(sym.owner());
- assert owner != null : Debug.show(sym);
- method = (MethodBase) symbols2methods.get(sym);
- if (method != null)
- return new MethodBase[]{method};
- switch (sym.info()) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- Type[] params = new Type[vparams.length];
- Type resType = getType(result);
- for (int i = 0; i < params.length; i++)
- params[i] = getType(vparams[i]);
- if (sym.isInitializer()) {
- // The owner of a constructor is the outer class
- // so get the result type of the constructor
- method = owner.GetConstructor(params);
- assert method != null : "cannot find " + owner
- + "::.ctor" + methodSignature(params);
- } else {
- method = owner instanceof TypeBuilder
- ? findMethod(sym.owner(), sym)
- : owner.GetMethod
- (getMethodName(sym.name, params), params, resType);
- }
- break;
- case OverloadedType(Symbol[] alts, scalac.symtab.Type[] alttypes):
- MethodBase[] methods = new MethodBase[alts.length];
- for (int i = 0; i < alts.length; i++)
- methods[i] = getMethod(alts[i]);
- return methods;
-
- default:
- throw Debug.abort("Symbol doesn't have a method type", sym);
- }
- assert method != null
- : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym);
- }
- symbols2methods.put(sym, method);
- return new MethodBase[]{method};
- }
-
- /**
- * Returns the exactest apply method.
- * The exactest method is taken to be the first method that doesn't have
- * an 'object' return type and all 'object' parameter types.
- */
- public MethodBase getDelegateApplyMethod(Symbol sym) {
- MethodBase methods[] = getMethods(sym);
- if(methods.length > 1) {
- assert methods.length == 2;
- for (int i = 0; i < methods.length; i++) {
- if(((MethodInfo)methods[i]).ReturnType != OBJECT)
- return methods[i];
- ParameterInfo pi[] = methods[i].GetParameters();
- for (int j = 0; j < pi.length; j++) {
- if(pi[j].ParameterType != OBJECT)
- return methods[i];
- }
- }
- throw Debug.abort("Expected apply method not found", sym);
- } else {
- return methods[0];
- }
- }
-
- private String getMethodName(Name name, Type[] params) {
- if (name == Names.finalize && params.length == 0)
- return "Finalize";
- if (name == Names.toString && params.length == 0)
- return "ToString";
- if (name == Names.hashCode && params.length == 0)
- return "GetHashCode";
- if (name == Names.equals && params.length == 1 && params[0] == OBJECT)
- return "Equals";
- if (name == Names.clone && params.length == 0)
- return "Clone";
- return name.toString();
- }
-
- private MethodBase findMethod(Symbol owner, Symbol member) {
- Symbol[] ms = owner.lookup(member.name).alternativeSymbols();
- for (int i = 0; i < ms.length; i++)
- if (member.info().isSameAs(ms[i].info())) {
- MethodBase m = getMethod(ms[i]);
- if (m != null)
- return m;
- }
- throw Debug.abort("Couldn't find mapping for " + Debug.show(member));
- }
-
- private MethodBase createMethod(Symbol sym) {
- MethodBase method =
- createMethod((TypeBuilder)getType(sym.owner()), sym, false);
- symbols2methods.put(sym, method);
- setAttributes((ICustomAttributeSetter)method, global.getAttributes(sym));
- return method;
- }
-
-
- /**
- * Create the method corresponding to the symbol.
-
- * @param isStatic - forces the created method to be static
- */
- private MethodBase createMethod(TypeBuilder type, Symbol sym, boolean isStatic)
- {
- MethodBase method = null;
- switch (sym.info()) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- short attr = translateMethodAttributes(sym);
- if (isStatic)
- attr = (short)((attr & ~MethodAttributes.Virtual
- & ~MethodAttributes.Final)
- | MethodAttributes.Static);
- Phase bkpCurrent = global.currentPhase;
- global.currentPhase = backPhase;
- Name name = sym.name; String sname = name.toString();
- switch (sym.info()) {
- case PolyType(Symbol[] tparams, _):
- if (tparams.length == 0) {
- name = Name.fromString("get_" + name);
- }
- break;
- default:
- if (sname.endsWith("_$eq")) {
- name = Name.fromString("set_" + sname
- .substring(0, sname.length() - 4));
- }
- }
- global.currentPhase = bkpCurrent;
-
- return createMethod(type, name, sym.info(), attr);
- default:
- throw Debug.abort("Symbol doesn't have a method type: "
- + Debug.show(sym));
- }
- }
-
-
- /**
- * Helper method to createMethod(Symbol)
- */
- private MethodBase createMethod(TypeBuilder type, Name name,
- scalac.symtab.Type symType, short attr)
- {
- MethodBase method = null;
- switch (symType) {
- case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- Type[] params = new Type[vparams.length];
- for (int i = 0; i < params.length; i++)
- params[i] = getType(vparams[i]);
-
- if (name == Names.CONSTRUCTOR) {
- ConstructorBuilder constructor = type.DefineConstructor
- (attr, CallingConventions.Standard, params);
-
- for (int i = 0; i < vparams.length; i++)
- constructor.DefineParameter
- (i, ParameterAttributes.None, vparams[i].name.toString());
- return constructor;
- } else {
- final String sname = getMethodName(name, params);
- MethodBuilder methodBuilder = type.DefineMethod
- (sname, attr, getType(result), params);
-
- for (int i = 0; i < vparams.length; i++)
- methodBuilder.DefineParameter
- (i, 0/*ParameterAttributes.In*/, vparams[i].name.toString());
- return methodBuilder;
- }
- default:
- throw Debug.abort("Method type expected: " + Debug.show(symType));
- }
- }
-
- //##########################################################################
- // find/create fields
-
- /** Returns the FieldInfo object corresponing to the symbol
- */
- public FieldInfo getField(Symbol sym) {
- FieldInfo field = (FieldInfo) symbols2fields.get(sym);
- if (field != null) return field;
- MemberInfo m = ti.getMember(sym);
- if (m != null && m instanceof FieldInfo) {
- field = (FieldInfo)m;
- } else {
- Type owner = getType(sym.owner());
- field = owner.GetField(sym.name.toString());
- if (field == null) {
- System.out.println("Fields of class " + owner);
- int bindingFlags = BindingFlags.DeclaredOnly
- | BindingFlags.Instance | BindingFlags.Static
- | BindingFlags.Public | BindingFlags.NonPublic;
- FieldInfo[] fields = owner.GetFields(bindingFlags);
- for (int i = 0; i < fields.length; i ++)
- System.out.println("\t" + fields[i]);
- }
- }
- assert field != null : "Cannot find field: " + Debug.show(sym);
- symbols2fields.put(sym, field);
- return field;
- }
-
- /*
- *
- */
- public FieldInfo createField(Symbol sym) {
- TypeBuilder owner = (TypeBuilder) getType(sym.owner());
- FieldInfo field = (FieldInfo) symbols2fields.get(sym);
- if (field != null) {
- assert field instanceof FieldBuilder;
- return field;
- }
- field = owner.DefineField(sym.name.toString(), getType(sym.type()),
- translateFieldAttributes(sym));
- Object o = symbols2fields.put(sym, field);
- assert o == null : "Cannot re-define field: " + Debug.show(sym);
- return field;
- }
-
- /*
- *
- */
- private FieldInfo getModuleField(Type type) {
- Symbol sym = (Symbol) types2symbols.get(type);
- assert sym != null;
- return getModuleField(sym);
- }
-
- /**
- *
- */
- public MethodBuilder getStaticObjectMethod(Symbol sym) {
- assert sym.owner().isModuleClass() : Debug.show(sym);
- MethodBuilder method = (MethodBuilder)syms2staticMethods.get(sym);
- assert sym != null : Debug.show(sym);
- return method;
- }
-
- private Map syms2staticTypes = new HashMap();
-
- public TypeBuilder getStaticType(Symbol moduleClass) {
- getType(moduleClass); // force the creation of the Type
- TypeBuilder staticType = (TypeBuilder)syms2staticTypes.get(moduleClass);
-// assert staticType != null : Debug.show(moduleClass)
-// + " : " + syms2staticTypes;
- return staticType;
- }
-
- /*
- *
- */
- private Symbol getTypeSymbol(scalac.symtab.Type type) {
- switch (type) {
- case TypeRef(_, Symbol s, _):
- return s;
- default:
- throw new ApplicationError("Cannot get symbol for: "
- + Debug.show(type));
- }
- }
-
- /**
- * @return the field descriptor of the object instance
- */
- public FieldInfo getModuleField(Symbol sym) {
- assert sym.isModule() || sym.isModuleClass() : Debug.show(sym);
- FieldInfo moduleField = (FieldInfo) symbols2moduleFields.get(sym);
- if (moduleField == null) {
- Symbol s = getTypeSymbol(sym.type());
- if (sym != s) {
- moduleField = getModuleField(s);
- } else {
- Type type = getType(sym);
- if (type instanceof TypeBuilder) {
- TypeBuilder module = (TypeBuilder) type;
- moduleField = module.DefineField
- (MODULE_S,
- module,
- (short)(FieldAttributes.Public
- | FieldAttributes.InitOnly
- | FieldAttributes.Static));
- } else {
- moduleField = type.GetField(MODULE_S);
- assert moduleField != null;
- }
- }
- symbols2moduleFields.put(sym, moduleField);
- }
- assert moduleField != null : Debug.show(sym);
- return moduleField;
- }
-
- //##########################################################################
- // translate Scala modifiers into attributes
-
- /** Translates Scala modifiers into TypeAttributes
- */
- private int translateTypeAttributes(Symbol clazz, boolean nested) {
- int mods = clazz.flags;
- int attr = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass;
-
- if (Modifiers.Helper.isInterface(mods))
- attr |= TypeAttributes.Interface;
- else
- attr |= TypeAttributes.Class;
-
- if (Modifiers.Helper.isAbstract(mods))
- attr |= TypeAttributes.Abstract;
- if (Modifiers.Helper.isFinal(mods))
- attr |= TypeAttributes.Sealed;
-
- if (nested) {
- if (Modifiers.Helper.isPrivate(mods))
- //attr |= TypeAttributes.NestedPrivate;
- // Inner classes end up in the interface of a Scala class
- // and are not accessible from the implementation class.
- // Giving them assembly visibility fixes the problem.
- attr |= TypeAttributes.NestedAssembly;
- else if (Modifiers.Helper.isProtected(mods))
- attr |= TypeAttributes.NestedFamORAssem;
- else
- attr |= TypeAttributes.NestedPublic;
- } else {
- if (Modifiers.Helper.isPrivate(mods))
- attr |= TypeAttributes.NotPublic;
- else
- attr |= TypeAttributes.Public;
- }
- boolean serializable =
- global.getAttrArguments(clazz, defs.SCALA_SERIALIZABLE_CONSTR) != null
- || global.getAttrArguments(clazz, SYSTEM_SERIALIZABLE_CONSTR) != null;
- if (serializable)
- attr |= TypeAttributes.Serializable;
- return attr;
- }
-
- /*
- * Translates Scala modifiers into FieldAttributes
- */
- private short translateFieldAttributes(Symbol field) {
- int mods = field.flags;
- int attr = 0;
-
- if (Modifiers.Helper.isFinal(mods))
- attr |= FieldAttributes.InitOnly;
- if (Modifiers.Helper.isPrivate(mods))
- attr |= FieldAttributes.Private;
- else if (Modifiers.Helper.isProtected(mods))
- attr |= FieldAttributes.FamORAssem;
- else
- attr |= FieldAttributes.Public;
-
- if (field.owner().isJava() && field.owner().isModuleClass())
- attr |= FieldAttributes.Static;
- boolean tranzient =
- global.getAttrArguments(field, defs.SCALA_TRANSIENT_CONSTR) != null
- || global.getAttrArguments(field, SYSTEM_NONSERIALIZED_CONSTR) != null;
- if (tranzient)
- attr |= FieldAttributes.NotSerialized;
-
- return (short)attr;
- }
-
- /*
- * Translates Scala modifiers into MethodAttributes
- */
- private static short translateMethodAttributes(Symbol method)
- {
- int mods = method.flags;
- if (method.owner().isInterface())
- mods |= Modifiers.DEFERRED;
- int attr = MethodAttributes.HideBySig;
- if (!method.isInitializer()) {
- attr |= MethodAttributes.Virtual;
- if (Modifiers.Helper.isFinal(mods))
- attr |= MethodAttributes.Final;
- if (Modifiers.Helper.isAbstract(mods))
- attr |= MethodAttributes.Abstract;
- }
-
- if (Modifiers.Helper.isPrivate(mods))
- attr |= MethodAttributes.Private;
- else if (Modifiers.Helper.isProtected(mods))
- attr |= MethodAttributes.Family;
- else
- attr |= MethodAttributes.Public;
-
- return (short)attr;
- }
-
- //##########################################################################
-
- byte[] attributeArgs(AConstant[] args) {
- ByteBuffer buf = ByteBuffer.allocate(1024);
- buf.order(ByteOrder.LITTLE_ENDIAN);
- buf.putShort((short)1); // write signature
- for (int i = 0; i < args.length; i++) {
- switch (args[i]) {
- case BOOLEAN(boolean value): buf.put((byte)(value ? 1 : 0)); break;
- case BYTE(byte value): buf.put(value); break;
- case SHORT(short value): buf.putShort(value); break;
- case CHAR(char value): buf.putChar(value); break;
- case INT(int value): buf.putInt(value); break;
- case LONG(long value): buf.putLong(value); break;
- case FLOAT(float value): buf.putFloat(value); break;
- case DOUBLE(double value): buf.putDouble(value); break;
- case STRING(String value):
- int length = value.length();
- if (length < 128)
- buf.put((byte)length);
- else if (length < 2<<14) {
- buf.put((byte)((length >> 8) | 0x80));
- buf.put((byte)(length & 0xff));
- } else if (length < 2<<29) {
- buf.put((byte)((length >> 24) | 0xc0));
- buf.put((byte)((length >> 16) & 0xff));
- buf.put((byte)((length >> 8) & 0xff));
- buf.put((byte)((length ) & 0xff));
- } else
- throw Debug.abort("String too long: " + length);
- try {
- buf.put(value.getBytes("UTF-8"));
- } catch (java.io.UnsupportedEncodingException e) {
- throw Debug.abort(e);
- }
- break;
- default:
- throw Debug.abort("Cannot handle attribute argument " + args[i]);
- }
- }
- buf.putShort((short)0); // count of named parameters == 0
- int length = buf.position();
- byte[] arr = new byte[length];
- System.arraycopy(buf.array(), 0, arr, 0, length);
- return arr;
- }
-
- private void setAttributes(ICustomAttributeSetter icas, AttributeInfo attr) {
- for (; attr != null; attr = attr.next) {
- if (!specialAttrs.contains(attr.constr)) {
- ConstructorInfo constr =
- (ConstructorInfo)getMethod(attr.constr);
- byte[] args = attributeArgs(attr.args);
- icas.SetCustomAttribute(constr, args);
- }
- }
- }
-
-} // class TypeCreator