summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2009-10-22 16:14:39 +0000
committerIulian Dragos <jaguarul@gmail.com>2009-10-22 16:14:39 +0000
commitc23174011d44ddf9b405feccf5823d55a6178e06 (patch)
treeec0a7d03bf74db06fedb6f72c3582e20b3e347cc
parent1b7e1feee18b1897f831ccd356b1032c09b203fa (diff)
downloadscala-c23174011d44ddf9b405feccf5823d55a6178e06.tar.gz
scala-c23174011d44ddf9b405feccf5823d55a6178e06.tar.bz2
scala-c23174011d44ddf9b405feccf5823d55a6178e06.zip
Specialized works with Unit and handles correct...
Specialized works with Unit and handles correctly uncheckedVariance annotations.
-rw-r--r--compiler.iml14
-rw-r--r--scala-lang.ipr5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala118
4 files changed, 95 insertions, 45 deletions
diff --git a/compiler.iml b/compiler.iml
index a41887aa3b..72b86fd446 100644
--- a/compiler.iml
+++ b/compiler.iml
@@ -2,20 +2,26 @@
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Scala" name="Scala">
- <configuration />
+ <configuration>
+ <option name="takeFromSettings" value="true" />
+ <option name="myScalaCompilerJarPath" value="$MODULE_DIR$/build/locker/classes/compiler:/localhome/dragos/workspace-laptop/git/scala/lib/fjbg.jar" />
+ <option name="myScalaSdkJarPath" value="$MODULE_DIR$/build/locker/classes/library" />
+ </configuration>
</facet>
</component>
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/build/quick/classes/compiler" />
+ <output-test url="file://$MODULE_DIR$/out/test/compiler" />
<exclude-output />
<content url="file://$MODULE_DIR$/src/compiler">
<sourceFolder url="file://$MODULE_DIR$/src/compiler" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="library" />
+ <orderEntry type="library" name="Scala SDK" level="application" />
<orderEntry type="library" name="Project ant library" level="project" />
- <orderEntry type="library" name="Project Scala SDK" level="project" />
<orderEntry type="library" name="ant" level="application" />
+ <orderEntry type="library" name="Project Scala SDK" level="project" />
</component>
</module>
diff --git a/scala-lang.ipr b/scala-lang.ipr
index eaf94edb96..4cf15390b4 100644
--- a/scala-lang.ipr
+++ b/scala-lang.ipr
@@ -1337,6 +1337,7 @@
</component>
<component name="ProjectDictionaryState">
<dictionary name="odersky" />
+ <dictionary name="dragos" />
</component>
<component name="ProjectFileVersion" converted="true" />
<component name="ProjectKey">
@@ -1507,13 +1508,9 @@
</library>
<library name="Project Scala SDK">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/scala-library.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jline.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/scala-compiler.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/fjbg.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/ScalaCheckHelper.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/ScalaCheck.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/scala-library-src.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/msil.jar!/" />
</CLASSES>
<JAVADOC />
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index a2e30e0cd0..43abc6501d 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1204,8 +1204,7 @@ trait Symbols {
(this.rawInfo ne NoType) && {
val res =
!this.owner.isPackageClass ||
- (this.sourceFile eq null) ||
- (that.sourceFile eq null) ||
+ ((this.sourceFile eq null) && (that.sourceFile eq null)) ||
(this.sourceFile eq that.sourceFile) ||
(this.sourceFile == that.sourceFile)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index aeb54ea02d..d0e92aebd9 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -129,6 +129,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Symbol is a specialized method whose body should be the target's method body. */
case class Implementation(target: Symbol) extends SpecializedInfo
+ /** An Inner class that specializes on a type parameter of the enclosing class. */
+ case class SpecializedInnerClass(target: Symbol, env: TypeEnv) extends SpecializedInfo
+
/** Symbol is a normalized member of 'target'. */
case class NormalizedMember(target: Symbol) extends SpecializedInfo {
@@ -233,6 +236,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
lazy val primitiveTypes = Map(
+ "Unit" -> definitions.UnitClass.tpe,
"Boolean" -> definitions.BooleanClass.tpe,
"Byte" -> definitions.ByteClass.tpe,
"Short" -> definitions.ShortClass.tpe,
@@ -517,22 +521,32 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
m.resetFlag(PRIVATE)
specVal.resetFlag(PRIVATE)
}
+ } else if (m.isClass) {
+ val specClass: Symbol = m.cloneSymbol(cls).setFlag(SPECIALIZED)
+ typeEnv(specClass) = fullEnv
+ specClass.name = specializedName(specClass, fullEnv)
+ enterMember(specClass)
+ log("entered specialized class with info " + specClass.fullNameString + ": " + specClass.info)
+ info(specClass) = SpecializedInnerClass(m, fullEnv)
}
}
cls
}
+ log("specializeClass " + clazz.fullNameString)
val decls1 = (clazz.info.decls.toList flatMap { m: Symbol =>
- normalizeMember(m.owner, m, outerEnv) flatMap { normalizedMember =>
- val ms = specializeMember(m.owner, normalizedMember, outerEnv, clazz.info.typeParams)
- if (normalizedMember.isMethod) {
- val newTpe = subst(outerEnv, normalizedMember.info)
- if (newTpe != normalizedMember.info) // only do it when necessary, otherwise the method type might be at a later phase already
- normalizedMember.updateInfo(newTpe) :: ms
- else
+ if (m.isAnonymousClass) List(m) else {
+ normalizeMember(m.owner, m, outerEnv) flatMap { normalizedMember =>
+ val ms = specializeMember(m.owner, normalizedMember, outerEnv, clazz.info.typeParams)
+ if (normalizedMember.isMethod) {
+ val newTpe = subst(outerEnv, normalizedMember.info)
+ if (newTpe != normalizedMember.info) // only do it when necessary, otherwise the method type might be at a later phase already
+ normalizedMember.updateInfo(newTpe) :: ms
+ else
+ normalizedMember :: ms
+ } else
normalizedMember :: ms
- } else
- normalizedMember :: ms
+ }
}
})
@@ -635,12 +649,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val opc = new overridingPairs.Cursor(clazz)
val oms = new mutable.ListBuffer[Symbol]
while (opc.hasNext) {
-// log("\toverriding pairs: " + opc.overridden.fullNameString + ": " + opc.overridden.info
-// + "> " + opc.overriding.fullNameString + ": " + opc.overriding.info)
- if (!specializedTypeVars(opc.overridden.info).isEmpty) {
-// log("\t\tspecializedTVars: " + specializedTypeVars(opc.overridden.info))
+ log("\toverriding pairs: " + opc.overridden.fullNameString + ": " + opc.overridden.info
+ + " overriden by " + opc.overriding.fullNameString + ": " + opc.overriding.info)
+ if (opc.overriding.owner == clazz && !specializedTypeVars(opc.overridden.info).isEmpty) {
+ log("\t\tspecializedTVars: " + specializedTypeVars(opc.overridden.info))
val env = unify(opc.overridden.info, opc.overriding.info, emptyEnv)
- log("\t\tenv: " + env)
+ log("\t\tenv: " + env + "isValid: "
+ + TypeEnv.isValid(env, opc.overridden)
+ + " exists: " + opc.overridden.owner.info.decl(specializedName(opc.overridden, env)))
if (!env.isEmpty
&& TypeEnv.isValid(env, opc.overridden)
&& opc.overridden.owner.info.decl(specializedName(opc.overridden, env)) != NoSymbol) {
@@ -712,12 +728,41 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def subst(env: TypeEnv, decls: List[Symbol]): List[Symbol] =
decls map subst(env)
+ /** Apply the type environment 'env' to the given type. All type
+ * bindings are supposed to be to primitive types. A type variable
+ * that is annotated with 'uncheckedVariance' is mapped to the corresponding
+ * primitive type losing the annotation.
+ */
private def subst(env: TypeEnv, tpe: Type): Type = {
+ class FullTypeMap(from: List[Symbol], to: List[Type]) extends SubstTypeMap(from, to) {
+
+ override def mapOver(tp: Type): Type = tp match {
+ case ClassInfoType(parents, decls, clazz) =>
+ val parents1 = parents mapConserve (this);
+ val decls1 = mapOver(decls.toList);
+ if ((parents1 eq parents) && (decls1 eq decls)) tp
+ else ClassInfoType(parents1, newScope(decls1), clazz)
+ case AnnotatedType(annots, atp, selfsym) =>
+ val annots1 = mapOverAnnotations(annots)
+ val atp1 = this(atp)
+ if ((annots1 eq annots) && (atp1 eq atp)) tp
+ else if (annots1.isEmpty) atp1
+ else if (atp1 ne atp) {
+ val annots2 = annots1.filter(_.atp.typeSymbol != definitions.uncheckedVarianceClass)
+ if (annots2.isEmpty) atp1
+ else AnnotatedType(annots2, atp1, selfsym)
+ } else
+ AnnotatedType(annots1, atp1, selfsym)
+
+ case _ => super.mapOver(tp)
+ }
+ }
// disabled because of bugs in std. collections
//val (keys, values) = env.iterator.toList.unzip
val keys = env.keysIterator.toList
val values = env.valuesIterator.toList
- tpe.subst(keys, values)
+ (new FullTypeMap(keys, values))(tpe)
+// tpe.subst(keys, values)
}
private def subst(env: TypeEnv)(decl: Symbol): Symbol = {
@@ -735,7 +780,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val parents = base map specializedType
PolyType(targs, ClassInfoType(parents, newScope(specializeClass(clazz, typeEnv(clazz))), clazz))
- case ClassInfoType(base, decls, clazz) =>
+ case ClassInfoType(base, decls, clazz) if !clazz.isPackageClass =>
// val parents = base map specializedType
log("transformInfo " + clazz )
val res = ClassInfoType(base map specializedType, newScope(specializeClass(clazz, typeEnv(clazz))), clazz)
@@ -814,9 +859,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Map a specializable method to its value parameter symbols. */
val parameters: mutable.Map[Symbol, List[List[Symbol]]] = new mutable.HashMap
- /** The current fresh name creator. */
- implicit val fresh: FreshNameCreator = unit.fresh
-
/** Collect method bodies that are concrete specialized methods.
*/
class CollectMethodBodies extends Traverser {
@@ -889,8 +931,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case None => super.transform(tree)
}
- case Select(qual, name) if (!symbol.isMethod
- && !specializedTypeVars(symbol.info).isEmpty
+ case Select(qual, name) if (/*!symbol.isMethod
+ &&*/ !specializedTypeVars(symbol.info).isEmpty
&& name != nme.CONSTRUCTOR) =>
val qual1 = transform(qual)
log("checking for unification at " + tree + " with sym.tpe: " + symbol.tpe + " and tree.tpe: " + tree.tpe + " at " + tree.pos.line)
@@ -902,13 +944,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
log("** routing " + tree + " to " + specMember.get.sym.fullNameString + " tree: " + Select(qual1, specMember.get.sym.name))
localTyper.typedOperator(atPos(tree.pos)(Select(qual1, specMember.get.sym.name)))
} else {
- val specMember = qual1.tpe.member(specializedName(symbol, env))
- if (specMember ne NoSymbol) {
+ val specMember = qual1.tpe.member(specializedName(symbol, env))
+ if (specMember ne NoSymbol) {
log("** using spec member " + specMember)
- localTyper.typed(atPos(tree.pos)(Select(qual1, specMember.name)))
- } else
- super.transform(tree)
- }
+ localTyper.typed(atPos(tree.pos)(Select(qual1, specMember.name)))
+ } else
+ super.transform(tree)
+ }
} else
super.transform(tree)
@@ -940,10 +982,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case Implementation(target) =>
assert(body.isDefinedAt(target), "sym: " + symbol.fullNameString + " target: " + target.fullNameString)
// we have an rhs, specialize it
- val tree1 = duplicateBody(ddef, target)
+ val tree1 = duplicateBody(ddef, target)
log("implementation: " + tree1)
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = tree1
- treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs))
+ treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs))
case NormalizedMember(target) =>
log("normalized member " + symbol + " of " + target)
@@ -969,10 +1011,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
List(Literal("boom! you stepped on a bug. This method should never be called.")))))*/
} else {
// we have an rhs, specialize it
- val tree1 = duplicateBody(ddef, target)
+ val tree1 = duplicateBody(ddef, target)
log("implementation: " + tree1)
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = tree1
- treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs))
+ treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs))
}
case SpecialOverload(original, env) =>
@@ -1159,9 +1201,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
mbrs += DefDef(m, Modifiers(m.flags), List(vparams) map (_ map ValDef), EmptyTree)
} else
mbrs += DefDef(m, { paramss => EmptyTree })
- } else {
- assert(m.isValue)
+ } else if (m.isValue) {
mbrs += ValDef(m, EmptyTree).setType(NoType).setPos(m.pos)
+ } else if (m.isClass) {
+// mbrs +=
+// ClassDef(m, Template(m.info.parents map TypeTree, emptyValDef, List())
+// .setSymbol(m.newLocalDummy(m.pos)))
+// log("created synthetic class: " + m.fullNameString)
}
}
mbrs.toList
@@ -1180,10 +1226,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
tree match {
case ClassDef(_, _, _, impl) =>
tree.symbol.info // force specialization
- for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol)
+ for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) {
buf +=
ClassDef(specCls, Template(specCls.info.parents map TypeTree, emptyValDef, List())
.setSymbol(specCls.newLocalDummy(sym1.pos)))
+ log("created synthetic class: " + specCls + " of " + sym1 + " in env: " + env)
+ }
case _ =>
}
log(buf)
@@ -1215,7 +1263,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Cast `tree' to 'pt', unless tpe is a subtype of pt, or pt is Unit. */
def maybeCastTo(pt: Type, tpe: Type, tree: Tree): Tree =
if ((pt == definitions.UnitClass.tpe) || (tpe <:< pt)) {
- //log("no need to cast from " + tpe + " to " + pt)
+ log("no need to cast from " + tpe + " to " + pt)
tree
} else
gen.mkAsInstanceOf(tree, pt)