summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-06-21 07:53:15 +0000
committermihaylov <mihaylov@epfl.ch>2004-06-21 07:53:15 +0000
commit4761c438954f0f1bdbf39023585c14853e3fa205 (patch)
treec2e99fbf4ebc1057f0aa0d58cbde203dffc0358d /sources/scalac
parent53e1782c7186d0a6448b7f1d7e884eb24528d52d (diff)
downloadscala-4761c438954f0f1bdbf39023585c14853e3fa205.tar.gz
scala-4761c438954f0f1bdbf39023585c14853e3fa205.tar.bz2
scala-4761c438954f0f1bdbf39023585c14853e3fa205.zip
- Handle index properties by assigning the name...
- Handle index properties by assigning the name "apply" to the getter, and "update" to the setter. Then they can be used as a function application/assignment to.
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/symtab/classfile/CLRClassParser.java330
1 files changed, 206 insertions, 124 deletions
diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java
index c7f3e85d95..4863735459 100644
--- a/sources/scalac/symtab/classfile/CLRClassParser.java
+++ b/sources/scalac/symtab/classfile/CLRClassParser.java
@@ -22,16 +22,14 @@ import scalac.util.Debug;
import scala.tools.util.Position;
import ch.epfl.lamp.compiler.msil.*;
-public class CLRClassParser extends SymbolLoader {
-
- protected JavaTypeFactory make;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Iterator;
- protected final CLRPackageParser importer;
+public class CLRClassParser extends SymbolLoader {
- public CLRClassParser(Global global, CLRPackageParser importer) {
- super(global);
- this.importer = importer;
- }
+ //##########################################################################
private static Name[] ENUM_CMP_NAMES = new Name[]
{ Names.EQ, Names.NE, Names.LT, Names.LE, Names.GT, Names.GE };
@@ -39,51 +37,63 @@ public class CLRClassParser extends SymbolLoader {
private static Name[] ENUM_BIT_LOG_NAMES = new Name[]
{ Names.OR, Names.AND, Names.XOR };
- protected String doComplete(Symbol root) {
- assert root.isClassType(): Debug.show(root);
- try { return doComplete0(root); }
- catch (Throwable e) {
- // !!! doComplete may throw an IOException which is then
- // caught by SymbolLoader and reported to the user as
- // normal error message
- System.err.println("\nWhile processing " + Debug.show(root));
- e.printStackTrace();
- System.exit(1);
- return null; // !!!
- }
+ private static JavaTypeFactory make;
+
+ private static final CLRPackageParser clrParser =
+ CLRPackageParser.instance();
+
+ private final Type type;
+
+ public CLRClassParser(Global global, Type type) {
+ super(global);
+ this.type = type;
}
- protected String doComplete0(Symbol clazz) {
+// protected String doComplete(Symbol root) {
+// assert root.isClassType(): Debug.show(root);
+// try { return doComplete0(root); }
+// catch (Throwable e) {
+// // !!! doComplete may throw an IOException which is then
+// // caught by SymbolLoader and reported to the user as
+// // normal error message
+// System.err.println("\nWhile processing " + Debug.show(root));
+// e.printStackTrace();
+// System.exit(1);
+// return null; // !!!
+// }
+// }
+
+ private Symbol clazz;
+ private Scope members;
+ private Symbol staticsClass;
+ private Scope statics;
+ scalac.symtab.Type clazzType;
+
+ protected String doComplete(Symbol root) {
+ clazz = root;
clazz.owner().initialize(); //???
if (make == null)
make = new JavaTypeCreator(global.definitions);
- Type type = (Type)importer.getMember(clazz);
- if (type == null)
- type = Type.GetType(global.primitives.getCLRClassName(clazz));
- assert type != null : Debug.show(clazz);
-
clazz.flags = translateAttributes(type);
Type[] ifaces = type.getInterfaces();
scalac.symtab.Type[] baseTypes = new scalac.symtab.Type[ifaces.length+1];
- baseTypes[0] = type.BaseType == null ? global.definitions.ANYREF_TYPE()
+ baseTypes[0] = type.BaseType == null ? make.anyType()
: getCLRType(type.BaseType);
for (int i = 0; i < ifaces.length; i++)
baseTypes[i + 1] = getCLRType(ifaces[i]);
- Scope members = new Scope();
- Scope statics = new Scope();
- scalac.symtab.Type classInfo =
- scalac.symtab.Type.compoundType(baseTypes, members, clazz);
- clazz.setInfo(classInfo);
+ members = new Scope();
+ statics = new Scope();
+ clazz.setInfo(scalac.symtab.Type.compoundType(baseTypes, members, clazz));
Symbol staticsModule = clazz.linkedModule();
- Symbol staticsClass = staticsModule.moduleClass();
+ staticsClass = staticsModule.moduleClass();
assert staticsClass.isModuleClass(): Debug.show(staticsClass);
scalac.symtab.Type staticsInfo = scalac.symtab.Type.compoundType
(scalac.symtab.Type.EMPTY_ARRAY, statics, staticsClass);
staticsClass.setInfo(staticsInfo);
staticsModule.setInfo(make.classType(staticsClass));
- scalac.symtab.Type ctype = make.classType(clazz);
+ clazzType = make.classType(clazz);
// import nested types
Type[] nestedTypes = type.getNestedTypes();
@@ -99,8 +109,10 @@ public class CLRClassParser extends SymbolLoader {
Name aliasname = Name.fromString(ntype.Name).toTypeName();
// put the class at the level of its outermost class
// the owner of a class is always its most specific package
- Symbol nclazz = clazz.owner().newLoadedClass(JAVA, classname, this, null);
- importer.map(nclazz, ntype);
+ CLRClassParser loader = new CLRClassParser(global, ntype);
+ Symbol nclazz =
+ clazz.owner().newLoadedClass(JAVA, classname, loader, null);
+ clrParser.map(nclazz, ntype);
// create an alias in the module of the outer class
Symbol alias = staticsClass.newTypeAlias(Position.NOPOS,
translateAttributes(ntype), aliasname, make.classType(nclazz));
@@ -122,79 +134,80 @@ public class CLRClassParser extends SymbolLoader {
Symbol field = owner.newField(Position.NOPOS, mods, name);
field.setInfo(fieldType);
(fields[i].IsStatic() ? statics : members).enterOrOverload(field);
- importer.map(field, fields[i]);
+ clrParser.map(field, fields[i]);
}
+ Set methodsSet = new HashSet(Arrays.asList(type.getMethods()));
+
PropertyInfo[] props = type.getProperties();
for (int i = 0; i < props.length; i++) {
+ scalac.symtab.Type proptype = getCLSType(props[i].PropertyType);
+ if (proptype == null)
+ continue;
+
MethodInfo getter = props[i].GetGetMethod(true);
MethodInfo setter = props[i].GetSetMethod(true);
- if (getter == null || getter.GetParameters().length > 0)
+ if (getter == null)
continue;
assert props[i].PropertyType == getter.ReturnType;
- scalac.symtab.Type proptype = getCLSType(props[i].PropertyType);
- if (proptype == null)
- continue;
- Name n = Name.fromString(props[i].Name);
- scalac.symtab.Type mtype =
- scalac.symtab.Type.PolyType(Symbol.EMPTY_ARRAY, proptype);
- int mods = translateAttributes(getter);
+ Name n;
+ Symbol method;
+ scalac.symtab.Type mtype;
+
+ ParameterInfo[] gparams = getter.GetParameters();
+ if (gparams.length == 0) {
+ n = Name.fromString(props[i].Name);
+ mtype =
+ scalac.symtab.Type.PolyType(Symbol.EMPTY_ARRAY, proptype);
+ } else {
+ n = Names.apply;
+ mtype = methodType(getter, getter.ReturnType);
+ }
Symbol owner = getter.IsStatic() ? staticsClass : clazz;
- Symbol method = owner.newMethod(Position.NOPOS, mods, n);
+ int mods = translateAttributes(getter);
+ method = owner.newMethod(Position.NOPOS, mods, n);
setParamOwners(mtype, method);
method.setInfo(mtype);
(getter.IsStatic() ? statics : members).enterOrOverload(method);
- importer.map(method, getter);
+ clrParser.map(method, getter);
+ assert methodsSet.contains(getter) : "" + getter;
+ methodsSet.remove(getter);
if (setter == null)
continue;
+ ParameterInfo[] sparams = setter.GetParameters();
assert getter.IsStatic() == setter.IsStatic();
- assert setter.ReturnType == importer.VOID;
- mtype = methodType(setter, getCLSType(importer.VOID));
- if (mtype == null)
- continue;
- n = Name.fromString(n.toString() + Names._EQ);
+ assert setter.ReturnType == clrParser.VOID;
+ assert sparams.length == gparams.length + 1 : "" + getter + "; " + setter;
+
+ if (gparams.length == 0)
+ n = Name.fromString(n.toString() + Names._EQ);
+ else n = Names.update;
+
mods = translateAttributes(setter);
method = owner.newMethod(Position.NOPOS, mods, n);
+ mtype = methodType(setter, global.definitions.UNIT_TYPE());
setParamOwners(mtype, method);
method.setInfo(mtype);
(setter.IsStatic() ? statics : members).enterOrOverload(method);
- importer.map(method, setter);
+ clrParser.map(method, setter);
+ assert methodsSet.contains(setter) : "" + setter;
+ methodsSet.remove(setter);
}
- MethodInfo[] methods = type.getMethods();
- for (int i = 0; i < methods.length; i++) {
- if ((importer.getSymbol(methods[i]) != null)
- || methods[i].IsPrivate()
- || methods[i].IsAssembly()
- || methods[i].IsFamilyAndAssembly())
- continue;
- scalac.symtab.Type rettype = getCLSType(methods[i].ReturnType);
- if (rettype == null)
+ for (Iterator i = methodsSet.iterator(); i.hasNext(); ) {
+ MethodInfo method = (MethodInfo)i.next();
+ if ((clrParser.getSymbol(method) != null) || method.IsPrivate()
+ || method.IsAssembly() || method.IsFamilyAndAssembly())
continue;
- scalac.symtab.Type mtype = methodType(methods[i], rettype);
- if (mtype == null)
- continue;
- String name = methods[i].Name;
- Name n;
- if (name.equals("GetHashCode")) n = Names.hashCode;
- else if (name.equals("Equals")) n = Names.equals;
- else if (name.equals("ToString")) n = Names.toString;
- else n = Name.fromString(name);
- int mods = translateAttributes(methods[i]);
- Symbol owner = methods[i].IsStatic() ? staticsClass : clazz;
- Symbol method = owner.newMethod(Position.NOPOS, mods, n);
- setParamOwners(mtype, method);
- method.setInfo(mtype);
- (methods[i].IsStatic() ? statics : members).enterOrOverload(method);
- importer.map(method, methods[i]);
+ createMethod(method);
}
// for enumerations introduce comparison and bitwise logical operations;
// the backend should recognize and replace them with comparison or
// bitwise logical operations on the primitive underlying type
if (type.IsEnum()) {
- scalac.symtab.Type[] argTypes = new scalac.symtab.Type[] {ctype};
+ scalac.symtab.Type[] argTypes = new scalac.symtab.Type[] {clazzType};
int mods = Modifiers.JAVA | Modifiers.FINAL;
for (int i = 0; i < ENUM_CMP_NAMES.length; i++) {
scalac.symtab.Type enumCmpType =
@@ -209,7 +222,7 @@ public class CLRClassParser extends SymbolLoader {
}
for (int i = 0; i < ENUM_BIT_LOG_NAMES.length; i++) {
scalac.symtab.Type enumBitLogType = make.methodType
- (argTypes, ctype, scalac.symtab.Type.EMPTY_ARRAY);
+ (argTypes, clazzType, scalac.symtab.Type.EMPTY_ARRAY);
Symbol enumBitLog = clazz.newMethod
(Position.NOPOS, mods, ENUM_BIT_LOG_NAMES[i]);
setParamOwners(enumBitLogType, enumBitLog);
@@ -223,26 +236,13 @@ public class CLRClassParser extends SymbolLoader {
if (constrs[i].IsStatic() || constrs[i].IsPrivate()
|| constrs[i].IsAssembly() || constrs[i].IsFamilyAndAssembly())
continue;
- scalac.symtab.Type mtype = methodType(constrs[i], ctype);
- if (mtype == null)
- continue;
- Symbol constr = clazz.primaryConstructor();
- int mods = translateAttributes(constrs[i]);
- if (constr.isInitialized()) {
- clazz.addConstructor(
- constr = clazz.newConstructor(Position.NOPOS, mods));
- } else {
- constr.flags = mods;
- }
- setParamOwners(mtype, constr);
- constr.setInfo(mtype);
- importer.map(constr, constrs[i]);
+ createConstructor(constrs[i]);
}
Symbol constr = clazz.primaryConstructor();
if (!constr.isInitialized()) {
constr.setInfo(scalac.symtab.Type.MethodType
- (Symbol.EMPTY_ARRAY, ctype));
+ (Symbol.EMPTY_ARRAY, clazzType));
if ((clazz.flags & Modifiers.INTERFACE) == 0)
constr.flags |= Modifiers.PRIVATE;
}
@@ -250,20 +250,100 @@ public class CLRClassParser extends SymbolLoader {
return type + " from assembly " + type.Assembly;
}
- /** Return a method type for */
- protected scalac.symtab.Type methodType(MethodBase method,
- scalac.symtab.Type rettype) {
+
+ private void createConstructor(ConstructorInfo constructor) {
+ scalac.symtab.Type mtype = methodType(constructor, clazzType);
+ if (mtype == null)
+ return;
+ Symbol constr = clazz.primaryConstructor();
+ int mods = translateAttributes(constructor);
+ if (constr.isInitialized()) {
+ constr = clazz.newConstructor(Position.NOPOS, mods);
+ clazz.addConstructor(constr);
+ } else {
+ constr.flags = mods;
+ }
+ setParamOwners(mtype, constr);
+ constr.setInfo(mtype);
+ clrParser.map(constr, constructor);
+ }
+
+ private void createMethod(MethodInfo method) {
+ scalac.symtab.Type mtype =
+ methodType(method, method.ReturnType);
+ if (mtype == null)
+ return;
+ int mods = translateAttributes(method);
+ Symbol owner = method.IsStatic() ? staticsClass : clazz;
+ Symbol methodSym =
+ owner.newMethod(Position.NOPOS, mods, getName(method.Name));
+ setParamOwners(mtype, methodSym);
+ methodSym.setInfo(mtype);
+ (method.IsStatic() ? statics : members).enterOrOverload(methodSym);
+ clrParser.map(methodSym, method);
+ }
+
+ private Name getName(String name) {
+ if (name.equals("GetHashCode")) return Names.hashCode;
+ else if (name.equals("Equals")) return Names.equals;
+ else if (name.equals("ToString")) return Names.toString;
+ else if (name.equals("Finalize")) return Names.finalize;
+ return Name.fromString(name);
+ }
+
+ //##########################################################################
+
+// private static class Method {
+// public final String name;
+// public final Type[] argTypes;
+// public final Type retType;
+// }
+
+ private String initializeJavaLangObject(Symbol sym) {
+ MethodInfo[] methods = type.getMethods();
+ return "java.lang.Object from internal data";
+ }
+
+ private String initializeJavaLangString(Symbol sym) {
+ return "java.lang.String from internal data";
+ }
+
+ //##########################################################################
+
+ private Type[] getParamTypes(MethodBase method) {
ParameterInfo[] params = method.GetParameters();
- scalac.symtab.Type[] ptypes = new scalac.symtab.Type[params.length];
- for (int j = 0; j < params.length; j++) {
- ptypes[j] = getCLSType(params[j].ParameterType);
- if (ptypes[j] == null)
+ Type[] paramTypes = new Type[params.length];
+ for (int i = 0; i < params.length; i++)
+ paramTypes[i] = params[i].ParameterType;
+ return paramTypes;
+ }
+
+ private scalac.symtab.Type methodType(MethodBase method, Type rettype) {
+ scalac.symtab.Type rtype = getCLSType(rettype);
+ return rtype == null ? null : methodType(method, rtype);
+ }
+
+ /** Return a method type for the given method. */
+ private scalac.symtab.Type methodType(MethodBase method,
+ scalac.symtab.Type rettype)
+ {
+ return methodType(getParamTypes(method), rettype);
+ }
+
+ /** Return a method type for the provided argument types and return type. */
+ private scalac.symtab.Type methodType(Type[] argtypes,
+ scalac.symtab.Type rettype)
+ {
+ scalac.symtab.Type[] ptypes = new scalac.symtab.Type[argtypes.length];
+ for (int i = 0; i < argtypes.length; i++) {
+ ptypes[i] = getCLSType(argtypes[i]);
+ if (ptypes[i] == null)
return null;
}
return make.methodType(ptypes, rettype, scalac.symtab.Type.EMPTY_ARRAY);
}
- protected void setParamOwners(scalac.symtab.Type type, Symbol owner) {
+ private void setParamOwners(scalac.symtab.Type type, Symbol owner) {
switch (type) {
case PolyType(Symbol[] params, scalac.symtab.Type restype):
for (int i = 0; i < params.length; i++) params[i].setOwner(owner);
@@ -276,7 +356,9 @@ public class CLRClassParser extends SymbolLoader {
}
}
- protected scalac.symtab.Type getClassType(Type type) {
+ //##########################################################################
+
+ private scalac.symtab.Type getClassType(Type type) {
assert type != null;
scalac.symtab.Type res =
make.classType(type.FullName.replace('+', '.'));
@@ -285,43 +367,43 @@ public class CLRClassParser extends SymbolLoader {
return res;
}
- protected scalac.symtab.Type getCLSType(Type type) {
- if (type == importer.BYTE || type == importer.USHORT
- || type == importer.UINT || type == importer.ULONG
+ private scalac.symtab.Type getCLSType(Type type) {
+ if (type == clrParser.BYTE || type == clrParser.USHORT
+ || type == clrParser.UINT || type == clrParser.ULONG
|| type.IsPointer()
|| (type.IsArray() && getCLSType(type.GetElementType()) == null))
return null;
- //Symbol s = importer.getSymbol(type);
+ //Symbol s = clrParser.getSymbol(type);
//scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type);
return getCLRType(type);
}
- protected scalac.symtab.Type getCLRType(Type type) {
- if (type == importer.OBJECT)
+ private scalac.symtab.Type getCLRType(Type type) {
+ if (type == clrParser.OBJECT)
return make.objectType();
- if (type == importer.STRING)
+ if (type == clrParser.STRING)
return make.stringType();
- if (type == importer.VOID)
+ if (type == clrParser.VOID)
return make.voidType();
- if (type == importer.BOOLEAN)
+ if (type == clrParser.BOOLEAN)
return make.booleanType();
- if (type == importer.CHAR)
+ if (type == clrParser.CHAR)
return make.charType();
- if (type == importer.BYTE || type == importer.UBYTE)
+ if (type == clrParser.BYTE || type == clrParser.UBYTE)
return make.byteType();
- if (type == importer.SHORT || type == importer.USHORT)
+ if (type == clrParser.SHORT || type == clrParser.USHORT)
return make.shortType();
- if (type == importer.INT || type == importer.UINT)
+ if (type == clrParser.INT || type == clrParser.UINT)
return make.intType();
- if (type == importer.LONG || type == importer.ULONG)
+ if (type == clrParser.LONG || type == clrParser.ULONG)
return make.longType();
- if (type == importer.FLOAT)
+ if (type == clrParser.FLOAT)
return make.floatType();
- if (type == importer.DOUBLE)
+ if (type == clrParser.DOUBLE)
return make.doubleType();
if (type.IsArray())
return make.arrayType(getCLRType(type.GetElementType()));
- Symbol s = importer.getSymbol(type);
+ Symbol s = clrParser.getSymbol(type);
return s != null ? make.classType(s) : getClassType(type);
}
@@ -347,7 +429,7 @@ public class CLRClassParser extends SymbolLoader {
throw Debug.abort("illegal value", Debug.show(value, base));
}
- protected static int translateAttributes(Type type) {
+ private static int translateAttributes(Type type) {
int mods = Modifiers.JAVA;
if (type.IsNotPublic() || type.IsNestedPrivate()
|| type.IsNestedAssembly() || type.IsNestedFamANDAssem())
@@ -364,7 +446,7 @@ public class CLRClassParser extends SymbolLoader {
return mods;
}
- protected static int translateAttributes(FieldInfo field) {
+ private static int translateAttributes(FieldInfo field) {
int mods = Modifiers.JAVA;
if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly())
mods |= Modifiers.PRIVATE;
@@ -378,7 +460,7 @@ public class CLRClassParser extends SymbolLoader {
return mods;
}
- protected static int translateAttributes(MethodBase method) {
+ private static int translateAttributes(MethodBase method) {
int mods = Modifiers.JAVA;
if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly())
mods |= Modifiers.PRIVATE;