summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLex Spoon <lex@lexspoon.org>2007-01-23 15:34:40 +0000
committerLex Spoon <lex@lexspoon.org>2007-01-23 15:34:40 +0000
commit8acb41bd0a4dc1a6a6e6c20f48cb1c508470551a (patch)
treea65ac192ef81ab0e068e4891654511d5f0ff4982
parent76d0d7ad84a236a5b2fb52e83af158b25b817a85 (diff)
downloadscala-8acb41bd0a4dc1a6a6e6c20f48cb1c508470551a.tar.gz
scala-8acb41bd0a4dc1a6a6e6c20f48cb1c508470551a.tar.bz2
scala-8acb41bd0a4dc1a6a6e6c20f48cb1c508470551a.zip
- Added default constructors for Settings and G...
- Added default constructors for Settings and Global - Added attributed types, if -Xplugtypes is available. This enables non-LAMP people to experiment with type attributes. (This is a merge from the plugtypes branch, revision 9679) The attributes are ignored for now, even with -Xplugtypes, but do get propagated.
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala10
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala13
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala10
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala33
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala36
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala3
-rw-r--r--src/compiler/scala/tools/nsc/models/SemanticTokens.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala105
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Variances.scala2
15 files changed, 223 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 6466a02d8d..03848e7439 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -35,6 +35,16 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
with Trees
with CompilationUnits
{
+ // alternate constructors ------------------------------------------
+ def this(reporter: Reporter) =
+ this(new Settings(err => reporter.error(null,err)),
+ reporter)
+
+ def this(settings: Settings) =
+ this(settings, new ConsoleReporter)
+
+ def this() = this(new Settings, new ConsoleReporter)
+
// sub-components --------------------------------------------------
object treePrinters extends TreePrinters {
val global: Global.this.type = Global.this
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index 16f7acfe45..bde12d3be0 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -10,6 +10,7 @@ import java.lang.System
import java.io.File
class Settings(error: String => unit) {
+ def this() = this(Console.println)
private var allsettings: List[Setting] = List()
@@ -131,6 +132,7 @@ class Settings(error: String => unit) {
val Xunapply = BooleanSetting("-Xunapply", "enable unapply pattern matching")
Xunapply.value = true
val Xplugtypes = BooleanSetting("-Xplugtypes", "parse but ignore annotations in more locations")
+ //Xplugtypes.value = true // just while experimenting
val Xkilloption = BooleanSetting("-Xkilloption", "optimizes option types")
val XprintOuterMatches = BooleanSetting("-XprintOuterMatches", "prints outer-checks caused by pattern matching")
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index ccbc9dd764..ce17c7f1ee 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -353,6 +353,9 @@ abstract class TreeBrowsers {
case TypeTree() =>
Pair("TypeTree", EMPTY)
+ case AttributedTypeTree(attribs, tpt) =>
+ Pair("AttributedTypeTree", EMPTY)
+
case SingletonTypeTree(ref) =>
Pair("SingletonType", EMPTY)
@@ -494,6 +497,9 @@ abstract class TreeBrowsers {
case TypeTree() =>
Nil
+ case AttributedTypeTree(attribs, tpt) =>
+ attribs ::: List(tpt)
+
case SingletonTypeTree(ref) =>
List(ref)
@@ -645,6 +651,13 @@ abstract class TreeBrowsers {
toDocument(result) :: ")")
)
+ case AttributedType(attribs, tp) =>
+ Document.group(
+ Document.nest(4, "AttributedType(" :/:
+ attribs.mkString("[", ",", "]") :/:
+ "," :/: toDocument(tp) :: ")")
+ )
+
case _ =>
abort("Unknown case: " + t.toString())
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 0ba2519e0d..3b3fca377c 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -304,6 +304,16 @@ abstract class TreePrinters {
tree.tpe.toString()
)
+ case AttributedTypeTree(attribs, tree) =>
+ for(val attrib <- attribs) {
+ print("[")
+ print(attrib)
+ print("]")
+ }
+ if(!attribs.isEmpty)
+ print(" ")
+ print(tree)
+
case SingletonTypeTree(ref) =>
print(ref); print(".type")
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 8f21650b13..8df742bd59 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -137,6 +137,9 @@ trait Trees requires Global {
if (hasSymbol) symbol = tree.symbol
this
}
+
+ def withAttributes(attribs: List[Tree]) =
+ AttributedTypeTree(attribs, this)
}
trait SymTree extends Tree {
@@ -153,6 +156,8 @@ trait Trees requires Global {
override def isTerm = true
}
+ /** A tree for a type. Note that not all type trees implement
+ * this trait; in particular, Ident's are an exception. */
trait TypTree extends Tree {
override def isType = true
}
@@ -622,7 +627,11 @@ trait Trees requires Global {
def Literal(value: Any): Literal =
Literal(Constant(value))
- /** General type term, introduced by the phase <code>RefCheck</code>. */
+ /** A synthetic term holding an arbitrary type. Not to be confused with
+ * with TypTree, the trait for trees that are only used for type trees.
+ * TypeTree's are inserted in several places, but most notably in
+ * <code>RefCheck</code>, where the arbitrary type trees are all replaced by
+ * TypeTree's. */
case class TypeTree() extends TypTree {
var original: Tree = _
@@ -630,12 +639,19 @@ trait Trees requires Global {
original = tree
setPos(tree.pos)
}
+
override def isEmpty = (tpe eq null) || tpe == NoType
}
def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
// def TypeTree(tp: Type, tree : Tree): TypeTree = TypeTree(tree) setType tp
+ /** A type tree that has attributes attached to it */
+ case class AttributedTypeTree(attribs: List[Tree], tpt: Tree)
+ extends TypTree {
+ override def withAttributes(attribs: List[Tree]) =
+ AttributedTypeTree(attribs:::this.attribs, this)
+ }
/** Singleton type, eliminated by RefCheck */
case class SingletonTypeTree(ref: Tree)
@@ -697,7 +713,8 @@ trait Trees requires Global {
case Select(qualifier, selector) =>
case Ident(name) =>
case Literal(value) =>
- case TypeTree() =>
+ case TypeTree() => (introduced by refcheck)
+ case AttributedTypeTree(attribs, tpt) => (eliminated by uncurry)
case SingletonTypeTree(ref) => (eliminated by uncurry)
case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry)
case CompoundTypeTree(templ: Template) => (eliminated by uncurry)
@@ -743,6 +760,7 @@ trait Trees requires Global {
def Ident(tree: Tree, name: Name): Ident
def Literal(tree: Tree, value: Constant): Literal
def TypeTree(tree: Tree): TypeTree
+ def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree): AttributedTypeTree
def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree
def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree
@@ -825,6 +843,8 @@ trait Trees requires Global {
new Literal(value).copyAttrs(tree)
def TypeTree(tree: Tree) =
new TypeTree().copyAttrs(tree)
+ def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) =
+ new AttributedTypeTree(attribs, tpt)
def SingletonTypeTree(tree: Tree, ref: Tree) =
new SingletonTypeTree(ref).copyAttrs(tree)
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
@@ -1024,6 +1044,11 @@ trait Trees requires Global {
case t @ TypeTree() => t
case _ => copy.TypeTree(tree)
}
+ def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) = tree match {
+ case t @ AttributedTypeTree(attribs0, tpt0)
+ if (attribs0==attribs) && (tpt0==tpt) => t
+ case _ => copy.AttributedTypeTree(tree, attribs, tpt)
+ }
def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
case t @ SingletonTypeTree(ref0)
if ref0 == ref => t
@@ -1152,6 +1177,8 @@ trait Trees requires Global {
copy.Literal(tree, value)
case TypeTree() =>
copy.TypeTree(tree)
+ case AttributedTypeTree(attribs, tpt) =>
+ copy.AttributedTypeTree(tree, transformTrees(attribs), transform(tpt))
case SingletonTypeTree(ref) =>
copy.SingletonTypeTree(tree, transform(ref))
case SelectFromTypeTree(qualifier, selector) =>
@@ -1288,6 +1315,8 @@ trait Trees requires Global {
;
case TypeTree() =>
;
+ case AttributedTypeTree(attribs, tpt) =>
+ traverseTrees(attribs); traverse(tpt)
case SingletonTypeTree(ref) =>
traverse(ref)
case SelectFromTypeTree(qualifier, selector) =>
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index f0a3808c01..53314b4581 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -648,7 +648,7 @@ trait Parsers requires SyntaxAnalyzer {
* | Path `.' type
* | `(' Type `)'
* | `{' [Type `,' [Types [`,']]] `}'
- * | AttributeClauses SimpleType // if Xplugtypes enabled
+ * | TypeAttributes SimpleType (if -Xplugtypes)
* SimpleTypePattern ::= SimpleTypePattern1 [TypePatternArgs]
* SimpleTypePattern1 ::= SimpleTypePattern1 "#" Id
* | StableId
@@ -656,8 +656,11 @@ trait Parsers requires SyntaxAnalyzer {
* | `{' [ArgTypePattern `,' [ArgTypePatterns [`,']]] `}'
*/
def simpleType(isPattern: boolean): Tree = {
- if(settings.Xplugtypes.value)
- attributeClauses
+ val attribs =
+ if(settings.Xplugtypes.value)
+ typeAttributes
+ else
+ Nil
val pos = in.currentPos
var t: Tree =
@@ -686,18 +689,22 @@ trait Parsers requires SyntaxAnalyzer {
// System.err.println("SIMPLE_TYPE: " + r.pos + " " + r + " => " + x.pos + " " + x)
x
}
- while (true) {
+
+ // scan for # and []
+ var done = false
+ while (!done) {
if (in.token == HASH) {
t = atPos(in.skipToken()) {
SelectFromTypeTree(t, ident().toTypeName)
}
} else if (in.token == LBRACKET) {
t = atPos(pos) { AppliedTypeTree(t, typeArgs(isPattern)) }
- if (isPattern) return t
+ if (isPattern) done=true
} else
- return t
+ done=true
}
- null; //dummy
+
+ t.withAttributes(attribs)
}
/** TypeArgs ::= `[' ArgTypes `]'
@@ -2147,6 +2154,21 @@ trait Parsers requires SyntaxAnalyzer {
defs
}
+ /** TypeAttributes ::= (`[' Exprs `]') *
+ *
+ * Type attributes may be arbitrary expressions.
+ */
+ def typeAttributes: List[Tree] = {
+ val exps = new ListBuffer[Tree]
+ while(in.token == LBRACKET) {
+ accept(LBRACKET)
+ exps ++= argExprs
+ accept(RBRACKET)
+ }
+ exps.toList
+ }
+
+
/** RefineStatSeq ::= RefineStat {StatementSeparator RefineStat}
* RefineStat ::= Dcl
* | type TypeDef
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index dcf98c2493..20c1c190ed 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -401,6 +401,9 @@ trait TypeKinds requires ICodes {
REFERENCE(sym)
}
+ case AttributedType(attribs, tp) =>
+ toTypeKind(tp)
+
case _ =>
abort("Unknown type: " + t)
}
diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
index 3d4b199304..efe79e2baf 100644
--- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
+++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
@@ -354,6 +354,7 @@ class SemanticTokens(val compiler: Global) {
case tpe0 : ThisType => tree match {
case stt : SingletonTypeTree => stt.ref match {
case ths : This => build(ths);
+
case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + unit.source.dbg(tree.pos));
}
case tt : This =>
@@ -476,6 +477,7 @@ class SemanticTokens(val compiler: Global) {
case tree : DocDef => build(tree.definition);
case tree: Import => build(tree.expr)
case tree: AppliedTypeTree => ;
+ case tree: AttributedTypeTree => ;
case tree: SingletonTypeTree => ;
case tree: Super => ;
case tree: Literal => ;
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index b899c04999..3e3d07cb92 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -22,7 +22,6 @@ abstract class AbstractReporter extends Reporter {
var nowarn : Boolean = false;
def displayPrompt : Unit;
- // XXX: while is pos ignored?
protected def info0(pos : Position, msg : String, severity : Severity, force : Boolean) : Unit = severity match {
case INFO => if (force || verbose) display(pos, msg, severity);
case WARNING => {
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index ebef3e87b5..24acb66646 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -29,6 +29,7 @@ import Flags._
case OverloadedType(pre, tparams, alts) =>
case AntiPolyType(pre: Type, targs) =>
case TypeVar(_, _) =>
+ case AttributedType(attribs, tp) =>
*/
trait Types requires SymbolTable {
@@ -47,7 +48,7 @@ trait Types requires SymbolTable {
private var explainSwitch = false
private var checkMalformedSwitch = true
- private var globalVariance = 1//only necessary of healTypes = true?
+ private var globalVariance = 1//only necessary if healTypes = true?
private final val healTypes = false
private final val LubGlbMargin = 0
@@ -55,6 +56,18 @@ trait Types requires SymbolTable {
/** The base class for all types */
abstract class Type {
+ /** Add an attribute to this type */
+ def withAttribute(attrib: Any) = withAttributes(List(attrib))
+
+ /** Add a number of attributes to this type */
+ def withAttributes(attribs: List[Any]): Type =
+ attribs match {
+ case Nil => this
+ case _ => AttributedType(attribs, this)
+ }
+
+ /** Remove any attributes from this type */
+ def withoutAttributes = this
/** Types for which asSeenFrom always is the identity, no matter what
* prefix or owner.
@@ -1069,7 +1082,79 @@ trait Types requires SymbolTable {
override def toString(): String =
if (constr.inst eq null) "<null " + origin + ">"
else if (constr.inst eq NoType) "?" + origin
- else constr.inst.toString();
+ else constr.inst.toString;
+ }
+
+ /** A type carrying some attributes. The attributes have no significance
+ * to the core compiler, but can be observed by type-system plugins. The
+ * core compiler does take care to propagate attributes and to save them
+ * in the symbol tables of object files. */
+ case class AttributedType(attributes: List[Any], tp: Type) extends Type {
+ override def toString(): String = {
+ val attString =
+ if(attributes.isEmpty)
+ ""
+ else
+ attributes.mkString("[", "] [", "] ")
+
+ attString + tp
+ }
+
+
+ /** Add a number of attributes to this type */
+ override def withAttributes(attribs: List[Any]): Type =
+ AttributedType(attribs:::this.attributes, this)
+
+ /** Remove any attributes from this type */
+ override def withoutAttributes = tp.withoutAttributes
+
+ override def isTrivial: boolean = tp.isTrivial
+
+ /** Return the argument, unless it is eq to tp, in which case return the
+ * receiver. This method is used for methods like singleDeref and widen,
+ * so that the attributes are remembered more frequently. */
+ private def maybeRewrap(newtp: Type) =
+ if(newtp eq tp) this else newtp
+
+ // ---------------- methods forwarded to tp ------------------ \\
+
+ override def symbol: Symbol = tp.symbol
+ override def singleDeref: Type = maybeRewrap(tp.singleDeref)
+ override def widen: Type = maybeRewrap(tp.widen)
+ override def deconst: Type = maybeRewrap(tp.deconst)
+ override def bounds: TypeBounds = {
+ val oftp = tp.bounds
+ oftp match {
+ case TypeBounds(lo, hi) if((lo eq this) && (hi eq this)) => TypeBounds(this,this)
+ case _ => oftp
+ }
+ }
+ override def parents: List[Type] = tp.parents
+ override def prefix: Type = tp.prefix
+ override def typeArgs: List[Type] = tp.typeArgs
+ override def resultType: Type = maybeRewrap(tp.resultType)
+ override def finalResultType: Type = maybeRewrap(tp.finalResultType)
+ override def paramSectionCount: int = tp.paramSectionCount
+ override def paramTypes: List[Type] = tp.paramTypes
+ override def typeParams: List[Symbol] = tp.typeParams
+ override def isStable: boolean = tp.isStable
+ override def nonPrivateDecl(name: Name): Symbol = tp.nonPrivateDecl(name)
+ override def baseType(clazz: Symbol): Type = tp.baseType(clazz)
+ override def closure: Array[Type] = {
+ val oftp = tp.closure
+ if((oftp.length == 1 &&) (oftp(0) eq this))
+ Array(this)
+ else
+ oftp
+ }
+ override def closureDepth: int = tp.closureDepth
+ override def baseClasses: List[Symbol] = tp.baseClasses
+ override def cloneInfo(owner: Symbol) = maybeRewrap(cloneInfo(owner))
+ override def isComplete: boolean = tp.isComplete
+ override def complete(sym: Symbol) = tp.complete(sym)
+ override def load(sym: Symbol): unit = tp.load(sym)
+ override def findMember(name: Name, excludedFlags: int, requiredFlags: long, stableOnly: boolean): Symbol =
+ tp.findMember(name, excludedFlags, requiredFlags, stableOnly)
}
/** A class representing an as-yet unevaluated type.
@@ -1077,6 +1162,7 @@ trait Types requires SymbolTable {
abstract class LazyType extends Type {
override def isComplete: boolean = false
override def complete(sym: Symbol): unit
+ override def toString = "LazyType"
}
/** A class representing a lazy type with known type parameters.
@@ -1412,6 +1498,12 @@ trait Types requires SymbolTable {
case TypeVar(_, constr) =>
if (constr.inst != NoType) this(constr.inst)
else tp
+ case AttributedType(attribs, atp) =>
+ val atp1 = this(atp)
+ if(atp1 eq atp)
+ tp
+ else
+ AttributedType(attribs, atp1)
case _ =>
tp
// throw new Error("mapOver inapplicable for " + tp);
@@ -1720,6 +1812,7 @@ trait Types requires SymbolTable {
case TypeBounds(_, _) => mapOver(tp)
case MethodType(_, _) => mapOver(tp)
case TypeVar(_, _) => mapOver(tp)
+ case AttributedType(_,_) => mapOver(tp)
case _ => tp
}
}
@@ -1849,6 +1942,10 @@ trait Types requires SymbolTable {
case Pair(_, TypeVar(_, constr2)) =>
if (constr2.inst != NoType) tp1 =:= constr2.inst
else constr2 instantiate (wildcardToTypeVarMap(tp1))
+ case Pair(AttributedType(_,atp), _) =>
+ isSameType(atp, tp2)
+ case Pair(_, AttributedType(_,atp)) =>
+ isSameType(tp1, atp)
case _ =>
if (tp1.isStable && tp2.isStable) {
var origin1 = tp1
@@ -1951,6 +2048,10 @@ trait Types requires SymbolTable {
case Pair(TypeVar(_, constr1), _) =>
if (constr1.inst != NoType) constr1.inst <:< tp2
else { constr1.hibounds = tp2 :: constr1.hibounds; true }
+ case Pair(AttributedType(_,atp1), _) =>
+ atp1 <:< tp2
+ case Pair(_, AttributedType(_,atp2)) =>
+ tp1 <:< atp2
case Pair(_, TypeRef(pre2, sym2, args2))
if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) =>
true
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 7a9f044064..857f9b9db2 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -144,6 +144,9 @@ abstract class Pickler extends SubComponent {
putType(restpe); putTypes(formals)
case PolyType(tparams, restpe) =>
putType(restpe); putSymbols(tparams)
+ case AttributedType(attribs, tp) =>
+ putType(tp) // the attributes should be stored, but it is not yet
+ // decided how to handle that.
case _ =>
throw new FatalError("bad type: " + tp + "(" + tp.getClass() + ")")
}
@@ -204,7 +207,7 @@ abstract class Pickler extends SubComponent {
/** Write an entry */
private def writeEntry(entry: AnyRef): unit = {
- def writeBody: int = entry match {
+ def writeBody(entry: AnyRef): int = entry match {
case name: Name =>
writeName(name)
if (name.isTermName) TERMname else TYPEname
@@ -268,12 +271,14 @@ abstract class Pickler extends SubComponent {
for (val c <- cs) writeRef(cs);
ATTRIBUTE
*/
+ case AttributedType(attribs, tp)
+ => writeBody(tp) // obviously, this should be improved
case _ =>
throw new FatalError("bad entry: " + entry + " " + entry.getClass())//debug
}
val startpos = writeIndex
writeByte(0); writeByte(0)
- patchNat(startpos, writeBody)
+ patchNat(startpos, writeBody(entry))
patchNat(startpos + 1, writeIndex - (startpos + 2))
}
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index bd6050f99a..9e87b4fee4 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -213,6 +213,8 @@ abstract class LiftCode extends Transform {
if (_log_reify_type_) Console.println("cannot handle MethodType "+tp); null
case PolyType(tparams, result) =>
if (_log_reify_type_) Console.println("cannot handle PolyType "+tp); null;
+ case AttributedType(attribs, tp) =>
+ reify(tp)
case _ =>
null
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 62d2185600..407068299b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -366,6 +366,8 @@ abstract class RefChecks extends InfoTransform {
validateVariance(result, variance)
case PolyType(tparams, result) =>
validateVariance(result, variance)
+ case AttributedType(attribs, tp) =>
+ validateVariance(tp, variance)
}
def validateVariances(tps: List[Type], variance: int): unit =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9faffe5466..aa81ba6de3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2150,6 +2150,11 @@ trait Typers requires Analyzer {
if (value.tag == UnitTag) UnitClass.tpe
else ConstantType(value))
+ case AttributedTypeTree(attribs, tpt) =>
+ attribs.foreach(t => typed(t, EXPRmode, WildcardType))
+ val tptTyped = typed1(tpt, mode, pt)
+ tptTyped setType (tptTyped.tpe.withAttributes(attribs))
+
case SingletonTypeTree(ref) =>
val ref1 = checkStable(typed(ref, EXPRmode | QUALmode, AnyRefClass.tpe))
tree setType ref1.tpe.resultType
@@ -2159,7 +2164,7 @@ trait Typers requires Analyzer {
tree setSymbol sel.symbol setType typedSelect(typedType(qual), selector).tpe
case tree @ CompoundTypeTree(templ: Template) =>
- tree setType {
+ (tree setType {
val parents1 = List.mapConserve(templ.parents)(typedType)
if (parents1 exists (.tpe.isError)) ErrorType
else {
@@ -2168,7 +2173,7 @@ trait Typers requires Analyzer {
newTyper(context.make(templ, self.symbol, decls)).typedRefinement(templ.body)
self
}
- }
+ }) : CompoundTypeTree
case AppliedTypeTree(tpt, args) =>
val tpt1 = typed1(tpt, mode | FUNmode | TAPPmode, WildcardType)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
index 30b89200bb..43e394cd91 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
@@ -79,5 +79,7 @@ trait Variances {
flip(varianceInTypes(formals)(tparam)) & varianceInType(restpe)(tparam)
case PolyType(tparams, restpe) =>
flip(varianceInSyms(tparams)(tparam)) & varianceInType(restpe)(tparam)
+ case AttributedType(attribs, tp) =>
+ varianceInType(tp)(tparam)
}
}