summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-06-22 10:39:55 +0000
committerMartin Odersky <odersky@gmail.com>2007-06-22 10:39:55 +0000
commit67915c66942365eda284ef0308d74e15cc1daec5 (patch)
tree1653d90005158ff6f918494909a80890111243c7 /src
parent4e18a7e8d40efc59ff9d3c0a87eb04c67343e48d (diff)
downloadscala-67915c66942365eda284ef0308d74e15cc1daec5.tar.gz
scala-67915c66942365eda284ef0308d74e15cc1daec5.tar.bz2
scala-67915c66942365eda284ef0308d74e15cc1daec5.zip
added support for higher-kinded existentials; a...
added support for higher-kinded existentials; added Iterable.toStream
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala129
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala8
-rw-r--r--src/library/scala/Iterable.scala4
6 files changed, 76 insertions, 79 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c65f73ad85..e49153f732 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -665,8 +665,6 @@ trait Parsers {
} else TypeTree()
/** Types ::= Type {`,' Type}
- * ArgTypePats ::= ArgTypePat {`,' ArgTypePat}
- *
* (also eats trailing comma if it finds one)
*/
def types(isPattern: Boolean): List[Tree] = {
@@ -684,60 +682,55 @@ trait Parsers {
private final val LeftOp = 1 // left associative
private final val RightOp = 2 // right associative
- /** Type ::= Type1 [forSome `{' WhereClause {semi WhereClause}} `}']
- * WhereClause ::= type TypeDcl
- * | val ValDcl
- * |
- */
- def typ(): Tree = {
- val t = typ1()
- if (inToken == FORSOME) {
- atPos(inSkipToken) {
- val whereClauses = refinement()
- for (wc <- whereClauses) {
- wc match {
- case TypeDef(_, _, _, TypeBoundsTree(_, _)) | ValDef(_, _, _, EmptyTree) =>
- ;
- case _ =>
- syntaxError(wc.pos, "not a legal where clause", false)
- }
- }
- ExistentialTypeTree(t, whereClauses)
- }
- } else t
- }
-
- /** Type1 ::= InfixType [`=>' Type1]
- * | `(' [`=>' Type] `)' `=>' Type1
+ /** Type ::= InfixType `=>' Type
+ * | `(' [`=>' Type] `)' `=>' Type
+ * | InfixType [ExistentialClause]
+ * ExistentialClause ::= forSome `{' ExistentialDcl {semi ExistentialDcl}} `}'
+ * ExistentialDcl ::= type TypeDcl | val ValDcl
* XXX: Hook for IDE.
*/
- def typ1(): Tree = {
+ def typ(): Tree = {
val t =
if (inToken == LPAREN) {
val pos = inSkipToken
if (inToken == RPAREN) {
inNextToken
- atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ1()) }
+ atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ()) }
} else if (inToken == ARROW) {
inNextToken
- val t0 = typ1()
+ val t0 = typ()
accept(RPAREN)
- atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ1()) }
+ atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ()) }
} else {
val ts = types(false)
accept(RPAREN)
- if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(ts, typ1()) }
- else infixTypeRest(pos, makeTupleType(ts, true), false, FirstOp)
+ if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(ts, typ()) }
+ else infixTypeRest(pos, annotTypeRest(pos, false, makeTupleType(ts, true)), false, FirstOp)
}
} else {
infixType(false, FirstOp)
}
- if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(List(t), typ1()) }
+ if (inToken == ARROW)
+ atPos(inSkipToken) {
+ makeFunctionTypeTree(List(t), typ())
+ }
+ else if (inToken == FORSOME)
+ atPos(inSkipToken) {
+ val whereClauses = refinement()
+ for (wc <- whereClauses) {
+ wc match {
+ case TypeDef(_, _, _, TypeBoundsTree(_, _)) | ValDef(_, _, _, EmptyTree) =>
+ ;
+ case _ =>
+ syntaxError(wc.pos, "not a legal where clause", false)
+ }
+ }
+ ExistentialTypeTree(t, whereClauses)
+ }
else t
}
/** InfixType ::= CompoundType {id [nl] CompoundType}
- * TypePat ::= CompoundTypePat {id [nl] CompoundTypePat
*/
def infixType(isPattern: Boolean, mode: Int): Tree =
infixTypeRest(inCurrentPos, annotType(isPattern), isPattern, mode)
@@ -760,7 +753,6 @@ trait Parsers {
}
/** CompoundType ::= AnnotType {with AnnotType} [Refinement]
- * CompoundTypePat ::= AnnotTypePat {with AnnotTypePat}
*/
def compoundType(isPattern: Boolean): Tree =
compoundTypeRest(inCurrentPos, annotType(isPattern), isPattern)
@@ -784,54 +776,49 @@ trait Parsers {
* | StableId
* | Path `.' type
* | `(' Types [`,'] `)'
- * | `_' TypeBounds
- * AnnotTypePat ::= Annotations SimpleTypePat
- * SimpleTypePat ::= SimpleTypePat1 [TypePatArgs]
- * SimpleTypePat1 ::= SimpleTypePat1 "#" Id
- * | StableId
- * | Path `.' type
- * | `(' ArgTypePats [`,'] `)'
+ * | WildcardType
*/
def annotType(isPattern: Boolean): Tree = {
val annots = annotations()
val pos = inCurrentPos
- var t: Tree =
+
+ val t: Tree = annotTypeRest(pos, isPattern,
if (inToken == LPAREN) {
inNextToken
val ts = types(isPattern)
accept(RPAREN)
atPos(pos) { makeTupleType(ts, true) }
- } else if (inToken == USCORE && !isPattern) {
- val pname = freshName("_$").toTypeName
- val param = atPos(inSkipToken) { makeSyntheticTypeParam(pname, typeBounds()) }
- placeholderTypes = param :: placeholderTypes
- atPos(pos) { Ident(pname) }
+ } else if (inToken == USCORE) {
+ wildcardType(in.skipToken)
} else {
val r = path(false, true)
r match {
case SingletonTypeTree(_) => r
case _ => convertToTypeId(r)
}
- }
-
- // scan for # and []
- var done = false
- while (!done) {
- if (inToken == HASH) {
- t = atPos(inSkipToken) {
- SelectFromTypeTree(t, ident().toTypeName)
- }
- } else if (inToken == LBRACKET) {
- t = atPos(pos) { AppliedTypeTree(t, typeArgs(isPattern)) }
- if (isPattern) done=true
- } else
- done=true
- }
+ })
(t /: annots) (makeAnnotated)
}
+ def annotTypeRest(pos: ScanPosition, isPattern: boolean, t: Tree): Tree =
+ if (inToken == HASH)
+ annotTypeRest(pos, isPattern, atPos(inSkipToken) { SelectFromTypeTree(t, ident().toTypeName) })
+ else if (inToken == LBRACKET)
+ annotTypeRest(pos, isPattern, atPos(pos) { AppliedTypeTree(t, typeArgs(isPattern)) })
+ else
+ t
+
+ /** WildcardType ::= `_' TypeBounds
+ */
+ def wildcardType(pos: ScanPosition) = {
+ val pname = freshName("_$").toTypeName
+ val param = atPos(pos) { makeSyntheticTypeParam(pname, typeBounds()) }
+ placeholderTypes = param :: placeholderTypes
+ Ident(pname) setPos pos
+ }
+
/** TypeArgs ::= `[' ArgType {`,' ArgType} `]'
- * TypePatArgs ::= '[' ArgTypePat {`,' ArgTypePat} `]'
+ * TypePatArgs ::= `[' TypePatArg {`,' TypePatArg} `]'
*/
def typeArgs(isPattern: Boolean): List[Tree] = {
accept(LBRACKET)
@@ -841,16 +828,18 @@ trait Parsers {
}
/** ArgType ::= Type
- * ArgTypePat ::= varid
- * | `_'
- * | Type // for array elements only!
+ * TypePatArg ::= `_'
+ * | varid
*/
def argType(isPattern: Boolean): Tree =
if (isPattern) {
if (inToken == USCORE)
- atPos(inSkipToken) { Bind(nme.WILDCARD.toTypeName, EmptyTree) }
+ if (inToken == SUBTYPE || inToken == SUPERTYPE) wildcardType(inSkipToken)
+ else atPos(inSkipToken) { Bind(nme.WILDCARD.toTypeName, EmptyTree) }
else if (inToken == IDENTIFIER && treeInfo.isVariableName(inName.toTypeName))
- atPos(inCurrentPos) { Bind(ident().toTypeName, EmptyTree) }
+ atPos(inCurrentPos) {
+ Bind(ident().toTypeName, EmptyTree)
+ }
else {
typ()
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 612633bc62..5dd43f1438 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -755,7 +755,7 @@ trait Definitions {
AllClass = newClass(ScalaPackageClass, nme.Nothing, anyparam)
.setFlag(ABSTRACT | TRAIT | FINAL)
- SingletonClass = newClass(RootClass, "<singleton>", anyparam)
+ SingletonClass = newClass(ScalaPackageClass, nme.Singleton, anyparam)
.setFlag(ABSTRACT | TRAIT | FINAL)
StringClass = getClass(if (forMSIL) "System.String" else "java.lang.String")
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 0c0dbb96a8..b11c09b478 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -222,6 +222,7 @@ trait StdNames {
val ScalaRunTime = newTermName("ScalaRunTime")
val Seq = newTermName("Seq")
val Short = newTermName("Short")
+ val Singleton = newTermName("Singleton")
val Some = newTermName("Some")
val SourceFile = newTermName("SourceFile")
val String = newTermName("String")
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 08f76bbdf2..38ab3c7bd8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1468,13 +1468,14 @@ A type's symbol should never be inspected directly.
override def closure = tp.closure map maybeRewrap
override def skolemizeExistential(owner: Symbol, origin: AnyRef) = {
- def mkSkolem(tparam: Symbol) =
- new TypeSkolem(
+ def mkSkolem(tparam: Symbol): Symbol = {
+ val skolem = new TypeSkolem(
if (owner == NoSymbol) tparam.owner else owner,
tparam.pos, tparam.name, origin)
- .setInfo(tparam.info)
- .setFlag(tparam.flags | EXISTENTIAL)
- .resetFlag(PARAM)
+ skolem.setInfo(tparam.info.cloneInfo(skolem))
+ .setFlag(tparam.flags | EXISTENTIAL)
+ .resetFlag(PARAM)
+ }
val skolems = typeParams map mkSkolem
for (skolem <- skolems)
skolem setInfo skolem.info.substSym(typeParams, skolems)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7e486c3439..34f09f6acf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1714,11 +1714,12 @@ trait Typers { self: Analyzer =>
* and in the returned type itself.
*/
protected def existentialTransform(rawSyms: List[Symbol], tp: Type) = {
- val typeParams = rawSyms map { sym =>
+ val typeParams: List[Symbol] = rawSyms map { sym =>
val (name, bound) =
if (sym.isClass)
(sym.name,
- mkTypeBounds(AllClass.tpe, anonymousClassRefinement(sym)))
+ parameterizedType(
+ sym.typeParams, mkTypeBounds(AllClass.tpe, anonymousClassRefinement(sym))))
else if (sym.isAbstractType)
(sym.name,
sym.info)
@@ -1727,7 +1728,8 @@ trait Typers { self: Analyzer =>
mkTypeBounds(AllClass.tpe, intersectionType(List(sym.tpe, SingletonClass.tpe))))
else
throw new Error("unexpected alias type: "+sym)
- sym.owner.newAbstractType(sym.pos, name) setFlag EXISTENTIAL setInfo bound
+ val quantified: Symbol = sym.owner.newAbstractType(sym.pos, name)
+ quantified setFlag EXISTENTIAL setInfo bound.cloneInfo(quantified)
}
val typeParamTypes = typeParams map (_.tpe)
for (tparam <- typeParams) tparam.setInfo(tparam.info.subst(rawSyms, typeParamTypes))
diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala
index 5657a624cd..e7202c035c 100644
--- a/src/library/scala/Iterable.scala
+++ b/src/library/scala/Iterable.scala
@@ -383,6 +383,10 @@ trait Iterable[+A] {
*/
def toList: List[A] = elements.toList
+ /**
+ * Create a stream which contains all the elements of this iterable object.
+ */
+ def toStream: Stream[A] = Stream.fromIterator(elements)
/** Returns a string representation of this iterable object. The resulting string
* begins with the string <code>start</code> and is finished by the string