diff options
author | Martin Odersky <odersky@gmail.com> | 2007-06-22 10:39:55 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-06-22 10:39:55 +0000 |
commit | 67915c66942365eda284ef0308d74e15cc1daec5 (patch) | |
tree | 1653d90005158ff6f918494909a80890111243c7 /src | |
parent | 4e18a7e8d40efc59ff9d3c0a87eb04c67343e48d (diff) | |
download | scala-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.scala | 129 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 8 | ||||
-rw-r--r-- | src/library/scala/Iterable.scala | 4 |
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 |