Merged the dotnet-scala branch
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@9896 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
904b292757
commit
d7a62c5089
18
build.xml
18
build.xml
|
@ -39,6 +39,7 @@ PROPERTIES
|
|||
<property name="lib.starr.jar" value="${lib.dir}/scala-library.jar"/>
|
||||
<property name="comp.starr.jar" value="${lib.dir}/scala-compiler.jar"/>
|
||||
<property name="fjbg.jar" value="${lib.dir}/fjbg.jar"/>
|
||||
<property name="msil.jar" value="${lib.dir}/msil.jar"/>
|
||||
<property name="ant.jar" value="${ant.home}/lib/ant.jar"/>
|
||||
<property name="ant-contrib.jar" value="${lib.dir}/ant-contrib.jar"/>
|
||||
<!-- Sets location of build folders -->
|
||||
|
@ -77,6 +78,7 @@ INITIALISATION
|
|||
<available file="${lib.starr.jar}"/>
|
||||
<available file="${comp.starr.jar}"/>
|
||||
<available file="${fjbg.jar}"/>
|
||||
<available file="${msil.jar}"/>
|
||||
<available file="${ant-contrib.jar}"/>
|
||||
</and></not></condition>
|
||||
</fail>
|
||||
|
@ -206,6 +208,7 @@ SETUP
|
|||
<pathelement location="${locker.dir}/lib/library"/>
|
||||
<pathelement location="${locker.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
</path>
|
||||
<taskdef
|
||||
name="locker"
|
||||
|
@ -218,6 +221,7 @@ SETUP
|
|||
<pathelement location="${quick.dir}/lib/library"/>
|
||||
<pathelement location="${quick.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
</path>
|
||||
<taskdef
|
||||
name="quick" classname="scala.tools.ant.Scalac"
|
||||
|
@ -268,6 +272,15 @@ BUILD SUPPORT MACROS
|
|||
resource="${fjbg.jar}" overwrite="yes" failonerror="no"/>
|
||||
</else></if>
|
||||
</then></if>
|
||||
<if><not><available file="@{build.dir}/lib/msil.jar"/></not><then>
|
||||
<if><isset property="os.win"/><then>
|
||||
<copy file="${msil.jar}" tofile="@{build.dir}/lib/msil.jar"/>
|
||||
</then><else>
|
||||
<symlink
|
||||
link="@{build.dir}/lib/msil.jar"
|
||||
resource="${msil.jar}" overwrite="yes" failonerror="no"/>
|
||||
</else></if>
|
||||
</then></if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
@ -317,6 +330,7 @@ BUILD LOCAL REFERENCE (LOCKER) LAYER
|
|||
<pathelement location="${locker.dir}/lib/library"/>
|
||||
<pathelement location="${locker.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</classpath>
|
||||
<include name="**/*.scala"/>
|
||||
|
@ -462,6 +476,7 @@ BUILD QUICK-TEST LAYER
|
|||
<pathelement location="${quick.dir}/lib/library"/>
|
||||
<pathelement location="${quick.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</classpath>
|
||||
<include name="**/*.scala"/>
|
||||
|
@ -607,6 +622,7 @@ TEST
|
|||
<pathelement location="${strap.dir}/lib/library"/>
|
||||
<pathelement location="${strap.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</classpath>
|
||||
<include name="**/*.scala"/>
|
||||
|
@ -743,6 +759,7 @@ DOCUMENTATION
|
|||
<pathelement location="${quick.dir}/lib/library"/>
|
||||
<pathelement location="${quick.dir}/lib/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</classpath>
|
||||
<include name="**/*.scala"/>
|
||||
|
@ -851,6 +868,7 @@ GENERATES A DISTRIBUTION
|
|||
<jar destfile="${dist.current.dir}/lib/${comp.jar.name}">
|
||||
<fileset dir="${strap.dir}/lib/compiler"/>
|
||||
<zipfileset src="${fjbg.jar}"/>
|
||||
<zipfileset src="${msil.jar}"/>
|
||||
<manifest>
|
||||
<attribute name="Signature-Version" value="${version.number}"/>
|
||||
<attribute name="Built-By" value="${user.name}"/>
|
||||
|
|
|
@ -28,6 +28,7 @@ import transform._
|
|||
import backend.icode.{ICodes, GenICode, Checkers}
|
||||
import backend.ScalaPrimitives
|
||||
import backend.jvm.GenJVM
|
||||
import backend.msil.GenMSIL
|
||||
import backend.opt.{Inliners, ClosureElimination, DeadCodeElimination}
|
||||
import backend.icode.analysis._
|
||||
|
||||
|
@ -170,11 +171,11 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
|
|||
val classPath0 = new ClassPath(false && onlyPresentation)
|
||||
|
||||
val classPath = new classPath0.Build(
|
||||
settings.classpath.value,
|
||||
if (forMSIL) "" else settings.classpath.value,
|
||||
settings.sourcepath.value,
|
||||
settings.outdir.value,
|
||||
settings.bootclasspath.value,
|
||||
settings.extdirs.value)
|
||||
if (forMSIL) "" else settings.bootclasspath.value,
|
||||
if (forMSIL) "" else settings.extdirs.value)
|
||||
|
||||
if (settings.verbose.value) {
|
||||
inform("[Classpath = " + classPath+"]")
|
||||
|
@ -201,7 +202,8 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
|
|||
val global: Global.this.type = Global.this
|
||||
}
|
||||
|
||||
def rootLoader: LazyType = new loaders.PackageLoader(classPath.root /* getRoot() */)
|
||||
def rootLoader: LazyType = if (forMSIL) new loaders.NamespaceLoader(classPath.root)
|
||||
else new loaders.PackageLoader(classPath.root /* getRoot() */)
|
||||
|
||||
val migrateMsg = "migration problem when moving from Scala version 1.0 to version 2.0:\n"
|
||||
|
||||
|
@ -343,6 +345,10 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
|
|||
val global: Global.this.type = Global.this
|
||||
}
|
||||
|
||||
object genMSIL extends GenMSIL {
|
||||
val global: Global.this.type = Global.this
|
||||
}
|
||||
|
||||
object icodeChecker extends checkers.ICodeChecker()
|
||||
|
||||
object typer extends analyzer.Typer(
|
||||
|
@ -371,7 +377,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
|
|||
// inliner,
|
||||
// closureElimination,
|
||||
// deadCode,
|
||||
genJVM,
|
||||
if (forMSIL) genMSIL else genJVM,
|
||||
sampleTransform)
|
||||
|
||||
protected def insertBefore(c: SubComponent, cs: List[SubComponent], before: SubComponent): List[SubComponent] = cs match {
|
||||
|
@ -633,6 +639,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
|
|||
}
|
||||
|
||||
def forCLDC: Boolean = settings.target.value == "cldc"
|
||||
def forMSIL: Boolean = settings.target.value == "msil"
|
||||
def onlyPresentation = settings.doc.value
|
||||
// position stuff
|
||||
final val positionConfiguration: PositionConfiguration = initConfig;
|
||||
|
|
|
@ -92,6 +92,8 @@ class Settings(error: String => unit) {
|
|||
val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault)
|
||||
val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm-1.5", "jvm-1.4", "msil", "cldc"), "jvm-1.4")
|
||||
val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0")
|
||||
val assemname = StringSetting ("-o", "file", "Name of the output assembly (only relevant with -target:msil)", "")
|
||||
val assemrefs = StringSetting ("-r", "path", "List of assemblies referenced by the program (only relevant with -target:msil)", ".")
|
||||
val debug = new BooleanSetting("-debug", "Output debugging messages") { override def hiddenToIDE = true }
|
||||
val deprecation = BooleanSetting ("-deprecation", "enable detailed deprecation warnings")
|
||||
val unchecked = BooleanSetting ("-unchecked", "enable detailed unchecked warnings")
|
||||
|
|
|
@ -445,7 +445,7 @@ abstract class ScalaPrimitives {
|
|||
/** Add a primitive operation to the map */
|
||||
def addPrimitive(s: Symbol, code: Int): Unit = {
|
||||
assert(!(primitives contains s), "Duplicate primitive " + s)
|
||||
primitives += s -> code
|
||||
primitives(s) = code
|
||||
}
|
||||
|
||||
def addPrimitives(cls: Symbol, method: Name, code: Int): Unit = {
|
||||
|
|
|
@ -23,7 +23,9 @@ trait ExceptionHandlers requires ICodes {
|
|||
class ExceptionHandler(val method: IMethod, val label: String, val cls: Symbol) {
|
||||
private var _startBlock: BasicBlock = _;
|
||||
var finalizer: Finalizer = _;
|
||||
|
||||
|
||||
var resultKind: TypeKind = _;
|
||||
|
||||
def setStartBlock(b: BasicBlock) = _startBlock = b;
|
||||
def startBlock = _startBlock;
|
||||
|
||||
|
|
|
@ -480,14 +480,14 @@ abstract class GenICode extends SubComponent {
|
|||
val kind = toTypeKind(tree.tpe)
|
||||
var handlers = for (val CaseDef(pat, _, body) <- catches.reverse)
|
||||
yield pat match {
|
||||
case Typed(Ident(nme.WILDCARD), tpt) => Pair(tpt.tpe.symbol, {
|
||||
case Typed(Ident(nme.WILDCARD), tpt) => Triple(tpt.tpe.symbol, kind, {
|
||||
ctx: Context =>
|
||||
ctx.bb.emit(DROP(REFERENCE(tpt.tpe.symbol)));
|
||||
val ctx1 = genLoad(body, ctx, kind);
|
||||
genLoad(finalizer, ctx1, UNIT);
|
||||
})
|
||||
|
||||
case Ident(nme.WILDCARD) => Pair(definitions.ThrowableClass, {
|
||||
case Ident(nme.WILDCARD) => Triple(definitions.ThrowableClass, kind, {
|
||||
ctx: Context =>
|
||||
ctx.bb.emit(DROP(REFERENCE(definitions.ThrowableClass)))
|
||||
val ctx1 = genLoad(body, ctx, kind)
|
||||
|
@ -498,7 +498,7 @@ abstract class GenICode extends SubComponent {
|
|||
val exception = new Local(pat.symbol, toTypeKind(pat.symbol.tpe), false)
|
||||
ctx.method.addLocal(exception);
|
||||
|
||||
Pair(pat.symbol.tpe.symbol, {
|
||||
Triple(pat.symbol.tpe.symbol, kind, {
|
||||
ctx: Context =>
|
||||
ctx.bb.emit(STORE_LOCAL(exception), pat.pos);
|
||||
val ctx1 = genLoad(body, ctx, kind);
|
||||
|
@ -507,7 +507,7 @@ abstract class GenICode extends SubComponent {
|
|||
}
|
||||
|
||||
if (finalizer != EmptyTree)
|
||||
handlers = Pair(NoSymbol, {
|
||||
handlers = Triple(NoSymbol, kind, {
|
||||
ctx: Context =>
|
||||
val exception = new Local(ctx.method.symbol.newVariable(finalizer.pos, unit.fresh.newName("exc"))
|
||||
.setFlag(Flags.SYNTHETIC)
|
||||
|
@ -686,10 +686,10 @@ abstract class GenICode extends SubComponent {
|
|||
|
||||
ctx1.bb.close
|
||||
ctx1.newBlock
|
||||
} else if (isPrimitive(fun.symbol)) { // primitive method call
|
||||
} else if (isPrimitive(sym)) { // primitive method call
|
||||
val Select(receiver, _) = fun
|
||||
|
||||
val code = scalaPrimitives.getPrimitive(fun.symbol, receiver.tpe)
|
||||
val code = scalaPrimitives.getPrimitive(sym, receiver.tpe)
|
||||
var ctx1 = ctx
|
||||
|
||||
if (scalaPrimitives.isArithmeticOp(code)) {
|
||||
|
@ -733,6 +733,7 @@ abstract class GenICode extends SubComponent {
|
|||
|
||||
if (settings.debug.value)
|
||||
log("synchronized block start");
|
||||
|
||||
ctx1 = ctx1.Try(
|
||||
bodyCtx => {
|
||||
val ctx1 = genLoad(args.head, bodyCtx, expectedType /* toTypeKind(tree.tpe.resultType) */)
|
||||
|
@ -740,7 +741,8 @@ abstract class GenICode extends SubComponent {
|
|||
ctx1.bb.emit(MONITOR_EXIT(), tree.pos)
|
||||
ctx1
|
||||
}, List(
|
||||
Pair(NoSymbol, exhCtx => {
|
||||
// tree.tpe / fun.tpe is object, which is no longer true after this transformation
|
||||
Triple(NoSymbol, expectedType, exhCtx => {
|
||||
exhCtx.bb.emit(LOAD_LOCAL(monitor))
|
||||
exhCtx.bb.emit(MONITOR_EXIT(), tree.pos)
|
||||
exhCtx.bb.emit(THROW())
|
||||
|
@ -756,9 +758,8 @@ abstract class GenICode extends SubComponent {
|
|||
genCoercion(tree, ctx1, code)
|
||||
generatedType = scalaPrimitives.generatedKind(code)
|
||||
} else
|
||||
abort("Primitive operation not handled yet: " +
|
||||
fun.symbol.fullNameString + "(" + fun.symbol.simpleName + ") "
|
||||
+ " at: " + unit.position(tree.pos));
|
||||
abort("Primitive operation not handled yet: " + sym.fullNameString + "(" +
|
||||
fun.symbol.simpleName + ") " + " at: " + unit.position(tree.pos));
|
||||
ctx1
|
||||
} else { // normal method call
|
||||
if (settings.debug.value)
|
||||
|
@ -775,7 +776,7 @@ abstract class GenICode extends SubComponent {
|
|||
if (invokeStyle.hasInstance) genLoadQualifier(fun, ctx)
|
||||
else ctx
|
||||
|
||||
ctx1 = genLoadArguments(args, fun.symbol.info.paramTypes, ctx1)
|
||||
ctx1 = genLoadArguments(args, sym.info.paramTypes, ctx1)
|
||||
|
||||
val hostClass = fun match {
|
||||
case Select(qualifier, _)
|
||||
|
@ -983,6 +984,11 @@ abstract class GenICode extends SubComponent {
|
|||
def isStaticSymbol(s: Symbol): Boolean =
|
||||
s.hasFlag(Flags.STATIC) || s.hasFlag(Flags.STATICMEMBER) || s.owner.isImplClass
|
||||
|
||||
// def isUnbox(s: Symbol): Boolean = (
|
||||
// s.name.==(nme.unbox) && s.owner.isModuleClass
|
||||
// && s.owner.linkedClassOfClass.isSubClass(definitions.AnyValClass)
|
||||
// )
|
||||
|
||||
/**
|
||||
* Generate code that loads args into label parameters.
|
||||
*/
|
||||
|
@ -1044,7 +1050,7 @@ abstract class GenICode extends SubComponent {
|
|||
* @param ctx ...
|
||||
* @param cast ...
|
||||
*/
|
||||
def genBoxedConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) = {
|
||||
def genBoxedConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean): Unit = {
|
||||
assert(to.isValueType || to.isArrayType,
|
||||
"Expecting conversion to value type: " + to)
|
||||
|
||||
|
@ -1054,7 +1060,12 @@ abstract class GenICode extends SubComponent {
|
|||
case ARRAY(elem) =>
|
||||
definitions.boxedArrayClass(elem.toType.symbol)
|
||||
case _ =>
|
||||
definitions.boxedClass(to.toType.symbol)
|
||||
if (cast) {
|
||||
ctx.bb.emit(UNBOX(to))
|
||||
return
|
||||
}
|
||||
else
|
||||
definitions.boxedClass(to.toType.symbol)
|
||||
}
|
||||
|
||||
if (cast) {
|
||||
|
@ -1709,9 +1720,10 @@ abstract class GenICode extends SubComponent {
|
|||
* 'covered' by this exception handler (in addition to the
|
||||
* previously active handlers).
|
||||
*/
|
||||
def newHandler(cls: Symbol): ExceptionHandler = {
|
||||
def newHandler(cls: Symbol, resultKind: TypeKind): ExceptionHandler = {
|
||||
handlerCount = handlerCount + 1
|
||||
val exh = new ExceptionHandler(method, "" + handlerCount, cls)
|
||||
exh.resultKind = resultKind
|
||||
method.addHandler(exh)
|
||||
handlers = exh :: handlers
|
||||
if (settings.debug.value)
|
||||
|
@ -1762,14 +1774,14 @@ abstract class GenICode extends SubComponent {
|
|||
* } ))</code>
|
||||
*/
|
||||
def Try(body: Context => Context,
|
||||
handlers: List[Pair[Symbol, (Context => Context)]],
|
||||
handlers: List[Triple[Symbol, TypeKind, (Context => Context)]],
|
||||
finalizer: Tree) = {
|
||||
val outerCtx = this.dup
|
||||
val afterCtx = outerCtx.newBlock
|
||||
|
||||
val exhs = handlers.map { handler =>
|
||||
val exh = this.newHandler(handler._1)
|
||||
val ctx1 = handler._2(outerCtx.enterHandler(exh))
|
||||
val exh = this.newHandler(handler._1, handler._2)
|
||||
val ctx1 = handler._3(outerCtx.enterHandler(exh))
|
||||
ctx1.bb.emit(JUMP(afterCtx.bb))
|
||||
ctx1.bb.close
|
||||
exh
|
||||
|
|
|
@ -32,23 +32,7 @@ trait TypeKinds requires ICodes {
|
|||
* represent the types that the VM know (or the ICode
|
||||
* view of what VMs know).
|
||||
*/
|
||||
abstract class TypeKind {
|
||||
|
||||
/** Returns a string representation of this type kind. */
|
||||
override def toString(): String = this match {
|
||||
case UNIT => "UNIT"
|
||||
case BOOL => "BOOL"
|
||||
case BYTE => "BYTE"
|
||||
case SHORT => "SHORT"
|
||||
case CHAR => "CHAR"
|
||||
case INT => "INT"
|
||||
case LONG => "LONG"
|
||||
case FLOAT => "FLOAT"
|
||||
case DOUBLE => "DOUBLE"
|
||||
case REFERENCE(cls) => "REFERENCE(" + cls.fullNameString + ")"
|
||||
case ARRAY(elem) => "ARRAY[" + elem + "]"
|
||||
case _ => abort("Unkown type kind.")
|
||||
}
|
||||
sealed abstract class TypeKind {
|
||||
|
||||
def toType: Type = this match {
|
||||
case UNIT => definitions.UnitClass.tpe
|
||||
|
@ -61,6 +45,7 @@ trait TypeKinds requires ICodes {
|
|||
case FLOAT => definitions.FloatClass.tpe
|
||||
case DOUBLE => definitions.DoubleClass.tpe
|
||||
case REFERENCE(cls) => typeRef(cls.typeConstructor.prefix, cls, Nil)
|
||||
//case VALUE(cls) => typeRef(cls.typeConstructor.prefix, cls, Nil);
|
||||
case ARRAY(elem) => typeRef(definitions.ArrayClass.typeConstructor.prefix,
|
||||
definitions.ArrayClass,
|
||||
elem.toType :: Nil)
|
||||
|
@ -216,7 +201,7 @@ trait TypeKinds requires ICodes {
|
|||
// }
|
||||
|
||||
/** A class type. */
|
||||
case class REFERENCE(cls: Symbol) extends TypeKind {
|
||||
final case class REFERENCE(cls: Symbol) extends TypeKind {
|
||||
assert(cls ne null,
|
||||
"REFERENCE to null class symbol.")
|
||||
assert(cls != definitions.ArrayClass,
|
||||
|
@ -260,8 +245,20 @@ trait TypeKinds requires ICodes {
|
|||
}
|
||||
}
|
||||
|
||||
// final case class VALUE(cls: Symbol) extends TypeKind {
|
||||
// override def equals(other: Any): Boolean = other match {
|
||||
// case VALUE(cls2) => cls == cls2;
|
||||
// case _ => false;
|
||||
// }
|
||||
|
||||
case class ARRAY(val elem: TypeKind) extends TypeKind {
|
||||
// def maxType(other: TypeKind): TypeKind =
|
||||
// abort(toString() + " maxType " + other.toString());
|
||||
|
||||
// override def toString(): String =
|
||||
// "VALUE(" + cls.fullNameString + ")";
|
||||
// }
|
||||
|
||||
final case class ARRAY(val elem: TypeKind) extends TypeKind {
|
||||
override def toString(): String =
|
||||
"ARRAY[" + elem + "]"
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,6 +41,13 @@ trait Definitions requires SymbolTable {
|
|||
var NullPointerExceptionClass: Symbol = _
|
||||
var NonLocalReturnExceptionClass: Symbol = _
|
||||
|
||||
var ValueTypeClass: Symbol = _ // System.ValueType
|
||||
var DelegateClass: Symbol = _ // System.MulticastDelegate
|
||||
var Delegate_scalaCallers: List[Symbol] = List()
|
||||
// Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
|
||||
// var Delegate_scalaCallerInfos: HashMap[Symbol, Pair[Symbol, Type]] = _
|
||||
var Delegate_scalaCallerTargets: HashMap[Symbol, Symbol] = _
|
||||
|
||||
// the scala value classes
|
||||
var UnitClass: Symbol = _
|
||||
var BooleanClass: Symbol = _
|
||||
|
@ -269,6 +276,32 @@ trait Definitions requires SymbolTable {
|
|||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def isCorrespondingDelegate(delegateType: Type, functionType: Type): boolean = {
|
||||
var isCD: Boolean = false;
|
||||
if (DelegateClass != null && delegateType != null &&
|
||||
isSubType(delegateType, DelegateClass.tpe))
|
||||
{
|
||||
val meth: Symbol = delegateType.member(nme.apply)
|
||||
meth.tpe match {
|
||||
case MethodType(delegateParams, delegateReturn) =>
|
||||
val delegateParamsO = delegateParams.map(pt => {if (pt == definitions.AnyClass.tpe) definitions.ObjectClass.tpe else pt});
|
||||
if(isFunctionType(functionType))
|
||||
functionType match {
|
||||
case TypeRef(_, _, args) =>
|
||||
if(delegateParamsO == args.dropRight(1) &&
|
||||
delegateReturn == args.last)
|
||||
isCD = true;
|
||||
|
||||
case _ => ();
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
isCD
|
||||
}
|
||||
|
||||
/* val RemoteFunctionClass: Array[Symbol] = new Array(MaxFunctionArity + 1)
|
||||
def remoteFunctionApply(n: Int) = getMember(RemoteFunctionClass(n), nme.apply)
|
||||
def remoteFunctionType(formals: List[Type], restpe: Type) =
|
||||
|
@ -428,7 +461,17 @@ trait Definitions requires SymbolTable {
|
|||
|
||||
private def newValueClass(name: Name, tag: char): Symbol = {
|
||||
def boxedName: String =
|
||||
"scala.runtime.Boxed" + name
|
||||
if (!forMSIL) "scala.runtime.Boxed" + name
|
||||
else "System." + (name match {
|
||||
case nme.Boolean => "Boolean"
|
||||
case nme.Byte => "Byte"
|
||||
case nme.Char => "Char"
|
||||
case nme.Short => "Int16"
|
||||
case nme.Int => "Int32"
|
||||
case nme.Long => "Int64"
|
||||
case nme.Float => "Single"
|
||||
case nme.Double => "Double"
|
||||
})
|
||||
val clazz =
|
||||
newClass(ScalaPackageClass, name, List(AnyValClass.typeConstructor))
|
||||
.setFlag(ABSTRACT /* SEALED */) // bq: SEALED is interesting for case class descendants, only
|
||||
|
@ -606,9 +649,12 @@ trait Definitions requires SymbolTable {
|
|||
def isNumericValueClass(sym: Symbol): boolean =
|
||||
(sym ne BooleanClass) && (boxedClass contains sym)
|
||||
|
||||
def isValueType(sym: Symbol) =
|
||||
isValueClass(sym) || unboxMethod.contains(sym)
|
||||
|
||||
/** Is symbol a value or array class? */
|
||||
def isUnboxedClass(sym: Symbol): boolean =
|
||||
isValueClass(sym) || sym == ArrayClass
|
||||
isValueType(sym) || sym == ArrayClass
|
||||
|
||||
def signature(tp: Type): String = {
|
||||
def erasure(tp: Type): Type = tp match {
|
||||
|
@ -650,7 +696,7 @@ trait Definitions requires SymbolTable {
|
|||
RootClass.info.decls.enter(EmptyPackage)
|
||||
RootClass.info.decls.enter(RootPackage)
|
||||
|
||||
JavaLangPackage = getModule("java.lang")
|
||||
JavaLangPackage = getModule(if (forMSIL) "System" else "java.lang")
|
||||
ScalaPackage = getModule("scala")
|
||||
assert(ScalaPackage ne null, "Scala package is null")
|
||||
ScalaPackageClass = ScalaPackage.tpe.symbol
|
||||
|
@ -662,7 +708,7 @@ trait Definitions requires SymbolTable {
|
|||
AnyValClass = newClass(ScalaPackageClass, nme.AnyVal, anyparam)
|
||||
.setFlag(FINAL | SEALED)
|
||||
|
||||
ObjectClass = getClass("java.lang.Object")
|
||||
ObjectClass = getClass(if (forMSIL) "System.Object" else "java.lang.Object")
|
||||
|
||||
AnyRefClass =
|
||||
newAlias(ScalaPackageClass, nme.AnyRef, ObjectClass.typeConstructor)
|
||||
|
@ -675,13 +721,17 @@ trait Definitions requires SymbolTable {
|
|||
AllClass = newClass(ScalaPackageClass, nme.Nothing, anyparam)
|
||||
.setFlag(ABSTRACT | TRAIT | FINAL)
|
||||
|
||||
StringClass = getClass("java.lang.String")
|
||||
StringClass = getClass(if (forMSIL) "System.String" else "java.lang.String")
|
||||
|
||||
ClassClass = getClass("java.lang.Class")
|
||||
ThrowableClass = getClass("java.lang.Throwable")
|
||||
NullPointerExceptionClass = getClass("java.lang.NullPointerException")
|
||||
ClassClass = getClass(if (forMSIL) "System.Type" else "java.lang.Class")
|
||||
ThrowableClass = getClass(if (forMSIL) "System.Exception" else "java.lang.Throwable")
|
||||
NullPointerExceptionClass = getClass(if (forMSIL) "System.NullReferenceException"
|
||||
else "java.lang.NullPointerException")
|
||||
NonLocalReturnExceptionClass = getClass("scala.runtime.NonLocalReturnException")
|
||||
|
||||
ValueTypeClass = if (forMSIL) getClass("System.ValueType") else null
|
||||
DelegateClass = if (forMSIL) getClass("System.MulticastDelegate") else null
|
||||
|
||||
UnitClass =
|
||||
newClass(ScalaPackageClass, nme.Unit, List(AnyValClass.typeConstructor))
|
||||
abbrvTag(UnitClass) = 'V'
|
||||
|
@ -704,7 +754,7 @@ trait Definitions requires SymbolTable {
|
|||
StaticAttributeClass = getClass("scala.StaticAttribute")
|
||||
//ChannelClass = getClass("scala.distributed.Channel")
|
||||
//RemoteRefClass = getClass("scala.distributed.RemoteRef")
|
||||
if (!forCLDC) {
|
||||
if (!forCLDC && ! forMSIL) {
|
||||
CodeClass = getClass("scala.reflect.Code")
|
||||
CodeModule = getModule("scala.reflect.Code")
|
||||
}
|
||||
|
@ -716,12 +766,14 @@ trait Definitions requires SymbolTable {
|
|||
ListClass = getClass("scala.List")
|
||||
ListModule = getModule("scala.List")
|
||||
ArrayClass = getClass("scala.Array")
|
||||
SerializableClass = if (forCLDC) null else getClass("java.io.Serializable")
|
||||
SerializableClass = if (forMSIL || forCLDC) null else getClass("java.io.Serializable")
|
||||
PredefModule = getModule("scala.Predef")
|
||||
ConsoleModule = getModule("scala.Console")
|
||||
MatchErrorClass = getClass("scala.MatchError")
|
||||
MatchErrorModule = getModule("scala.MatchError")
|
||||
IndexOutOfBoundsExceptionClass = getClass("java.lang.IndexOutOfBoundsException")
|
||||
IndexOutOfBoundsExceptionClass =
|
||||
getClass(if (forMSIL) "System.IndexOutOfRangeException"
|
||||
else "java.lang.IndexOutOfBoundsException")
|
||||
//RemoteExecutionModule = getModule("scala.distributed.RemoteExecution")
|
||||
ScalaRunTimeModule = getModule("scala.runtime.ScalaRunTime")
|
||||
RepeatedParamClass = newCovariantPolyClass(
|
||||
|
@ -792,12 +844,85 @@ trait Definitions requires SymbolTable {
|
|||
BoxedUnitModule = getModule("scala.runtime.BoxedUnit")
|
||||
ObjectRefClass = getClass("scala.runtime.ObjectRef")
|
||||
|
||||
if (forMSIL) {
|
||||
val intType = IntClass.typeConstructor;
|
||||
val intParam = List(intType);
|
||||
val longType = LongClass.typeConstructor;
|
||||
val charType = CharClass.typeConstructor;
|
||||
val unitType = UnitClass.typeConstructor;
|
||||
val stringType = StringClass.typeConstructor;
|
||||
val stringParam = List(stringType);
|
||||
|
||||
// additional methods of Object
|
||||
newMethod(ObjectClass, "clone", List(), AnyRefClass.typeConstructor);
|
||||
newMethod(ObjectClass, "wait", List(), unitType);
|
||||
newMethod(ObjectClass, "wait", List(longType), unitType);
|
||||
newMethod(ObjectClass, "wait", List(longType, intType), unitType);
|
||||
newMethod(ObjectClass, "notify", List(), unitType);
|
||||
newMethod(ObjectClass, "notifyAll", List(), unitType);
|
||||
|
||||
// additional methods of String
|
||||
newMethod(StringClass, "length", List(), intType);
|
||||
newMethod(StringClass, "compareTo", stringParam, intType);
|
||||
newMethod(StringClass, "charAt", intParam, charType);
|
||||
newMethod(StringClass, "concat", stringParam, stringType);
|
||||
newMethod(StringClass, "indexOf", intParam, intType);
|
||||
newMethod(StringClass, "indexOf", List(intType, intType), intType);
|
||||
newMethod(StringClass, "indexOf", stringParam, intType);
|
||||
newMethod(StringClass, "indexOf", List(stringType, intType), intType);
|
||||
newMethod(StringClass, "lastIndexOf", intParam, intType);
|
||||
newMethod(StringClass, "lastIndexOf", List(intType, intType), intType);
|
||||
newMethod(StringClass, "lastIndexOf", stringParam, intType);
|
||||
newMethod(StringClass, "lastIndexOf", List(stringType, intType), intType);
|
||||
newMethod(StringClass, "toLowerCase", List(), stringType);
|
||||
newMethod(StringClass, "toUpperCase", List(), stringType);
|
||||
newMethod(StringClass, "startsWith", stringParam, booltype);
|
||||
newMethod(StringClass, "endsWith", stringParam, booltype);
|
||||
newMethod(StringClass, "substring", intParam, stringType);
|
||||
newMethod(StringClass, "substring", List(intType, intType), stringType);
|
||||
newMethod(StringClass, "trim", List(), stringType);
|
||||
newMethod(StringClass, "intern", List(), stringType);
|
||||
newMethod(StringClass, "replace", List(charType, charType), stringType);
|
||||
newMethod(StringClass, "toCharArray", List(),
|
||||
appliedType(ArrayClass.typeConstructor, List(charType)));
|
||||
|
||||
// Delegate_scalaCallerInfos = new HashMap()
|
||||
Delegate_scalaCallerTargets = new HashMap()
|
||||
}
|
||||
|
||||
AnnotationDefaultAttr = newClass(RootClass,
|
||||
nme.AnnotationDefaultATTR,
|
||||
List(AttributeClass.typeConstructor))
|
||||
SerializableAttr = getClass("scala.serializable")
|
||||
BeanPropertyAttr = if (forCLDC || forMSIL) null else getClass("scala.reflect.BeanProperty")
|
||||
DeprecatedAttr = getClass("scala.deprecated")
|
||||
BeanPropertyAttr = if (forCLDC) null else getClass("scala.reflect.BeanProperty")
|
||||
}
|
||||
|
||||
var nbScalaCallers: Int = 0
|
||||
def newScalaCaller(delegateType: Type): Symbol = {
|
||||
assert(forMSIL, "scalaCallers can only be created if target is .NET")
|
||||
// object: reference to object on which to call (scala-)metod
|
||||
val paramTypes: List[Type] = List(ObjectClass.tpe)
|
||||
val name: String = "$scalaCaller$$" + nbScalaCallers
|
||||
// tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
|
||||
// type parameter =-> a MethodType in this case
|
||||
// TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
|
||||
val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType) setFlag (FINAL | STATIC)
|
||||
// val newCaller = newPolyMethod(DelegateClass, name,
|
||||
// tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
|
||||
Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
|
||||
nbScalaCallers = nbScalaCallers + 1
|
||||
newCaller
|
||||
}
|
||||
|
||||
// def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol, delType: Type) = {
|
||||
// assert(Delegate_scalaCallers contains scalaCaller)
|
||||
// Delegate_scalaCallerInfos += scalaCaller -> Pair(methSym, delType)
|
||||
// }
|
||||
|
||||
def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol) = {
|
||||
assert(Delegate_scalaCallers contains scalaCaller)
|
||||
Delegate_scalaCallerTargets += scalaCaller -> methSym
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ trait StdNames requires SymbolTable {
|
|||
val filter = newTermName("filter")
|
||||
val finalize_ = newTermName("finalize")
|
||||
val flatMap = newTermName("flatMap")
|
||||
val forName = newTermName("forName")
|
||||
val forName = newTermName(if (forMSIL) "GetType" else "forName")
|
||||
val foreach = newTermName("foreach")
|
||||
val get = newTermName("get")
|
||||
val getClass_ = newTermName("getClass")
|
||||
|
|
|
@ -8,12 +8,12 @@ package scala.tools.nsc.symtab
|
|||
|
||||
import compat.Platform.currentTime
|
||||
import java.io.{File, IOException}
|
||||
|
||||
import scala.collection.mutable.HashMap
|
||||
import scala.collection.mutable.{HashMap, HashSet}
|
||||
import scala.tools.nsc.io.AbstractFile
|
||||
import scala.tools.nsc.util.{ClassPath, NameTransformer, Position}
|
||||
import classfile.{ClassfileParser, SymblfileParser}
|
||||
import Flags._
|
||||
import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute};
|
||||
|
||||
/** This class ...
|
||||
*
|
||||
|
@ -57,8 +57,8 @@ abstract class SymbolLoaders {
|
|||
phase = currentphase
|
||||
def source = kindString + " " + sourceString
|
||||
informTime("loaded " + source, start)
|
||||
if (root.rawInfo == this && root.linkedSym.rawInfo == this)
|
||||
throw new TypeError(source + " does not define " + root)
|
||||
//if (root.rawInfo == this && root.linkedSym.rawInfo == this)
|
||||
// throw new TypeError(source + " does not define " + root)
|
||||
ok = true
|
||||
} catch {
|
||||
case ex: IOException =>
|
||||
|
@ -88,12 +88,50 @@ abstract class SymbolLoaders {
|
|||
/** Load contents of a package
|
||||
*/
|
||||
class PackageLoader(directory: global.classPath0.Context) extends SymbolLoader {
|
||||
// System.err.println("PACKAGE LOADER: " + directory)
|
||||
|
||||
protected def sourceString = directory.toString()
|
||||
|
||||
protected def kindString: String = "directory path"
|
||||
|
||||
protected def newPackageLoader(dir: global.classPath0.Context): PackageLoader =
|
||||
new PackageLoader(dir)
|
||||
|
||||
protected def checkSource(name: String, source: AbstractFile): Boolean = true;
|
||||
|
||||
protected var root: Symbol = _
|
||||
|
||||
def enterPackage(name: String, completer: SymbolLoader): unit = {
|
||||
val pkg = root.newPackage(NoPos, newTermName(name))
|
||||
pkg.moduleClass.setInfo(completer)
|
||||
pkg.setInfo(pkg.moduleClass.tpe)
|
||||
root.info.decls.enter(pkg)
|
||||
}
|
||||
|
||||
// @return - the symbol of the class
|
||||
def enterClassAndModule(name: String, completer: SymbolLoader): Symbol = {
|
||||
val owner = if (root.isRoot) definitions.EmptyPackageClass else root
|
||||
val className = newTermName(name)
|
||||
assert(owner.info.decls.lookup(name) == NoSymbol, owner.fullNameString + "." + name)
|
||||
val clazz = owner.newClass(NoPos, name.toTypeName)
|
||||
val module = owner.newModule(NoPos, name)
|
||||
clazz.setInfo(completer)
|
||||
module.setInfo(completer)
|
||||
module.moduleClass.setInfo(moduleClassLoader)
|
||||
owner.info.decls.enter(clazz)
|
||||
owner.info.decls.enter(module)
|
||||
// if (completer.sourceFile != null) {
|
||||
// clazz.sourceFile = completer.sourceFile;
|
||||
// module.moduleClass.sourceFile = completer.sourceFile
|
||||
// }
|
||||
assert(clazz.linkedModuleOfClass == module, module)
|
||||
assert(module.linkedClassOfModule == clazz, clazz)
|
||||
//System.out.println("Added class " + clazz.fullNameString);
|
||||
clazz
|
||||
}
|
||||
|
||||
protected def doComplete(root: Symbol): unit = {
|
||||
assert(root.isPackageClass, root)
|
||||
this.root = root
|
||||
val scope = newScope
|
||||
root.setInfo(new PackageClassInfoType(scope, root))
|
||||
|
||||
|
@ -102,40 +140,13 @@ abstract class SymbolLoaders {
|
|||
name.length() > 0 && (settings.XbytecodeRead.value ||
|
||||
(!name.endsWith("$class") && name.indexOf("$anon") == -1));
|
||||
|
||||
def enterPackage(str: String, completer: SymbolLoader): unit = {
|
||||
val pkg = root.newPackage(NoPos, newTermName(str))
|
||||
pkg.moduleClass.setInfo(completer)
|
||||
pkg.setInfo(pkg.moduleClass.tpe)
|
||||
root.info.decls.enter(pkg)
|
||||
}
|
||||
|
||||
def enterClassAndModule(str: String, completer: SymbolLoader): unit = {
|
||||
val owner = if (root.isRoot) definitions.EmptyPackageClass else root
|
||||
val name = newTermName(str)
|
||||
val clazz = owner.newClass(NoPos, name.toTypeName)
|
||||
val module = owner.newModule(NoPos, name)
|
||||
clazz.setInfo(completer)
|
||||
module.setInfo(completer)
|
||||
module.moduleClass.setInfo(moduleClassLoader)
|
||||
owner.info.decls.enter(clazz)
|
||||
owner.info.decls.enter(module)
|
||||
/*
|
||||
if (completer.sourceFile ne null) {
|
||||
clazz.sourceFile = completer.sourceFile;
|
||||
module.moduleClass.sourceFile = completer.sourceFile
|
||||
}
|
||||
*/
|
||||
assert(clazz.linkedModuleOfClass == module, module)
|
||||
assert(module.linkedClassOfModule == clazz, clazz)
|
||||
}
|
||||
|
||||
val classes = new HashMap[String, global.classPath0.Context]
|
||||
val packages = new HashMap[String, global.classPath0.Context]
|
||||
for (val dir <- directory.entries) if (dir.location ne null) {
|
||||
for (val file <- dir.location) {
|
||||
if (file.isDirectory && directory.validPackage(file.name) && !packages.isDefinedAt(file.name))
|
||||
packages(file.name) = directory.find(file.name, true);
|
||||
else if (!file.isDirectory && file.name.endsWith(".class")) {
|
||||
else if (!global.forMSIL && !file.isDirectory && file.name.endsWith(".class")) {
|
||||
val name = file.name.substring(0, file.name.length() - (".class").length());
|
||||
if (isValid(name) && !classes.isDefinedAt(name)) {
|
||||
val clazz = directory.find(name, false)
|
||||
|
@ -147,33 +158,35 @@ abstract class SymbolLoaders {
|
|||
for (val dir <- directory.entries) if (dir.source ne null) {
|
||||
for (val file <- dir.source.location) {
|
||||
if (file.isDirectory && directory.validPackage(file.name) && !packages.isDefinedAt(file.name))
|
||||
packages(file.name) = directory.find(file.name, true);
|
||||
packages(file.name) = directory.find(file.name, true)
|
||||
else if (dir.source.compile && !file.isDirectory && file.name.endsWith(".scala")) {
|
||||
val name = file.name.substring(0, file.name.length() - (".scala").length());
|
||||
val name = file.name.substring(0, file.name.length() - (".scala").length())
|
||||
if (isValid(name) && !classes.isDefinedAt(name)) {
|
||||
val source = directory.find(name, false)
|
||||
if (source ne null) classes(name) = source
|
||||
if ((source ne null) && (source.sourceFile ne null))
|
||||
if (checkSource(name, source.sourceFile))
|
||||
classes(name) = source
|
||||
else if (settings.debug.value)
|
||||
Console.println("Skipping source file " + source.sourceFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (!packages.isEmpty) System.err.println("COMPLETE: " + packages)
|
||||
//if (! classes.isEmpty) System.err.println("COMPLETE: " + classes)
|
||||
// do classes first
|
||||
|
||||
// do classes first
|
||||
for (val {name, file} <- classes.elements) {
|
||||
val loader = if (!file.isSourceFile) {
|
||||
new ClassfileLoader(file.classFile, file.sourceFile, file.sourcePath);
|
||||
new ClassfileLoader(file.classFile, file.sourceFile, file.sourcePath)
|
||||
} else {
|
||||
assert(file.sourceFile ne null)
|
||||
new SourcefileLoader(file.sourceFile)
|
||||
}
|
||||
enterClassAndModule(name, loader)
|
||||
}
|
||||
|
||||
for (val {name, file} <- packages.elements)
|
||||
enterPackage(name, new PackageLoader(file))
|
||||
enterPackage(name, newPackageLoader(file))
|
||||
}
|
||||
protected def kindString: String = "directory path"
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -182,7 +195,68 @@ abstract class SymbolLoaders {
|
|||
}
|
||||
*/
|
||||
|
||||
class NamespaceLoader(directory: global.classPath0.Context) extends PackageLoader(directory) {
|
||||
|
||||
override protected def kindString: String = "namespace " + namespace
|
||||
|
||||
override protected def sourceString = "";
|
||||
|
||||
override def newPackageLoader(dir: global.classPath0.Context): PackageLoader =
|
||||
new NamespaceLoader(dir);
|
||||
|
||||
val types = new HashMap[String,MSILType]();
|
||||
|
||||
val namespaces = new HashSet[String]();
|
||||
|
||||
def namespace: String = if (root.isRoot) "" else root.fullNameString;
|
||||
|
||||
// TODO: Add check whether the source is newer than the assembly
|
||||
override protected def checkSource(name: String, source: AbstractFile): Boolean = {
|
||||
!types.contains(name)
|
||||
}
|
||||
|
||||
override protected def doComplete(root: Symbol): Unit = {
|
||||
clrTypes.collectMembers(root, types, namespaces);
|
||||
|
||||
super.doComplete(root);
|
||||
|
||||
for (val namespace <- namespaces.elements) {
|
||||
val oldPkg = root.info.decls.lookup(newTermName(namespace));
|
||||
if (oldPkg == NoSymbol)
|
||||
enterPackage(namespace, new NamespaceLoader(new classPath0.Context(List())));
|
||||
//else System.out.println("PackageLoader: package already in scope: " + oldPkg.fullNameString);
|
||||
}
|
||||
|
||||
// import the CLR types contained in the package (namespace)
|
||||
for (val Pair(name, typ) <- types.elements) {
|
||||
assert(namespace == typ.Namespace, typ.FullName);
|
||||
|
||||
if (typ.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) {
|
||||
val attrs = typ.GetCustomAttributes(clrTypes.SCALA_SYMTAB_ATTR, false);
|
||||
assert (attrs.length == 1, attrs.length);
|
||||
val a = attrs(0).asInstanceOf[MSILAttribute];
|
||||
if (a.getConstructor() == clrTypes.SYMTAB_CONSTR)
|
||||
enterClassAndModule(name, new MSILTypeLoader(typ));
|
||||
}
|
||||
else
|
||||
enterClassAndModule(name, new MSILTypeLoader(typ));
|
||||
}
|
||||
}
|
||||
} // NamespaceLoader
|
||||
|
||||
class MSILTypeLoader(typ: MSILType) extends SymbolLoader {
|
||||
private object typeParser extends clr.TypeParser {
|
||||
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global;
|
||||
}
|
||||
protected def doComplete(root: Symbol): Unit = {
|
||||
typeParser.parse(typ, root);
|
||||
}
|
||||
protected def kindString: String = typ.FullName;
|
||||
protected def sourceString = typ.Assembly.FullName;
|
||||
}
|
||||
|
||||
class ClassfileLoader(classFile: AbstractFile, override val sourceFile: AbstractFile, sourcePath0: AbstractFile) extends SymbolLoader {
|
||||
//throw new Error("classfile = " + classFile + "; sourcefile = " + sourceFile + "; sourcepath = " + sourcePath0)
|
||||
private object classfileParser extends ClassfileParser {
|
||||
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
|
||||
override def sourcePath = sourcePath0 /* could be null */
|
||||
|
@ -215,4 +289,10 @@ abstract class SymbolLoaders {
|
|||
protected def kindString: String = "";
|
||||
protected def sourceString = "";
|
||||
}
|
||||
|
||||
object clrTypes extends clr.CLRTypes {
|
||||
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global;
|
||||
if (global.forMSIL) init();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,10 @@ abstract class SymbolTable extends Names
|
|||
/** Are we compiling for the J2ME CLDC platform? */
|
||||
def forCLDC: Boolean
|
||||
|
||||
/** A period is an ordinal number for a phase in a run.
|
||||
/** Are we compiling for .NET*/
|
||||
def forMSIL: Boolean
|
||||
|
||||
/** A period is an ordinal number for a phase in a run.
|
||||
* Phases in later runs have higher periods than phases in earlier runs.
|
||||
* Later phases have higher periods than earlier phases in the same run.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
/* NSC -- new scala compiler
|
||||
* Copyright 2004-2006 LAMP/EPFL
|
||||
*/
|
||||
|
||||
// $Id: CLRTypes.scala 9524 2006-12-14 17:54:07Z mihaylov $
|
||||
|
||||
package scala.tools.nsc.symtab.clr;
|
||||
|
||||
import scala.tools.nsc.util.Position;
|
||||
|
||||
import scala.collection.mutable.{ListBuffer, Map, HashMap, Set, HashSet};
|
||||
import java.util.{Arrays, Comparator, StringTokenizer};
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import ch.epfl.lamp.compiler.msil._;
|
||||
|
||||
/**
|
||||
* Collects all types from all reference assemblies.
|
||||
*/
|
||||
abstract class CLRTypes {
|
||||
|
||||
val global: Global;
|
||||
import global.Symbol;
|
||||
import global.definitions;
|
||||
|
||||
//##########################################################################
|
||||
|
||||
var BYTE: Type = _;
|
||||
var UBYTE: Type = _;
|
||||
var SHORT: Type = _;
|
||||
var USHORT: Type = _;
|
||||
var CHAR: Type = _;
|
||||
var INT: Type = _;
|
||||
var UINT: Type = _;
|
||||
var LONG: Type = _;
|
||||
var ULONG: Type = _;
|
||||
var FLOAT: Type = _;
|
||||
var DOUBLE: Type = _;
|
||||
var BOOLEAN: Type = _;
|
||||
var VOID: Type = _;
|
||||
var ENUM: Type = _;
|
||||
var DELEGATE: Type = _;
|
||||
|
||||
var OBJECT: Type = _;
|
||||
var STRING: Type = _;
|
||||
var STRING_ARRAY: Type = _;
|
||||
|
||||
var VALUE_TYPE: Type = _;
|
||||
|
||||
var SCALA_SYMTAB_ATTR: Type = _;
|
||||
var SYMTAB_CONSTR: ConstructorInfo = _;
|
||||
var SYMTAB_DEFAULT_CONSTR: ConstructorInfo = _;
|
||||
|
||||
var DELEGATE_COMBINE: MethodInfo = _;
|
||||
var DELEGATE_REMOVE: MethodInfo = _;
|
||||
|
||||
val types: Map[Symbol,Type] = new HashMap;
|
||||
val constructors: Map[Symbol,ConstructorInfo] = new HashMap;
|
||||
val methods: Map[Symbol,MethodInfo] = new HashMap;
|
||||
val fields: Map[Symbol, FieldInfo] = new HashMap;
|
||||
val sym2type: Map[Type,Symbol] = new HashMap;
|
||||
|
||||
private var alltypes: Array[Type] = _;
|
||||
|
||||
def init(): Unit = { // initialize
|
||||
|
||||
val assems = new StringTokenizer(global.settings.assemrefs.value, File.pathSeparator);
|
||||
while (assems.hasMoreTokens()) {
|
||||
assemrefs += new File(assems.nextToken());
|
||||
}
|
||||
|
||||
val mscorlib = findAssembly("mscorlib.dll");
|
||||
Type.initMSCORLIB(mscorlib);
|
||||
findAssembly("scalaruntime.dll");
|
||||
findAllAssemblies();
|
||||
|
||||
BYTE = getTypeSafe("System.SByte");
|
||||
UBYTE = getTypeSafe("System.Byte");
|
||||
CHAR = getTypeSafe("System.Char");
|
||||
SHORT = getTypeSafe("System.Int16");
|
||||
USHORT = getTypeSafe("System.UInt16");
|
||||
INT = getTypeSafe("System.Int32");
|
||||
UINT = getTypeSafe("System.UInt32");
|
||||
LONG = getTypeSafe("System.Int64");
|
||||
ULONG = getTypeSafe("System.UInt64");
|
||||
FLOAT = getTypeSafe("System.Single");
|
||||
DOUBLE = getTypeSafe("System.Double");
|
||||
BOOLEAN = getTypeSafe("System.Boolean");
|
||||
VOID = getTypeSafe("System.Void");
|
||||
ENUM = getTypeSafe("System.Enum");
|
||||
DELEGATE = getTypeSafe("System.MulticastDelegate");
|
||||
|
||||
OBJECT = getTypeSafe("System.Object");
|
||||
STRING = getTypeSafe("System.String");
|
||||
STRING_ARRAY = getTypeSafe("System.String[]");
|
||||
VALUE_TYPE = getTypeSafe("System.ValueType");
|
||||
|
||||
SCALA_SYMTAB_ATTR = getTypeSafe("scala.runtime.SymtabAttribute");
|
||||
val bytearray: Array[Type] = Array( Type.GetType("System.Byte[]") );
|
||||
SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray);
|
||||
SYMTAB_DEFAULT_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes);
|
||||
|
||||
//assert(SCALA_SYMTAB_ATTR != null);
|
||||
|
||||
val delegate: Type = getTypeSafe("System.Delegate");
|
||||
val dargs: Array[Type] = Array(delegate, delegate);
|
||||
DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs);
|
||||
DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs);
|
||||
//assert(DELEGATE_COMBINE != null);
|
||||
//assert(DELEGATE_REMOVE != null);
|
||||
|
||||
|
||||
var alltypes: Array[Type] = Type.EmptyTypes;
|
||||
for (val assem <- assemblies) {
|
||||
val atypes = assem.GetTypes().filter((typ: Type) => typ.DeclaringType == null);
|
||||
alltypes = Array.concat(alltypes, atypes);
|
||||
}
|
||||
|
||||
val typeNameComparator: Comparator =
|
||||
new Comparator() {
|
||||
def compare(o1: Any, o2: Any): Int = {
|
||||
val t1 = o1.asInstanceOf[Type];
|
||||
val t2 = o2.asInstanceOf[Type];
|
||||
t1.FullName.compareTo(t2.FullName);
|
||||
}
|
||||
};
|
||||
|
||||
Arrays.sort(alltypes.asInstanceOf[Array[Object]], typeNameComparator);
|
||||
this.alltypes = alltypes;
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
// type mapping and lookup
|
||||
|
||||
// private class MyHashMap[A, B <: AnyRef] extends HashMap[A, B] {
|
||||
// override def default(key: A): B = null;
|
||||
// }
|
||||
|
||||
def getType(name: String): Type = Type.GetType(name);
|
||||
|
||||
def getTypeSafe(name: String): Type = {
|
||||
val t = Type.GetType(name);
|
||||
assert(t != null, name);
|
||||
t;
|
||||
}
|
||||
|
||||
def mkArrayType(elemType: Type): Type = getType(elemType.FullName + "[]");
|
||||
|
||||
def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE }
|
||||
|
||||
//##########################################################################
|
||||
// assembly loading methods
|
||||
|
||||
// a list of all loaded assemblies
|
||||
private var assemblies: ListBuffer[Assembly] = new ListBuffer();
|
||||
|
||||
// a set of all directories and assembly files
|
||||
private var assemrefs: Set[File] = new HashSet();
|
||||
|
||||
/** Load the assembly with the given name
|
||||
*/
|
||||
private def findAssembly(name: String): Assembly = {
|
||||
// see if the assembly is referenced directly
|
||||
for (val file <- assemrefs.elements; file.getName() == name) {
|
||||
val assem = Assembly.LoadFrom(file.getPath());
|
||||
if (assem != null) {
|
||||
assemrefs -= file;
|
||||
assemblies += assem;
|
||||
return assem;
|
||||
}
|
||||
}
|
||||
// look in directories specified with the '-r' option
|
||||
for (val dir <- assemrefs.elements; dir.isDirectory()) {
|
||||
val file = new File(dir, name);
|
||||
if (file.exists()) {
|
||||
val assem = Assembly.LoadFrom(file.getPath());
|
||||
if (assem != null) {
|
||||
assemblies += assem;
|
||||
return assem;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try in the current directory
|
||||
val file = new File(".", name);
|
||||
if (file.exists()) {
|
||||
val assem = Assembly.LoadFrom(file.getPath());
|
||||
if (assem != null) {
|
||||
assemblies += assem;
|
||||
return assem;
|
||||
}
|
||||
}
|
||||
global.reporter.error(new Position(null, Position.NOPOS),
|
||||
"cannot find assembly " + name + "; use the -r option to specify its location");
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
/** Load the rest of the assemblies specified with the '-r' option
|
||||
*/
|
||||
private def findAllAssemblies(): Unit = {
|
||||
for (val file <- assemrefs.elements) {
|
||||
if (file.isFile()) {
|
||||
//System.out.println("Loading assembly " + file)
|
||||
val assem = Assembly.LoadFrom(file.getPath());
|
||||
if (assem != null) {
|
||||
assemblies += assem;
|
||||
}
|
||||
}
|
||||
assemrefs -= file;
|
||||
}
|
||||
assert(assemrefs.isEmpty, assemrefs.toString());
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
// collect the members contained in a given namespace
|
||||
|
||||
/** Find the position of the first type whose name starts with
|
||||
* the given prefix; return the length of the types array if no match
|
||||
* is found so the result can be used to terminate loop conditions
|
||||
*/
|
||||
private def findFirst(prefix: String): Int = {
|
||||
var m = 0;
|
||||
var n = alltypes.length - 1;
|
||||
while (m < n) {
|
||||
val l = (m + n) / 2;
|
||||
val res = alltypes(l).FullName.compareTo(prefix);
|
||||
if (res < 0) m = l + 1;
|
||||
else n = l;
|
||||
}
|
||||
if (alltypes(m).FullName.startsWith(prefix)) m else alltypes.length;
|
||||
}
|
||||
|
||||
/** Collects the members contained in the given Scala package (namespace)
|
||||
*/
|
||||
def collectMembers(pakage: Symbol, typesMap: Map[String,Type], namespacesSet: Set[String]) = {
|
||||
val namespace = if (pakage.isRoot) "" else pakage.fullNameString + ".";
|
||||
val nl = namespace.length();
|
||||
var i = findFirst(namespace);
|
||||
while (i < alltypes.length && alltypes(i).FullName.startsWith(namespace)) {
|
||||
val typ = alltypes(i);
|
||||
if (typ.FullName != "java.lang.Object" && typ.FullName != "java.lang.String") {
|
||||
val k = typ.FullName.indexOf(".", nl);
|
||||
if (k < 0) {
|
||||
typesMap.update(typ.Name, typ);
|
||||
} else {
|
||||
namespacesSet += (typ.Namespace.substring(nl, k));
|
||||
}
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
} // CLRTypes
|
|
@ -0,0 +1,506 @@
|
|||
/* NSC -- new scala compiler
|
||||
* Copyright 2004-2006 LAMP/EPFL
|
||||
*/
|
||||
|
||||
// $Id: TypeParser.scala 8734 2006-09-21 14:56:02Z mihaylov $
|
||||
|
||||
package scala.tools.nsc.symtab.clr;
|
||||
|
||||
import scala.tools.nsc.util.Position;
|
||||
import classfile.UnPickler;
|
||||
import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _};
|
||||
|
||||
import scala.collection.mutable.{HashMap, HashSet};
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class TypeParser {
|
||||
|
||||
val global: Global;
|
||||
|
||||
import global._;
|
||||
import loaders.clrTypes;
|
||||
|
||||
//##########################################################################
|
||||
|
||||
private var clazz: Symbol = _;
|
||||
private var instanceDefs: Scope = _; // was members
|
||||
private var staticModule: Symbol = _; // was staticsClass
|
||||
private var staticDefs: Scope = _; // was statics
|
||||
|
||||
protected def statics: Symbol = staticModule.moduleClass
|
||||
|
||||
protected var busy: boolean = false // lock to detect recursive reads
|
||||
|
||||
private object unpickler extends UnPickler {
|
||||
val global: TypeParser.this.global.type = TypeParser.this.global
|
||||
}
|
||||
|
||||
|
||||
def parse(typ: MSILType, root: Symbol): Unit = {
|
||||
|
||||
def handleError(e: Exception) = {
|
||||
if (settings.debug.value) e.printStackTrace(); //debug
|
||||
throw new IOException("type '" + typ.FullName + "' is broken\n(" + e.getMessage() + ")")
|
||||
}
|
||||
assert(!busy)
|
||||
busy = true
|
||||
|
||||
if (root.isModule) {
|
||||
this.clazz = root.linkedClassOfModule
|
||||
this.staticModule = root
|
||||
} else {
|
||||
this.clazz = root
|
||||
this.staticModule = root.linkedModuleOfClass
|
||||
}
|
||||
try {
|
||||
parseClass(typ)
|
||||
} catch {
|
||||
case e: FatalError => handleError(e)
|
||||
case e: RuntimeException => handleError(e)
|
||||
}
|
||||
busy = false
|
||||
}
|
||||
|
||||
private def parseClass(typ: MSILType): Unit = {
|
||||
|
||||
clrTypes.types(clazz) = typ;
|
||||
clrTypes.sym2type(typ) = clazz;
|
||||
|
||||
if (typ.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) {
|
||||
val attrs = typ.GetCustomAttributes(clrTypes.SCALA_SYMTAB_ATTR, false);
|
||||
assert (attrs.length == 1, attrs.length);
|
||||
val a = attrs(0).asInstanceOf[MSILAttribute];
|
||||
assert (a.getConstructor() == clrTypes.SYMTAB_CONSTR);
|
||||
val symtab = a.getConstructorArguments()(0).asInstanceOf[Array[Byte]]
|
||||
unpickler.unpickle(symtab, 0, clazz, staticModule, typ.FullName);
|
||||
val mClass = clrTypes.getType(typ.FullName + "$");
|
||||
if (mClass != null) {
|
||||
clrTypes.types(statics) = mClass;
|
||||
val moduleInstance = mClass.GetField("MODULE$");
|
||||
assert (moduleInstance != null, mClass);
|
||||
clrTypes.fields(statics) = moduleInstance;
|
||||
}
|
||||
return;
|
||||
}
|
||||
val flags = translateAttributes(typ);
|
||||
val ifaces: Array[MSILType] = typ.getInterfaces();
|
||||
val superType = if (typ.BaseType() != null) getCLRType(typ.BaseType())
|
||||
else if (typ.IsInterface()) definitions.ObjectClass.tpe
|
||||
else definitions.AnyClass.tpe; // this is System.Object
|
||||
val parents = superType :: ifaces.map(getCLRType).toList;
|
||||
instanceDefs = newScope;
|
||||
staticDefs = newScope;
|
||||
|
||||
val classInfo = ClassInfoType(parents, instanceDefs, clazz);
|
||||
val staticInfo = ClassInfoType(List(), staticDefs, statics);
|
||||
|
||||
clazz.setFlag(flags);
|
||||
clazz.setInfo(classInfo);
|
||||
statics.setFlag(Flags.JAVA);
|
||||
statics.setInfo(staticInfo);
|
||||
staticModule.setFlag(Flags.JAVA);
|
||||
staticModule.setInfo(statics.tpe);
|
||||
|
||||
// import nested types
|
||||
for (val ntype <- typ.getNestedTypes(); (!(ntype.IsNestedPrivate
|
||||
|| ntype.IsNestedAssembly
|
||||
|| ntype.IsNestedFamANDAssem)
|
||||
|| ntype.IsInterface) )
|
||||
{
|
||||
val loader = new loaders.MSILTypeLoader(ntype)
|
||||
val nclazz = statics.newClass(NoPos, ntype.Name.toTypeName)
|
||||
val nmodule = statics.newModule(NoPos, ntype.Name)
|
||||
nclazz.setInfo(loader)
|
||||
nmodule.setInfo(loader)
|
||||
staticDefs.enter(nclazz)
|
||||
staticDefs.enter(nmodule)
|
||||
|
||||
assert(nclazz.linkedModuleOfClass == nmodule, nmodule);
|
||||
assert(nmodule.linkedClassOfModule == nclazz, nclazz);
|
||||
}
|
||||
|
||||
val fields = typ.getFields();
|
||||
for (val field <- fields; !(field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly)) {
|
||||
val flags = translateAttributes(field);
|
||||
val name = newTermName(field.Name);
|
||||
val fieldType =
|
||||
if (field.IsLiteral && !field.FieldType.IsEnum)
|
||||
ConstantType(getConstant(getCLRType(field.FieldType), field.getValue))
|
||||
else getCLRType(field.FieldType);
|
||||
val owner = if (field.IsStatic()) statics else clazz;
|
||||
val sym = owner.newValue(NoPos, name).setFlag(flags).setInfo(fieldType);
|
||||
// TODO: set private within!!! -> look at typechecker/Namers.scala
|
||||
(if (field.IsStatic()) staticDefs else instanceDefs).enter(sym);
|
||||
clrTypes.fields(sym) = field;
|
||||
}
|
||||
|
||||
for (val constr <- typ.getConstructors(); !constr.IsStatic() && !constr.IsPrivate() &&
|
||||
!constr.IsAssembly() && !constr.IsFamilyAndAssembly())
|
||||
createMethod(constr);
|
||||
|
||||
// initially also contains getters an setters of properties.
|
||||
val methodsSet = new HashSet[MethodInfo]();
|
||||
methodsSet ++= typ.getMethods();
|
||||
|
||||
for (val prop <- typ.getProperties) {
|
||||
val propType: Type = getCLSType(prop.PropertyType);
|
||||
if (propType != null) {
|
||||
val getter: MethodInfo = prop.GetGetMethod(true);
|
||||
val setter: MethodInfo = prop.GetSetMethod(true);
|
||||
var gparamsLength: Int = -1;
|
||||
if (!(getter == null || getter.IsPrivate || getter.IsAssembly
|
||||
|| getter.IsFamilyAndAssembly))
|
||||
{
|
||||
assert(prop.PropertyType == getter.ReturnType);
|
||||
val gparams: Array[ParameterInfo] = getter.GetParameters();
|
||||
gparamsLength = gparams.length;
|
||||
val name: Name = if (gparamsLength == 0) prop.Name else nme.apply;
|
||||
val flags = translateAttributes(getter);
|
||||
val mtype: Type = if (gparamsLength == 0) PolyType(List(), propType)
|
||||
else methodType(getter, getter.ReturnType);
|
||||
val owner: Symbol = if (getter.IsStatic) statics else clazz;
|
||||
val methodSym = owner.newMethod(NoPos, name).setFlag(flags).setInfo(mtype);
|
||||
methodSym.setFlag(Flags.ACCESSOR);
|
||||
(if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym)
|
||||
clrTypes.methods(methodSym) = getter;
|
||||
methodsSet -= getter;
|
||||
}
|
||||
if (!(setter == null || setter.IsPrivate || setter.IsAssembly
|
||||
|| setter.IsFamilyAndAssembly))
|
||||
{
|
||||
val sparams: Array[ParameterInfo] = setter.GetParameters()
|
||||
if(getter != null)
|
||||
assert(getter.IsStatic == setter.IsStatic);
|
||||
assert(setter.ReturnType == clrTypes.VOID);
|
||||
if(getter != null)
|
||||
assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);
|
||||
|
||||
val name: Name = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
|
||||
else nme.update;
|
||||
val flags = translateAttributes(setter);
|
||||
val mtype: Type = methodType(setter, definitions.UnitClass.tpe);
|
||||
val owner: Symbol = if (setter.IsStatic) statics else clazz;
|
||||
val methodSym = owner.newMethod(NoPos, name).setFlag(flags).setInfo(mtype);
|
||||
methodSym.setFlag(Flags.ACCESSOR);
|
||||
(if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym);
|
||||
clrTypes.methods(methodSym) = setter;
|
||||
methodsSet -= setter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* for (val event <- typ.GetEvents) {
|
||||
// adding += and -= methods to add delegates to an event.
|
||||
// raising the event ist not possible from outside the class (this is so
|
||||
// generally in .net world)
|
||||
val adder: MethodInfo = event.GetAddMethod();
|
||||
val remover: MethodInfo = event.GetRemoveMethod();
|
||||
if (!(adder == null || adder.IsPrivate || adder.IsAssembly
|
||||
|| adder.IsFamilyAndAssembly))
|
||||
{
|
||||
assert(adder.ReturnType == clrTypes.VOID);
|
||||
assert(adder.GetParameters().map(.ParameterType).toList == List(event.EventHandlerType));
|
||||
val name = encode("+=");
|
||||
val flags = translateAttributes(adder);
|
||||
val mtype: Type = methodType(adder, adder.ReturnType);
|
||||
createMethod(name, flags, mtype, adder, adder.IsStatic)
|
||||
methodsSet -= adder;
|
||||
}
|
||||
if (!(remover == null || remover.IsPrivate || remover.IsAssembly
|
||||
|| remover.IsFamilyAndAssembly))
|
||||
{
|
||||
assert(remover.ReturnType == clrTypes.VOID);
|
||||
assert(remover.GetParameters().map(.ParameterType).toList == List(event.EventHandlerType));
|
||||
val name = encode("-=");
|
||||
val flags = translateAttributes(remover);
|
||||
val mtype: Type = methodType(remover, remover.ReturnType);
|
||||
createMethod(name, flags, mtype, remover, remover.IsStatic)
|
||||
methodsSet -= remover;
|
||||
}
|
||||
} */
|
||||
|
||||
for (val method <- methodsSet.elements)
|
||||
if (!method.IsPrivate() && !method.IsAssembly() && !method.IsFamilyAndAssembly())
|
||||
createMethod(method);
|
||||
|
||||
|
||||
// Create methods and views for delegate support
|
||||
if (clrTypes.isDelegateType(typ)) {
|
||||
createDelegateView(typ);
|
||||
createDelegateChainers(typ);
|
||||
}
|
||||
|
||||
// create the box/unbox methods for value types
|
||||
if (typ.IsValueType) {
|
||||
val box = statics.newMethod(NoPos, nme.box).
|
||||
setInfo(MethodType(List(clazz.tpe), definitions.ObjectClass.tpe));
|
||||
definitions.isBox += box;
|
||||
definitions.boxMethod(clazz) = box;
|
||||
val unbox = statics.newMethod(NoPos, nme.unbox).
|
||||
setInfo(MethodType(List(definitions.ObjectClass.tpe), clazz.tpe));
|
||||
definitions.isUnbox += unbox;
|
||||
definitions.unboxMethod(clazz) = unbox;
|
||||
//Console.println(typ.FullName + " : " + parents);
|
||||
}
|
||||
|
||||
// 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 (typ.IsEnum) {
|
||||
val ENUM_CMP_NAMES = List(nme.EQ, nme.NE, nme.LT, nme.LE, nme.GT, nme.GE);
|
||||
val ENUM_BIT_LOG_NAMES = List(nme.OR, nme.AND, nme.XOR);
|
||||
|
||||
val flags = Flags.JAVA | Flags.FINAL;
|
||||
for (val cmpName <- ENUM_CMP_NAMES) {
|
||||
val enumCmpType: Type = JavaMethodType(List(clazz.tpe), definitions.BooleanClass.tpe);
|
||||
val enumCmp: Symbol = clazz.newMethod(NoPos, cmpName);
|
||||
enumCmp.setFlag(flags).setInfo(enumCmpType)
|
||||
instanceDefs.enter(enumCmp);
|
||||
}
|
||||
|
||||
for (val bitLogName <- ENUM_BIT_LOG_NAMES) {
|
||||
val enumBitLogType = JavaMethodType(List(clazz.tpe), classInfo);
|
||||
val enumBitLog = clazz.newMethod(NoPos, bitLogName);
|
||||
enumBitLog.setFlag(flags).setInfo(enumBitLogType);
|
||||
instanceDefs.enter(enumBitLog);
|
||||
}
|
||||
}
|
||||
|
||||
} // parseClass
|
||||
|
||||
private def createMethod(method: MethodBase): Unit = {
|
||||
val rettype = if (method.IsConstructor()) clazz.tpe
|
||||
else getCLSType(method.asInstanceOf[MethodInfo].ReturnType);
|
||||
if (rettype == null) return;
|
||||
val mtype = methodType(method, rettype);
|
||||
if (mtype == null) return;
|
||||
val flags = translateAttributes(method);
|
||||
val owner = if (method.IsStatic()) statics else clazz;
|
||||
val methodSym = owner.newMethod(NoPos, getName(method)).setFlag(flags).
|
||||
setInfo(mtype);
|
||||
(if (method.IsStatic()) staticDefs else instanceDefs).enter(methodSym);
|
||||
if (method.IsConstructor())
|
||||
clrTypes.constructors(methodSym) = method.asInstanceOf[ConstructorInfo]
|
||||
else clrTypes.methods(methodSym) = method.asInstanceOf[MethodInfo];
|
||||
}
|
||||
|
||||
private def createMethod(name: Name, flags: Long, args: Array[MSILType], retType: MSILType, method: MethodInfo, statik: Boolean): Symbol = {
|
||||
val mtype: Type = methodType(args, getCLSType(retType));
|
||||
assert(mtype != null);
|
||||
createMethod(name, flags, mtype, method, statik)
|
||||
}
|
||||
|
||||
private def createMethod(name: Name, flags: Long, mtype: Type, method: MethodInfo, statik: Boolean): Symbol = {
|
||||
val methodSym: Symbol = (if (statik) statics else clazz).newMethod(NoPos, name);
|
||||
methodSym.setFlag(flags).setInfo(mtype);
|
||||
(if (statik) staticDefs else instanceDefs).enter(methodSym);
|
||||
if (method != null)
|
||||
clrTypes.methods(methodSym) = method;
|
||||
methodSym
|
||||
}
|
||||
|
||||
private def createDelegateView(typ: MSILType) = {
|
||||
val invoke: MethodInfo = typ.GetMember("Invoke")(0).asInstanceOf[MethodInfo];
|
||||
val invokeRetType: Type = getCLRType(invoke.ReturnType);
|
||||
val invokeParamTypes: List[Type] =invoke.GetParameters().map(.ParameterType).map(getCLSType).toList;
|
||||
val funType: Type = definitions.functionType(invokeParamTypes, invokeRetType);
|
||||
|
||||
val typClrType: Type = getCLRType(typ);
|
||||
val flags = Flags.JAVA | Flags.STATIC | Flags.IMPLICIT; // todo: static? think not needed
|
||||
|
||||
// create the forward view: delegate => function
|
||||
val delegateParamTypes: List[Type] = List(typClrType);
|
||||
// not ImplicitMethodType, this is for methods with implicit parameters (not implicit methods)
|
||||
val forwardViewMethodType = JavaMethodType(delegateParamTypes, funType);
|
||||
val fmsym = createMethod(nme.view_, flags, forwardViewMethodType, null, true);
|
||||
|
||||
// create the backward view: function => delegate
|
||||
val functionParamTypes: List[Type] = List(funType);
|
||||
val backwardViewMethodType = JavaMethodType(functionParamTypes, typClrType);
|
||||
val bmsym = createMethod(nme.view_, flags, backwardViewMethodType, null, true);
|
||||
}
|
||||
|
||||
private def createDelegateChainers(typ: MSILType) = {
|
||||
val flags: Long = Flags.JAVA | Flags.FINAL;
|
||||
val args: Array[MSILType] = Array(typ);
|
||||
|
||||
var s = createMethod(encode("+="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_COMBINE, false);
|
||||
s = createMethod(encode("-="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_REMOVE, false);
|
||||
|
||||
s = createMethod(nme.PLUS, flags, args, typ, clrTypes.DELEGATE_COMBINE, false);
|
||||
s = createMethod(nme.MINUS, flags, args, typ, clrTypes.DELEGATE_REMOVE, false);
|
||||
}
|
||||
|
||||
private def getName(method: MethodBase): Name = {
|
||||
if (method.IsConstructor()) return nme.CONSTRUCTOR;
|
||||
val name = method.Name;
|
||||
if (method.IsStatic()) return newTermName(name);
|
||||
val params = method.GetParameters();
|
||||
name match {
|
||||
case "GetHashCode" if (params.length == 0) => nme.hashCode_;
|
||||
case "ToString" if (params.length == 0) => nme.toString_;
|
||||
case "Finalize" if (params.length == 0) => nme.finalize_;
|
||||
case "Equals" if (params.length == 1 && params(0).ParameterType == clrTypes.OBJECT) =>
|
||||
nme.equals_;
|
||||
case "Invoke" if (clrTypes.isDelegateType(method.DeclaringType)) => nme.apply;
|
||||
case _ => newTermName(name);
|
||||
}
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
|
||||
private def methodType(method: MethodBase, rettype: MSILType): Type = {
|
||||
val rtype = getCLSType(rettype);
|
||||
if (rtype == null) null else methodType(method, rtype);
|
||||
}
|
||||
|
||||
/** Return a method type for the given method. */
|
||||
private def methodType(method: MethodBase, rettype: Type): Type =
|
||||
methodType(method.GetParameters().map(.ParameterType), rettype);
|
||||
|
||||
/** Return a method type for the provided argument types and return type. */
|
||||
private def methodType(argtypes: Array[MSILType], rettype: Type): Type = {
|
||||
def paramType(typ: MSILType): Type =
|
||||
if (typ eq clrTypes.OBJECT) definitions.AnyClass.tpe
|
||||
else getCLSType(typ);
|
||||
val ptypes = argtypes.map(paramType).toList;
|
||||
if (ptypes.contains(null)) null
|
||||
else JavaMethodType(ptypes, rettype);
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
|
||||
private def getClassType(typ: MSILType): Type = {
|
||||
assert(typ != null);
|
||||
val res = definitions.getClass(typ.FullName.replace('+', '.')).tpe;
|
||||
//if (res.isError())
|
||||
// global.reporter.error("unknown class reference " + type.FullName);
|
||||
res
|
||||
}
|
||||
|
||||
private def getCLSType(typ: MSILType): Type = {
|
||||
if (/*type == clrTypes.BYTE ||*/ typ == clrTypes.USHORT
|
||||
|| typ == clrTypes.UINT || typ == clrTypes.ULONG
|
||||
|| typ.IsNotPublic() || typ.IsNestedPrivate()
|
||||
|| typ.IsNestedAssembly() || typ.IsNestedFamANDAssem()
|
||||
|| typ.IsPointer()
|
||||
|| (typ.IsArray() && getCLSType(typ.GetElementType()) == null))
|
||||
null;
|
||||
//Symbol s = clrTypes.getSymbol(type);
|
||||
//scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type);
|
||||
else
|
||||
getCLRType(typ)
|
||||
}
|
||||
|
||||
private def getCLRType(typ: MSILType): Type =
|
||||
if (typ == clrTypes.OBJECT)
|
||||
definitions.ObjectClass.tpe;
|
||||
else if (typ == clrTypes.VALUE_TYPE)
|
||||
definitions.AnyValClass.tpe
|
||||
else if (typ == clrTypes.STRING)
|
||||
definitions.StringClass.tpe;
|
||||
else if (typ == clrTypes.VOID)
|
||||
definitions.UnitClass.tpe
|
||||
else if (typ == clrTypes.BOOLEAN)
|
||||
definitions.BooleanClass.tpe
|
||||
else if (typ == clrTypes.CHAR)
|
||||
definitions.CharClass.tpe
|
||||
else if (typ == clrTypes.BYTE || typ == clrTypes.UBYTE)
|
||||
definitions.ByteClass.tpe
|
||||
else if (typ == clrTypes.SHORT || typ == clrTypes.USHORT)
|
||||
definitions.ShortClass.tpe
|
||||
else if (typ == clrTypes.INT || typ == clrTypes.UINT)
|
||||
definitions.IntClass.tpe
|
||||
else if (typ == clrTypes.LONG || typ == clrTypes.ULONG)
|
||||
definitions.LongClass.tpe
|
||||
else if (typ == clrTypes.FLOAT)
|
||||
definitions.FloatClass.tpe
|
||||
else if (typ == clrTypes.DOUBLE)
|
||||
definitions.DoubleClass.tpe
|
||||
else if (typ.IsArray())
|
||||
appliedType(definitions.ArrayClass.tpe,
|
||||
List(getCLRType(typ.GetElementType())));
|
||||
else {
|
||||
val res = clrTypes.sym2type.get (typ) match {
|
||||
case Some(sym) => sym.tpe
|
||||
case None => getClassType(typ);
|
||||
}
|
||||
assert (res != null, typ)
|
||||
res
|
||||
}
|
||||
|
||||
// the values are Java-Box-Classes (e.g. Integer, Boolean, Character)
|
||||
// java.lang.Number to get the value (if a number, not for boolean, character)
|
||||
// see ch.epfl.lamp.compiler.msil.util.PEStream.java
|
||||
def getConstant(constType: Type, value: Object): Constant = {
|
||||
val typeClass = constType.symbol
|
||||
if (typeClass == definitions.BooleanClass)
|
||||
Constant(value.asInstanceOf[java.lang.Boolean].booleanValue)
|
||||
else if (typeClass == definitions.ByteClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].byteValue)
|
||||
else if (typeClass == definitions.ShortClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].shortValue)
|
||||
else if (typeClass == definitions.CharClass)
|
||||
Constant(value.asInstanceOf[java.lang.Character].charValue)
|
||||
else if (typeClass == definitions.IntClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].intValue)
|
||||
else if (typeClass == definitions.LongClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].longValue)
|
||||
else if (typeClass == definitions.FloatClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].floatValue)
|
||||
else if (typeClass == definitions.DoubleClass)
|
||||
Constant(value.asInstanceOf[java.lang.Number].doubleValue)
|
||||
else if (typeClass == definitions.StringClass)
|
||||
Constant(value.asInstanceOf[java.lang.String])
|
||||
else
|
||||
abort("illegal value: " + value + ", class-symbol: " + typeClass)
|
||||
}
|
||||
|
||||
private def translateAttributes(typ: MSILType): Long = {
|
||||
var flags: Long = Flags.JAVA;
|
||||
if (typ.IsNotPublic() || typ.IsNestedPrivate()
|
||||
|| typ.IsNestedAssembly() || typ.IsNestedFamANDAssem())
|
||||
flags = flags | Flags.PRIVATE;
|
||||
else if (typ.IsNestedFamily() || typ.IsNestedFamORAssem())
|
||||
flags = flags | Flags.PROTECTED;
|
||||
if (typ.IsAbstract())
|
||||
flags = flags | Flags.ABSTRACT;
|
||||
if (typ.IsSealed())
|
||||
flags = flags | Flags.FINAL;
|
||||
if (typ.IsInterface())
|
||||
flags = flags | Flags.INTERFACE | Flags.TRAIT | Flags.ABSTRACT;
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
private def translateAttributes(field: FieldInfo): Long = {
|
||||
var flags: Long = Flags.JAVA;
|
||||
if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly())
|
||||
flags = flags | Flags.PRIVATE;
|
||||
else if (field.IsFamily() || field.IsFamilyOrAssembly())
|
||||
flags = flags | Flags.PROTECTED;
|
||||
if (field.IsInitOnly())
|
||||
flags = flags | Flags.FINAL;
|
||||
else
|
||||
flags = flags | Flags.MUTABLE;
|
||||
if (field.IsStatic)
|
||||
flags = flags | Flags.STATIC
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
private def translateAttributes(method: MethodBase): Long = {
|
||||
var flags: Long = Flags.JAVA;
|
||||
if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly())
|
||||
flags = flags | Flags.PRIVATE;
|
||||
else if (method.IsFamily() || method.IsFamilyOrAssembly())
|
||||
flags = flags | Flags.PROTECTED;
|
||||
if (method.IsAbstract())
|
||||
flags = flags | Flags.DEFERRED;
|
||||
if (method.IsStatic)
|
||||
flags = flags | Flags.STATIC
|
||||
|
||||
flags
|
||||
}
|
||||
}
|
|
@ -69,7 +69,7 @@ abstract class CleanUp extends Transform {
|
|||
}
|
||||
|
||||
override def transformUnit(unit: CompilationUnit) =
|
||||
if (settings.target.value != "jvm-1.5") {
|
||||
if (settings.target.value != "jvm-1.5" && !forMSIL) {
|
||||
unit.body = transform(unit.body)
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
else apply(parents.head)
|
||||
case ClassInfoType(parents, decls, clazz) =>
|
||||
ClassInfoType(
|
||||
if ((clazz == ObjectClass) || (isValueClass(clazz))) List()
|
||||
if ((clazz == ObjectClass) || (isValueType(clazz))) List()
|
||||
else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass))
|
||||
else removeDoubleObject(parents map this),
|
||||
decls, clazz)
|
||||
|
@ -308,7 +308,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
}
|
||||
else gen.mkAttributedCast(tree, pt)
|
||||
} else gen.mkAttributedCast(tree, pt)
|
||||
|
||||
|
||||
/** Is symbol a member of unboxed arrays (which will be expanded directly
|
||||
* later)?
|
||||
*
|
||||
|
@ -330,10 +330,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
*/
|
||||
private def adaptToType(tree: Tree, pt: Type): Tree = {
|
||||
if (settings.debug.value && pt != WildcardType)
|
||||
log("adapting " + tree + ":" + tree.tpe + " to " + pt)//debug
|
||||
if (tree.tpe <:< pt)
|
||||
log("adapting " + tree + ":" + tree.tpe + " : " + tree.tpe.parents + " to " + pt)//debug
|
||||
if (tree.tpe <:< pt)
|
||||
tree
|
||||
else if (isUnboxedClass(tree.tpe.symbol) && !isUnboxedClass(pt.symbol))
|
||||
else if (isUnboxedClass(tree.tpe.symbol) && !isUnboxedClass(pt.symbol))
|
||||
adaptToType(box(tree), pt)
|
||||
else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.paramTypes.isEmpty) {
|
||||
assert(tree.symbol.isStable);
|
||||
|
@ -403,6 +403,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
* </ul>
|
||||
*/
|
||||
private def adaptMember(tree: Tree): Tree = {
|
||||
//Console.println("adaptMember: " + tree);
|
||||
tree match {
|
||||
case Apply(Select(New(tpt), name), args) if (tpt.tpe.symbol == BoxedArrayClass) =>
|
||||
assert(name == nme.CONSTRUCTOR);
|
||||
|
@ -417,7 +418,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
if (isNumericValueClass(qualClass) && isNumericValueClass(targClass))
|
||||
// convert numeric type casts
|
||||
atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List()))
|
||||
else if (isValueClass(targClass) ||
|
||||
else if (isValueType(targClass) ||
|
||||
(targClass == ArrayClass && (qualClass isNonBottomSubClass BoxedArrayClass)))
|
||||
unbox(qual1, targ.tpe)
|
||||
else if (targClass == ArrayClass && qualClass == ObjectClass)
|
||||
|
@ -435,10 +436,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
|
|||
adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, name))))
|
||||
else {
|
||||
var qual1 = typedQualifier(qual);
|
||||
if ((isValueClass(qual1.tpe.symbol) && !isUnboxedValueMember(tree.symbol)) ||
|
||||
if ((isValueType(qual1.tpe.symbol) && !isUnboxedValueMember(tree.symbol)) ||
|
||||
(qual1.tpe.symbol == ArrayClass && !isUnboxedArrayMember(tree.symbol)))
|
||||
qual1 = box(qual1);
|
||||
else if (!isValueClass(qual1.tpe.symbol) && isUnboxedValueMember(tree.symbol))
|
||||
else if (!isValueType(qual1.tpe.symbol) && isUnboxedValueMember(tree.symbol))
|
||||
qual1 = unbox(qual1, tree.symbol.owner.tpe)
|
||||
else if (tree.symbol.owner == ArrayClass && qual1.tpe.symbol == ObjectClass)
|
||||
qual1 = cast(qual1, BoxedArrayClass.tpe)
|
||||
|
|
|
@ -243,7 +243,7 @@ trait SyntheticMethods requires Analyzer {
|
|||
// jw-04-2003/jw-0425-designpatterns_p.html)
|
||||
if (!hasImplementation(nme.readResolve)) ts += readResolveMethod
|
||||
}
|
||||
if (!forCLDC)
|
||||
if (!forCLDC && !forMSIL)
|
||||
for (val sym <- clazz.info.decls.toList)
|
||||
if (!sym.getAttributes(BeanPropertyAttr).isEmpty)
|
||||
if (sym.isGetter)
|
||||
|
|
|
@ -639,6 +639,14 @@ trait Typers requires Analyzer {
|
|||
// (13); the condition prevents chains of views
|
||||
if (settings.debug.value) log("inferring view from "+tree.tpe+" to "+pt)
|
||||
val coercion = inferView(tree.pos, tree.tpe, pt, true)
|
||||
// convert forward views of delegate types into closures wrapped around
|
||||
// the delegate's apply method (the "Invoke" method, which was translated into apply)
|
||||
if (forMSIL && coercion != null && isCorrespondingDelegate(tree.tpe, pt)) {
|
||||
val meth: Symbol = tree.tpe.member(nme.apply)
|
||||
if(settings.debug.value)
|
||||
log("replacing forward delegate view with: " + meth + ":" + meth.tpe)
|
||||
return typed(Select(tree, meth), mode, pt)
|
||||
}
|
||||
if (coercion != EmptyTree) {
|
||||
if (settings.debug.value) log("inferred view from "+tree.tpe+" to "+pt+" = "+coercion+":"+coercion.tpe)
|
||||
return typed(Apply(coercion, List(tree)) setPos tree.pos, mode, pt)
|
||||
|
@ -1187,7 +1195,7 @@ trait Typers requires Analyzer {
|
|||
* @return ...
|
||||
*/
|
||||
def typedFunction(fun: Function, mode: int, pt: Type): Tree = {
|
||||
val codeExpected = !forCLDC && (pt.symbol isNonBottomSubClass CodeClass)
|
||||
val codeExpected = !forCLDC && !forMSIL && (pt.symbol isNonBottomSubClass CodeClass)
|
||||
|
||||
def decompose(pt: Type): {Symbol, List[Type], Type} =
|
||||
if (isFunctionType(pt)
|
||||
|
@ -1361,6 +1369,28 @@ trait Typers requires Analyzer {
|
|||
case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
|
||||
case _ => tp
|
||||
}
|
||||
|
||||
// Replace the Delegate-Chainer methods += and -= with corresponding
|
||||
// + and - calls, which are translated in the code generator into
|
||||
// Combine and Remove
|
||||
if (forMSIL) {
|
||||
fun match {
|
||||
case Select(qual, name) =>
|
||||
if (isSubType(qual.tpe, definitions.DelegateClass.tpe)
|
||||
&& (name == encode("+=") || name == encode("-=")))
|
||||
{
|
||||
val n = if (name == encode("+=")) nme.PLUS else nme.MINUS
|
||||
val f = Select(qual, n)
|
||||
// the compiler thinks, the PLUS method takes only one argument,
|
||||
// but he thinks it's an instance method -> still two ref's on the stack
|
||||
// -> translated by backend
|
||||
val rhs = copy.Apply(tree, f, args)
|
||||
return typed(Assign(qual, rhs))
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
if (fun.symbol == List_apply && args.isEmpty) {
|
||||
atPos(tree.pos) { gen.mkNil setType restpe }
|
||||
} else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) {
|
||||
|
@ -2007,7 +2037,23 @@ trait Typers requires Analyzer {
|
|||
case PolyType(_, MethodType(formals, _)) =>
|
||||
adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
|
||||
case MethodType(formals, _) =>
|
||||
adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
|
||||
expr1 match {
|
||||
case Select(qual, name) =>
|
||||
if(forMSIL && pt != WildcardType && pt != ErrorType && isSubType(pt, definitions.DelegateClass.tpe)) {
|
||||
val scalaCaller = newScalaCaller(pt);
|
||||
addScalaCallerInfo(scalaCaller, expr1.symbol)
|
||||
val n: Name = scalaCaller.name
|
||||
val del = Ident(DelegateClass) setType DelegateClass.tpe
|
||||
val f = Select(del, n)
|
||||
//val f1 = TypeApply(f, List(Ident(pt.symbol) setType pt))
|
||||
val args: List[Tree] = if(expr1.symbol.isStatic) List(Literal(Constant(null)))
|
||||
else List(qual) // where the scala-method is located
|
||||
val rhs = Apply(f, args);
|
||||
return typed(rhs)
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
|
||||
case ErrorType =>
|
||||
expr1
|
||||
case _ =>
|
||||
|
|
|
@ -204,7 +204,7 @@ object Console {
|
|||
*/
|
||||
def readLine(text: String, args: Any*): String = {
|
||||
format(text, args: _*)
|
||||
in.readLine()
|
||||
readLine
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +212,7 @@ object Console {
|
|||
*
|
||||
* @return the boolean value read from the terminal.
|
||||
*/
|
||||
def readBoolean: Boolean = in.readLine().toLowerCase() match {
|
||||
def readBoolean: Boolean = readLine.toLowerCase() match {
|
||||
case "true" => true
|
||||
case "t" => true
|
||||
case "yes" => true
|
||||
|
@ -252,7 +252,7 @@ object Console {
|
|||
* @return a list of all extracted values.
|
||||
*/
|
||||
def readf(format: String): List[Any] =
|
||||
textComponents(new MessageFormat(format).parse(in.readLine()))
|
||||
textComponents(new MessageFormat(format).parse(readLine))
|
||||
|
||||
/** Read in some structured input, specified by a format specifier.
|
||||
* Opposed to <code>readf</code>, this function only returns the
|
||||
|
|
|
@ -45,7 +45,7 @@ abstract class Enumeration(initial: Int, names: String*) {
|
|||
def this(names: String*) = this(0, names: _*)
|
||||
|
||||
def name = {
|
||||
val cname = compat.Platform.getClassName(this)
|
||||
val cname = this.getClass().getName()
|
||||
if (cname.endsWith("$"))
|
||||
cname.substring(0, cname.length() - 1)
|
||||
else if (cname.endsWith("$class"))
|
||||
|
|
|
@ -26,15 +26,12 @@ object Platform {
|
|||
def createArray(elemClass: Class, length: Int): AnyRef =
|
||||
java.lang.reflect.Array.newInstance(elemClass, length)
|
||||
|
||||
def getClass(obj: AnyRef) = obj.getClass()
|
||||
def getClassName(obj: AnyRef) = obj.getClass().getName()
|
||||
def getName(cls: Class) = cls.getName()
|
||||
def getElementClass(obj: AnyRef) = obj.getClass().getComponentType()
|
||||
def getClassForName(name: String): Class = java.lang.Class.forName(name)
|
||||
|
||||
val EOL = System.getProperty("line.separator", "\n")
|
||||
|
||||
def currentTime: Long = System.currentTimeMillis()
|
||||
|
||||
def collectGarbage: Unit = System.gc()
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ package scala.runtime
|
|||
|
||||
|
||||
import Predef.Class
|
||||
import compat.Platform.{createArray, getElementClass}
|
||||
import compat.Platform.createArray
|
||||
|
||||
[serializable]
|
||||
final class BoxedObjectArray(val value: Array[AnyRef]) extends BoxedArray {
|
||||
|
@ -36,7 +36,7 @@ final class BoxedObjectArray(val value: Array[AnyRef]) extends BoxedArray {
|
|||
override def hashCode(): Int = value.hashCode()
|
||||
|
||||
private def create(length: Int): Array[AnyRef] = {
|
||||
createArray(getElementClass(value), length).asInstanceOf[Array[AnyRef]]
|
||||
createArray(value.getClass().getComponentType(), length).asInstanceOf[Array[AnyRef]]
|
||||
}
|
||||
|
||||
override def subArray(start: Int, end: Int): Array[AnyRef] = {
|
||||
|
|
|
@ -16,7 +16,6 @@ import scala.util.regexp.Base
|
|||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.immutable
|
||||
import compat.Platform
|
||||
|
||||
/** this turns a regexp over A into a NondetWorkAutom over A using the
|
||||
* celebrated position automata construction (also called Berry-Sethi or
|
||||
|
@ -64,7 +63,7 @@ abstract class BaseBerrySethi {
|
|||
tmp
|
||||
case Star(t) => compFirst(t)
|
||||
case _ =>
|
||||
throw new IllegalArgumentException("unexpected pattern " + Platform.getClass(r))
|
||||
throw new IllegalArgumentException("unexpected pattern " + r.getClass())
|
||||
}
|
||||
|
||||
/** computes last( r ) for the regexp r */
|
||||
|
@ -89,7 +88,7 @@ abstract class BaseBerrySethi {
|
|||
tmp
|
||||
case Star(t) => compLast(t)
|
||||
case _ =>
|
||||
throw new IllegalArgumentException("unexpected pattern " + Platform.getClass(r))
|
||||
throw new IllegalArgumentException("unexpected pattern " + r.getClass())
|
||||
}
|
||||
|
||||
/** Starts from the right-to-left
|
||||
|
@ -170,7 +169,7 @@ abstract class BaseBerrySethi {
|
|||
first
|
||||
|
||||
case _ =>
|
||||
throw new IllegalArgumentException("unexpected pattern: " + Platform.getClass(r))
|
||||
throw new IllegalArgumentException("unexpected pattern: " + r.getClass())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +192,7 @@ abstract class BaseBerrySethi {
|
|||
case Star(t) =>
|
||||
traverse(t)
|
||||
case _ =>
|
||||
throw new IllegalArgumentException("unexp pattern " + Platform.getClass(r))
|
||||
throw new IllegalArgumentException("unexp pattern " + r.getClass())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
//############################################################################
|
||||
// $Id$
|
||||
|
||||
import scala.compat.StringBuilder;
|
||||
|
||||
object M0 {
|
||||
class Rational(x: Int, y: Int) {
|
||||
def numer = x;
|
||||
|
@ -230,10 +232,10 @@ object M8 {
|
|||
def intersect2(that: IntSet): IntSet = filter(x => that.contains(x));
|
||||
def filter(f: Int => Boolean): IntSet = filter0(f, new Empty);
|
||||
|
||||
def printOn(out: java.io.PrintStream) = foreach(out.println);
|
||||
def print() = foreach(Console.println);
|
||||
|
||||
override def toString(): String = {
|
||||
val buffer: java.lang.StringBuffer = new java.lang.StringBuffer();
|
||||
val buffer: StringBuilder = new StringBuilder();
|
||||
buffer.append('[');
|
||||
foreach(i => {
|
||||
if (buffer.length() > 1) {buffer.append(','); ()}; // !!! ; ()
|
||||
|
@ -312,7 +314,7 @@ object M8 {
|
|||
Console.println;
|
||||
|
||||
Console.println("set4 contains the following elements:");
|
||||
set4.printOn(java.lang.System.out);
|
||||
set4.print();
|
||||
Console.println;
|
||||
|
||||
Console.println("2 <- set2: " + (set2 contains 2));
|
||||
|
|
|
@ -359,9 +359,9 @@ trait Bug266BB extends Bug266BA {
|
|||
val in = 3;
|
||||
}
|
||||
|
||||
object Bug266BTest extends Application {
|
||||
val a: Bug266BA1 = new Bug266BA1 with Bug266BB;
|
||||
a.mkP.f(a.in);
|
||||
object Bug266BTest {
|
||||
val a: Bug266BA1 = new Bug266BA1 with Bug266BB;
|
||||
def test(args: Array[String]): Unit = a.mkP.f(a.in);
|
||||
}
|
||||
|
||||
// main
|
||||
|
@ -369,7 +369,7 @@ object Bug266BTest extends Application {
|
|||
object Bug266Test {
|
||||
def test(args: Array[String]): Unit = {
|
||||
Bug266ATest.test(args);
|
||||
Bug266BTest;
|
||||
Bug266BTest.test(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,9 +412,9 @@ trait Bug396C extends Bug396A {
|
|||
override def run = { super.run; Console.println("C"); }
|
||||
}
|
||||
}
|
||||
object Bug396Test extends Application with Bug396B with Bug396C {
|
||||
object Bug396Test extends Bug396B with Bug396C {
|
||||
class I2 extends super[Bug396B].I with super[Bug396C].I;
|
||||
(new I2).run
|
||||
def test(args: Array[String]): Unit = (new I2).run
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
|
@ -478,7 +478,7 @@ object Test {
|
|||
test(266, Bug266Test.test(args));
|
||||
test(316, Bug316Test.test(args));
|
||||
test(328, Bug328Test.test(args));
|
||||
test(396, Bug396Test);
|
||||
test(396, Bug396Test.test(args));
|
||||
test(399, Bug399Test.test(args));
|
||||
|
||||
if (errors > 0) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
RichCharTest1:
|
||||
True
|
||||
True
|
||||
True
|
||||
False
|
||||
|
||||
RichIntTest:
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
0
|
||||
0
|
||||
|
||||
RichStringTest1:
|
||||
s1: abc
|
||||
s2: abc\txyz\n
|
||||
s3: abc
|
||||
xyz
|
||||
s4: abc
|
||||
|xyz
|
||||
s5: abc
|
||||
#xyz
|
||||
|
||||
RichStringTest2:
|
||||
s1: abc
|
||||
s2: abc\txyz\n
|
||||
s3: abc
|
||||
xyz
|
||||
s4: abc
|
||||
|xyz
|
||||
s5: abc
|
||||
#xyz
|
||||
|
||||
RichStringTest3:
|
||||
s1: abc
|
||||
s2: abc\txyz\n
|
||||
s3: abc
|
||||
xyz
|
||||
s4: abc
|
||||
|xyz
|
||||
s5: abc
|
||||
#xyz
|
||||
|
||||
RichStringTest4:
|
||||
s1: abc
|
||||
s2: abc\txyz\n
|
||||
s3: abc
|
||||
xyz
|
||||
s4: abc
|
||||
xyz
|
||||
s5: abc
|
||||
#xyz
|
||||
|
||||
RichStringTest5:
|
||||
s1: abc
|
||||
xyz
|
||||
s2: abc
|
||||
xyz
|
||||
s3: abc
|
||||
xyz
|
||||
s4: abc
|
||||
|xyz
|
||||
s5: abc
|
||||
xyz
|
|
@ -5,9 +5,6 @@ true
|
|||
true
|
||||
true
|
||||
|
||||
RichCharTest2:
|
||||
true
|
||||
|
||||
RichIntTest:
|
||||
10
|
||||
11
|
||||
|
|
|
@ -8,7 +8,7 @@ trait RichTest {
|
|||
val s5 = """abc
|
||||
#xyz"""
|
||||
def getObjectName: String = {
|
||||
val cn = compat.Platform.getClassName(this)
|
||||
val cn = this.getClass().getName()
|
||||
cn.substring(0, cn.length-1)
|
||||
}
|
||||
def length[A](it: Iterator[A]) = it.toList length
|
||||
|
@ -23,24 +23,24 @@ object RichCharTest1 extends RichTest {
|
|||
Console.println('A'.asDigit == 10)
|
||||
}
|
||||
}
|
||||
object RichCharTest2 extends RichTest {
|
||||
case class C(s: String) {
|
||||
private val it = s.elements
|
||||
private var c: Char = _
|
||||
def ch(): Char = c
|
||||
def nextch(): Unit = { c = if (it.hasNext) it.next else ';' }
|
||||
def err(msg: String) = Console.println(msg)
|
||||
nextch()
|
||||
}
|
||||
def run {
|
||||
Console.println("\n" + getObjectName + ":")
|
||||
val c1 = C("x4A;")
|
||||
val s1 = xml.Utility.parseCharRef(c1.ch, c1.nextch, c1.err)
|
||||
val c2 = C("74;")
|
||||
val s2 = xml.Utility.parseCharRef(c2.ch, c2.nextch, c2.err)
|
||||
Console.println(s1 == s2)
|
||||
}
|
||||
}
|
||||
// object RichCharTest2 extends RichTest {
|
||||
// case class C(s: String) {
|
||||
// private val it = s.elements
|
||||
// private var c: Char = _
|
||||
// def ch(): Char = c
|
||||
// def nextch(): Unit = { c = if (it.hasNext) it.next else ';' }
|
||||
// def err(msg: String) = Console.println(msg)
|
||||
// nextch()
|
||||
// }
|
||||
// def run {
|
||||
// Console.println("\n" + getObjectName + ":")
|
||||
// val c1 = C("x4A;")
|
||||
// val s1 = xml.Utility.parseCharRef(c1.ch, c1.nextch, c1.err)
|
||||
// val c2 = C("74;")
|
||||
// val s2 = xml.Utility.parseCharRef(c2.ch, c2.nextch, c2.err)
|
||||
// Console.println(s1 == s2)
|
||||
// }
|
||||
// }
|
||||
object RichIntTest extends RichTest {
|
||||
private val n = 10
|
||||
private val m = -2
|
||||
|
@ -107,7 +107,7 @@ object RichStringTest5 extends RichTest {
|
|||
object Test {
|
||||
def main(args: Array[String]): Unit = {
|
||||
RichCharTest1.run
|
||||
RichCharTest2.run
|
||||
//RichCharTest2.run
|
||||
RichIntTest.run
|
||||
RichStringTest1.run
|
||||
RichStringTest2.run
|
||||
|
|
|
@ -43,12 +43,12 @@ object Test extends AnyRef with Application {
|
|||
def try4 = {
|
||||
if (instance == null) {
|
||||
instance = try {
|
||||
new String();
|
||||
} catch {
|
||||
"" //new String();
|
||||
} catch {
|
||||
case _ =>
|
||||
val cs = "aaa";
|
||||
if (cs.length() > 0) {
|
||||
new String();
|
||||
"" //new String();
|
||||
} else {
|
||||
throw new Error("fatal error");
|
||||
null
|
||||
|
|
|
@ -687,9 +687,9 @@ fi;
|
|||
|
||||
SCALA="${BIN_DIR}scala";
|
||||
if [ "$USEFSC" = "true" ]; then
|
||||
SCALAC="${BIN_DIR}fsc -deprecation -encoding iso-8859-1";
|
||||
SCALAC="${BIN_DIR}fsc -nowarn -deprecation -encoding iso-8859-1";
|
||||
else
|
||||
SCALAC="${BIN_DIR}scalac -deprecation -encoding iso-8859-1";
|
||||
SCALAC="${BIN_DIR}scalac -nowarn -deprecation -encoding iso-8859-1";
|
||||
fi;
|
||||
SCALAP="scalap";
|
||||
ANT="ant";
|
||||
|
|
Loading…
Reference in New Issue