diff options
author | Martin Odersky <odersky@gmail.com> | 2003-08-25 15:26:29 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-08-25 15:26:29 +0000 |
commit | 1cfdffddd1d0d8d71426ef6c1b43aba3e9187561 (patch) | |
tree | dff7c39b217d268626af1014bb972d90036ec031 | |
parent | 4f8b58c0aed01c7a2659963ab658e5dd4239d9c4 (diff) | |
download | scala-1cfdffddd1d0d8d71426ef6c1b43aba3e9187561.tar.gz scala-1cfdffddd1d0d8d71426ef6c1b43aba3e9187561.tar.bz2 scala-1cfdffddd1d0d8d71426ef6c1b43aba3e9187561.zip |
*** empty log message ***
-rw-r--r-- | doc/reference/ScalaReference.tex | 554 | ||||
-rw-r--r-- | sources/scalac/ast/TreeGen.java | 25 | ||||
-rw-r--r-- | sources/scalac/ast/TreeInfo.java | 22 | ||||
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 15 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/PackageParser.java | 44 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 33 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 9 | ||||
-rw-r--r-- | sources/scalac/typechecker/DeSugarize.java | 2 | ||||
-rw-r--r-- | sources/scalac/util/Debug.java | 2 |
9 files changed, 373 insertions, 333 deletions
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex index e45bf98d64..f252db3c25 100644 --- a/doc/reference/ScalaReference.tex +++ b/doc/reference/ScalaReference.tex @@ -3473,254 +3473,11 @@ object HelloWord { } \end{lstlisting} -\appendix -\chapter{Scala Syntax Summary} - -The lexical syntax of Scala is given by the following grammar in EBNF -form. - -\begin{lstlisting} - upper ::= `A' | $\ldots$ | `Z' | `$\Dollar$' | `_' - lower ::= `a' | $\ldots$ | `z' - letter ::= upper | lower - digit ::= `0' | $\ldots$ | `9' - special ::= $\mbox{\rm\em ``all other characters except parentheses ([{}]) and periods''}$ - - op ::= special {special} [`_' [id]] - varid ::= lower {letter | digit} [`_' [id]] - id ::= upper {letter | digit} [`_' [id]] - | varid - | op - - intLit ::= $\mbox{\rm\em ``as in Java''}$ - floatLit ::= $\mbox{\rm\em ``as in Java''}$ - charLit ::= $\mbox{\rm\em ``as in Java''}$ - stringLit ::= $\mbox{\rm\em ``as in Java''}$ - symbolLit ::= `\'' id - - comment ::= `/*' ``any sequence of characters'' `*/' - | `//' `any sequence of characters up to end of line'' -\end{lstlisting} - -The context-free syntax of Scala is given by the following EBNF -grammar. - -\begin{lstlisting} - literal ::= intLit - | floatLit - | charLit - | stringLit - | symbolLit - - StableId ::= id - | Path `.' id - Path ::= StableId - | [id `.'] this - | [id '.'] super [`[' id `]']`.' id - - Type ::= Type1 `=>' Type - | `(' [Types] `)' `=>' Type - | Type1 - Type1 ::= SimpleType {with SimpleType} [Refinement] - SimpleType ::= SimpleType TypeArgs - | SimpleType `#' id - | StableId - | Path `.' type - | `(' Type ')' - TypeArgs ::= `[' Types `]' - Types ::= Type {`,' Type} - Refinement ::= `{' [RefineStat {`;' RefineStat}] `}' - RefineStat ::= Dcl - | type TypeDef {`,' TypeDef} - | - - Exprs ::= Expr {`,' Expr} - Expr ::= [Bindings `=>'] Expr - | if `(' Expr `)' Expr [[`;'] else Expr] - | try `{' block `}' [catch Expr] [finally Expr] - | do Expr [`;'] while `(' Expr ')' - | for `(' Enumerators `)' (do | yield) Expr - | [SimpleExpr `.'] id `=' Expr - | SimpleExpr ArgumentExpr `=' Expr - | PostfixExpr [`:' Type1] - PostfixExpr ::= InfixExpr [id] - InfixExpr ::= PrefixExpr - | InfixExpr id InfixExpr - PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr - SimpleExpr ::= literal - | true - | false - | null - | Path - | `(' [Expr] `)' - | BlockExpr - | new Template - | SimpleExpr `.' id - | id `#' id - | SimpleExpr TypeArgs - | SimpleExpr ArgumentExpr - ArgumentExpr ::= `(' Expr ')' - | BlockExpr - BlockExpr ::= `{' CaseClause {CaseClause} `}' - | `{' Block `}' - Block ::= {BlockStat `;'} [Expr] - - Enumerators ::= Generator {`;' Enumerator} - Enumerator ::= Generator - | Expr - Generator ::= val Pattern `<-' Expr - Block ::= {BlockStat `;'} [Expr] - BlockStat ::= Import - | Def - | {LocalModifier} ClsDef - | Expr - | - - CaseClause ::= case Pattern [`if' PostfixExpr] `=>' Block - - Constr ::= StableId [TypeArgs] [`(' [Exprs] `)'] - - Pattern ::= TreePattern { `|' TreePattern } - - TreePattern ::= varid `:' Type - | `_' `:' Type - | SimplePattern [ '*' | '?' | '+' ] - | SimplePattern { id SimplePattern } - - SimplePattern ::= varid [ '@' SimplePattern ] - | `_' - | literal - | StableId [ `(' [Patterns] `)' ] - | `(' Patterns `)' - | - - Patterns ::= Pattern {`,' Pattern} - - TypeParamClause ::= `[' TypeParam {`,' TypeParam} `]' - FunTypeParamClause ::= `[' TypeDcl {`,' TypeDcl} `]' - TypeParam ::= [`+' | `-'] TypeDcl - ParamClause ::= `(' [Param {`,' Param}] `)' - Param ::= [def] id `:' Type [`*'] - Bindings ::= id [`:' Type1] - | `(' Binding {`,' Binding `)' - Binding ::= id [`:' Type] - - Modifier ::= LocalModifier - | private - | protected - | override - LocalModifier ::= abstract - | final - | sealed - - Template ::= Constr {`with' Constr} [TemplateBody] - TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}' - TemplateStat ::= Import - | {Modifier} Def - | {Modifier} Dcl - | Expr - | - - Import ::= import ImportExpr {`,' ImportExpr} - ImportExpr ::= StableId `.' (id | `_' | ImportSelectors) - ImportSelectors ::= `{' {ImportSelector `,'} - (ImportSelector | `_') `}' - ImportSelector ::= id [`=>' id | `=>' `_'] - - Dcl ::= val ValDcl {`,' ValDcl} - | var VarDcl {`,' VarDcl} - | def FunDcl {`,' FunDcl} - | type TypeDcl {`,' TypeDcl} - ValDcl ::= id `:' Type - VarDcl ::= id `:' Type - FunDcl ::= id [FunTypeParamClause] {ParamClause} `:' Type - TypeDcl ::= id [`>:' Type] [`<:' Type] - - Def ::= val PatDef {`,' PatDef} - | var VarDef {`,' VarDef} - | def FunDef {`,' FunDef} - | type TypeDef {`,' TypeDef} - | ClsDef - PatDef ::= Pattern `=' Expr - VarDef ::= id [`:' Type] `=' Expr - | id `:' Type `=' `_' - FunDef ::= id [FunTypeParamClause] {ParamClause} - [`:' Type] `=' Expr - | this ParamClause `=' ConstrExpr - TypeDef ::= id [TypeParamClause] `=' Type - ClsDef ::= ([case] class | trait) ClassDef {`,' ClassDef} - | [case] object ObjectDef {`,' ObjectDef} - ClassDef ::= id [TypeParamClause] [ParamClause] - [`:' SimpleType] ClassTemplate - ObjectDef ::= id [`:' SimpleType] ClassTemplate - ClassTemplate ::= extends Template - | TemplateBody - | - ConstrExpr ::= this ArgumentExpr - | `{' {BlockStat `;'} ConstrExpr `}' - - CompilationUnit ::= [package QualId `;'] {TopStat `;'} TopStat - TopStat ::= {Modifier} ClsDef - | Import - | Packaging - | - Packaging ::= package QualId `{' {TopStat `;'} TopStat `}' - QualId ::= id {`.' id} -\end{lstlisting} - -\end{document} - -\chapter{Local Type Inference} -\label{sec:local-type-inf} - -This needs to be specified in detail. -Essentially, similar to what is done for GJ. - -\comment{ -\section{Definitions} - -For a possibly recursive definition such as $\LET;x_1 = e_1 -;\ldots; \LET x_n = e_n$, local type inference proceeds as -follows. -A first phase assigns {\em a-priori types} to the $x_i$. The a-priori -type of $x$ is the declared type of $x$ if a declared type is -given. Otherwise, it is the inherited type, if one is -given. Otherwise, it is undefined. - -A second phase assigns completely defined types to the $x_i$, in some -order. The type of $x$ is the a-priori type, if it is completely -defined. Otherwise, it is the a-priori type of $x$'s right hand side. -The a-priori type of an expression $e$ depends on the form of $e$. -\begin{enumerate} -\item -The a-priori type of a -typed expression $e:T$ is $T$. -\item -The a-priori type of a class instance -creation expression $c;\WITH;(b)$ is $C;\WITH;R$ where $C$ is the -type of the class given in $c$ and $R$ is the a-priori type of block -$b$. -\item -The a-priori type of a block is a record consisting the a-priori -types of each non-private identifier which is declared in the block -and which is visible at in last statement of the block. Here, it is -required that every import clause $\IMPORT;e_1 \commadots e_n$ refers -to expressions whose type can be computed with the type information -determined so far. Otherwise, a compile time error results. -\item -The a-priori type of any other expression is the expression's type, if -that type can be computed with the type information determined so far. -Otherwise, a compile time error results. -\end{enumerate} -The compiler will find an ordering in which types are assigned without -compiler errors to all variables $x_1 \commadots x_n$, if such an -ordering exists. This can be achieved by lazy evaluation. -} - \chapter{The Scala Standard Library} The Scala standard library consists of the package \code{scala} with a -number of classes and modules. +number of classes and modules. Some of these classes are described in +the following. \section{Root Classes} \label{sec:cls-root} @@ -3729,17 +3486,15 @@ number of classes and modules. The root of the Scala class hierarchy is formed by class \code{Any}. Every class in a Scala execution environment inherits directly or -indirectly from this class. Class \code{Any} has exactly two direct +indirectly from this class. Class \code{Any} has two direct subclasses: \code{AnyRef} and\code{AnyVal}. The subclass \code{AnyRef} represents all values which are represented -as objects in the underlying host system. The type of the \code{null} -value copnforms to every subclass of \code{AnyRef}. A direct subclass -of -\code{AnyRef} is class \code{Object}. Every user-defined Scala -class inherits directly or indirectly from this class. Classes written -in other languages still inherit from \code{scala.AnyRef}, but not -necessarily from \code{scala.Object}. +as objects in the underlying host system. A subclass of \code{AnyRef} +is class \code{Object}. Every user-defined Scala class inherits +directly or indirectly from this class. Classes written in other +languages still inherit from \code{scala.AnyRef}, but not necessarily +from \code{scala.Object}. The class \code{AnyVal} has a fixed number subclasses, which describe values which are not implemented as objects in the underlying host @@ -3755,46 +3510,49 @@ The standard interfaces of these root classes is described by the following definitions. \begin{lstlisting} -abstract class Any with { - /** Get runtime type descriptor */ - def getType: Type = $\ldots$ +abstract class Any { /** Reference equality */ - def eq (that: Any): Boolean = $\ldots$ + final def eq(that: Any): boolean = $\ldots$ - /** Hash code */ - def def hashCode: Int = $\ldots$ -\end{lstlisting} -\begin{lstlisting} - /** Type test */ - def is [a]: Boolean = $\ldots$ - - /** Type cast */ - def as[a]: a = if (is[a]) $\ldots$ else new CastException() throw + /** Defined equality */ + def equals(that: Any): boolean = this eq that; /** Semantic equality between values of same type */ - def == (that: Any): Boolean = this equals that + final def == (that: Any): boolean = this equals that /** Semantic inequality between values of same type */ - def != (that: Any): Boolean = !(this == that) + final def != (that: Any): boolean = !(this == that) - /** Semantic equality between arbitrary values */ - def equals (that: Any): Boolean = $\ldots$ + /** Hash code */ + def hashCode: Int = $\ldots$ - /** Representation as string */ - def toString: String = getType.toString ++ "@" ++ hashCode + /** Textual representation */ + def toString(): String = $\ldots$ - /** Concatenation of string representations */ - final def + (that: Any) = toString.concat(that) + /** Type test */ + def isInstanceOf[a]: Boolean = $\ldots$ + + /** Type cast */ + def asInstanceOf[a]: a = + if (isInstanceOf[a]) $\ldots$ + else if (this eq null) this + else new ClassCastException().throw + + /** Pattern match */ + def match[a](cases: Any => a): a = cases(this); - /** Pattern matching application */ - final def match [a] (f: (Any)a): a = f(this) + /** Representation as string */ + def toString(): String = $\ldots$ } final class AnyVal extends Any class AnyRef extends Any class Object extends AnyRef \end{lstlisting} +\section{Class String} + + \section{Value Classes} \label{sec:cls-value} @@ -4262,6 +4020,250 @@ module Array { } \end{lstlisting} } + +\appendix +\chapter{Scala Syntax Summary} + +The lexical syntax of Scala is given by the following grammar in EBNF +form. + +\begin{lstlisting} + upper ::= `A' | $\ldots$ | `Z' | `$\Dollar$' | `_' + lower ::= `a' | $\ldots$ | `z' + letter ::= upper | lower + digit ::= `0' | $\ldots$ | `9' + special ::= $\mbox{\rm\em ``all other characters except parentheses ([{}]) and periods''}$ + + op ::= special {special} [`_' [id]] + varid ::= lower {letter | digit} [`_' [id]] + id ::= upper {letter | digit} [`_' [id]] + | varid + | op + + intLit ::= $\mbox{\rm\em ``as in Java''}$ + floatLit ::= $\mbox{\rm\em ``as in Java''}$ + charLit ::= $\mbox{\rm\em ``as in Java''}$ + stringLit ::= $\mbox{\rm\em ``as in Java''}$ + symbolLit ::= `\'' id + + comment ::= `/*' ``any sequence of characters'' `*/' + | `//' `any sequence of characters up to end of line'' +\end{lstlisting} + +The context-free syntax of Scala is given by the following EBNF +grammar. + +\begin{lstlisting} + literal ::= intLit + | floatLit + | charLit + | stringLit + | symbolLit + + StableId ::= id + | Path `.' id + Path ::= StableId + | [id `.'] this + | [id '.'] super [`[' id `]']`.' id + + Type ::= Type1 `=>' Type + | `(' [Types] `)' `=>' Type + | Type1 + Type1 ::= SimpleType {with SimpleType} [Refinement] + SimpleType ::= SimpleType TypeArgs + | SimpleType `#' id + | StableId + | Path `.' type + | `(' Type ')' + TypeArgs ::= `[' Types `]' + Types ::= Type {`,' Type} + Refinement ::= `{' [RefineStat {`;' RefineStat}] `}' + RefineStat ::= Dcl + | type TypeDef {`,' TypeDef} + | + + Exprs ::= Expr {`,' Expr} + Expr ::= [Bindings `=>'] Expr + | if `(' Expr `)' Expr [[`;'] else Expr] + | try `{' block `}' [catch Expr] [finally Expr] + | do Expr [`;'] while `(' Expr ')' + | for `(' Enumerators `)' (do | yield) Expr + | [SimpleExpr `.'] id `=' Expr + | SimpleExpr ArgumentExpr `=' Expr + | PostfixExpr [`:' Type1] + PostfixExpr ::= InfixExpr [id] + InfixExpr ::= PrefixExpr + | InfixExpr id InfixExpr + PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr + SimpleExpr ::= literal + | true + | false + | null + | Path + | `(' [Expr] `)' + | BlockExpr + | new Template + | SimpleExpr `.' id + | id `#' id + | SimpleExpr TypeArgs + | SimpleExpr ArgumentExpr + ArgumentExpr ::= `(' Expr ')' + | BlockExpr + BlockExpr ::= `{' CaseClause {CaseClause} `}' + | `{' Block `}' + Block ::= {BlockStat `;'} [Expr] + + Enumerators ::= Generator {`;' Enumerator} + Enumerator ::= Generator + | Expr + Generator ::= val Pattern `<-' Expr + Block ::= {BlockStat `;'} [Expr] + BlockStat ::= Import + | Def + | {LocalModifier} ClsDef + | Expr + | + + CaseClause ::= case Pattern [`if' PostfixExpr] `=>' Block + + Constr ::= StableId [TypeArgs] [`(' [Exprs] `)'] + + Pattern ::= TreePattern { `|' TreePattern } + + TreePattern ::= varid `:' Type + | `_' `:' Type + | SimplePattern [ '*' | '?' | '+' ] + | SimplePattern { id SimplePattern } + + SimplePattern ::= varid [ '@' SimplePattern ] + | `_' + | literal + | StableId [ `(' [Patterns] `)' ] + | `(' Patterns `)' + | + + Patterns ::= Pattern {`,' Pattern} + + TypeParamClause ::= `[' TypeParam {`,' TypeParam} `]' + FunTypeParamClause ::= `[' TypeDcl {`,' TypeDcl} `]' + TypeParam ::= [`+' | `-'] TypeDcl + ParamClause ::= `(' [Param {`,' Param}] `)' + Param ::= [def] id `:' Type [`*'] + Bindings ::= id [`:' Type1] + | `(' Binding {`,' Binding `)' + Binding ::= id [`:' Type] + + Modifier ::= LocalModifier + | private + | protected + | override + LocalModifier ::= abstract + | final + | sealed + + Template ::= Constr {`with' Constr} [TemplateBody] + TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}' + TemplateStat ::= Import + | {Modifier} Def + | {Modifier} Dcl + | Expr + | + + Import ::= import ImportExpr {`,' ImportExpr} + ImportExpr ::= StableId `.' (id | `_' | ImportSelectors) + ImportSelectors ::= `{' {ImportSelector `,'} + (ImportSelector | `_') `}' + ImportSelector ::= id [`=>' id | `=>' `_'] + + Dcl ::= val ValDcl {`,' ValDcl} + | var VarDcl {`,' VarDcl} + | def FunDcl {`,' FunDcl} + | type TypeDcl {`,' TypeDcl} + ValDcl ::= id `:' Type + VarDcl ::= id `:' Type + FunDcl ::= id [FunTypeParamClause] {ParamClause} `:' Type + TypeDcl ::= id [`>:' Type] [`<:' Type] + + Def ::= val PatDef {`,' PatDef} + | var VarDef {`,' VarDef} + | def FunDef {`,' FunDef} + | type TypeDef {`,' TypeDef} + | ClsDef + PatDef ::= Pattern `=' Expr + VarDef ::= id [`:' Type] `=' Expr + | id `:' Type `=' `_' + FunDef ::= id [FunTypeParamClause] {ParamClause} + [`:' Type] `=' Expr + | this ParamClause `=' ConstrExpr + TypeDef ::= id [TypeParamClause] `=' Type + ClsDef ::= ([case] class | trait) ClassDef {`,' ClassDef} + | [case] object ObjectDef {`,' ObjectDef} + ClassDef ::= id [TypeParamClause] [ParamClause] + [`:' SimpleType] ClassTemplate + ObjectDef ::= id [`:' SimpleType] ClassTemplate + ClassTemplate ::= extends Template + | TemplateBody + | + ConstrExpr ::= this ArgumentExpr + | `{' {BlockStat `;'} ConstrExpr `}' + + CompilationUnit ::= [package QualId `;'] {TopStat `;'} TopStat + TopStat ::= {Modifier} ClsDef + | Import + | Packaging + | + Packaging ::= package QualId `{' {TopStat `;'} TopStat `}' + QualId ::= id {`.' id} +\end{lstlisting} + +\end{document} + +\chapter{Local Type Inference} +\label{sec:local-type-inf} + +This needs to be specified in detail. +Essentially, similar to what is done for GJ. + +\comment{ +\section{Definitions} + +For a possibly recursive definition such as $\LET;x_1 = e_1 +;\ldots; \LET x_n = e_n$, local type inference proceeds as +follows. +A first phase assigns {\em a-priori types} to the $x_i$. The a-priori +type of $x$ is the declared type of $x$ if a declared type is +given. Otherwise, it is the inherited type, if one is +given. Otherwise, it is undefined. + +A second phase assigns completely defined types to the $x_i$, in some +order. The type of $x$ is the a-priori type, if it is completely +defined. Otherwise, it is the a-priori type of $x$'s right hand side. +The a-priori type of an expression $e$ depends on the form of $e$. +\begin{enumerate} +\item +The a-priori type of a +typed expression $e:T$ is $T$. +\item +The a-priori type of a class instance +creation expression $c;\WITH;(b)$ is $C;\WITH;R$ where $C$ is the +type of the class given in $c$ and $R$ is the a-priori type of block +$b$. +\item +The a-priori type of a block is a record consisting the a-priori +types of each non-private identifier which is declared in the block +and which is visible at in last statement of the block. Here, it is +required that every import clause $\IMPORT;e_1 \commadots e_n$ refers +to expressions whose type can be computed with the type information +determined so far. Otherwise, a compile time error results. +\item +The a-priori type of any other expression is the expression's type, if +that type can be computed with the type information determined so far. +Otherwise, a compile time error results. +\end{enumerate} +The compiler will find an ordering in which types are assigned without +compiler errors to all variables $x_1 \commadots x_n$, if such an +ordering exists. This can be achieved by lazy evaluation. +} \section{Exceptions} \label{sec:exceptions} diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 36729e3270..e3c2315005 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -659,6 +659,7 @@ public class TreeGen implements Kinds, Modifiers { return Block(new Tree[]{classDef, alloc}); } + public Tree mkPartialFunction(int pos, Tree applyVisitor, Tree isDefinedAtVisitor, Type pattype, Type restype, Symbol owner) { Type pft = definitions.partialFunctionType(pattype, restype); @@ -688,8 +689,12 @@ public class TreeGen implements Kinds, Modifiers { meth.setInfo(Type.MethodType(new Symbol[]{param}, restype)); clazz.info().members().enter(meth); changeOwner(visitor, prevOwner, meth); - Tree body = Apply( - Select(Ident(param), definitions.MATCH), new Tree[]{visitor}) + Tree body = + Apply( + TypeApply( + Select(Ident(param), definitions.MATCH), + new Tree[]{mkType(pos, pattype), mkType(pos, restype)}), + new Tree[]{visitor}) .setType(restype); return DefDef(meth, body); } @@ -710,4 +715,20 @@ public class TreeGen implements Kinds, Modifiers { }; lifter.traverse(tree); } + + /** Build a postfix function application + */ + public Tree postfixApply(Tree obj, Tree fn, Symbol owner) { + if (TreeInfo.isPureExpr(obj) || TreeInfo.isPureExpr(fn)) { + return Apply(Select(fn, Names.apply), new Tree[]{obj}); + } else { + Name tmpname = global.freshNameCreator.newName("tmp", '$'); + Symbol tmp = new TermSymbol( + obj.pos, tmpname, owner, SYNTHETIC | FINAL) + .setInfo(obj.type); + Tree tmpdef = ValDef(tmp, obj); + Tree expr = postfixApply(Ident(tmp), fn, owner); + return Block(new Tree[]{tmpdef, expr}); + } + } } diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java index 19b2341f44..d0a8b41311 100644 --- a/sources/scalac/ast/TreeInfo.java +++ b/sources/scalac/ast/TreeInfo.java @@ -102,6 +102,10 @@ public class TreeInfo { return tree.symbol().isStable(); case Select(Tree qual, _): return tree.symbol().isStable() && isPureExpr(qual); + case Apply(Tree fn, Tree[] args): + return isPureExpr(fn) && args.length == 0; + case TypeApply(Tree fn, Tree[] targs): + return isPureExpr(fn); case Typed(Tree expr, _): return isPureExpr(expr); case Literal(_): @@ -167,19 +171,27 @@ public class TreeInfo { /** The method symbol of an application node, or Symbol.NONE, if none exists. */ public static Symbol methSymbol(Tree tree) { + Tree meth = methPart(tree); + if (meth.hasSymbol()) return meth.symbol(); + else return Symbol.NONE; + } + + /** The method part of an application node + */ + public static Tree methPart(Tree tree) { switch (tree) { case Apply(Tree fn, _): - return methSymbol(fn); + return methPart(fn); case TypeApply(Tree fn, _): - return methSymbol(fn); + return methPart(fn); case AppliedType(Tree fn, _): - return methSymbol(fn); + return methPart(fn); default: - if (tree.hasSymbol()) return tree.symbol(); - else return Symbol.NONE; + return tree; } } + /** returns true if the tree is a sequence-valued pattern. * precondition: tree is a pattern. * calls isSequenceValued( Tree, List ) because needs to remember bound diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index fcafabc1aa..1cf278c6c0 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -315,10 +315,19 @@ public class Definitions { // add members to class scala.Any MATCH = new TermSymbol( Position.NOPOS, Names.match, ANY_CLASS, Modifiers.FINAL); + Symbol matchTyParam1 = newTypeParameter(MATCH, ANY_TYPE); + Symbol matchTyParam2 = newTypeParameter(MATCH, ANY_TYPE); MATCH.setInfo( - Type.MethodType( - new Symbol[]{newParameter(MATCH, OBJECT_TYPE)}, - OBJECT_TYPE)); + Type.PolyType( + new Symbol[]{matchTyParam1, matchTyParam2}, + Type.MethodType( + new Symbol[]{ + newParameter( + MATCH, + functionType( + new Type[]{matchTyParam1.typeConstructor()}, + matchTyParam2.typeConstructor()))}, + matchTyParam2.typeConstructor()))); ANY_CLASS.members().enter(MATCH); AS = new TermSymbol( diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index 9d62fb1009..842cbd3870 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -42,9 +42,7 @@ public class PackageParser extends Type.LazyType { String dirname = null; Name name = p.fullName(); HashMap/*<Symbol, AbstractFile>*/ symFile = new HashMap(); - if (name.length() == 0) { - // includeMembers(AbstractFile.open(null, "."), p, members, false); - } else { + if (name.length() != 0) { dirname = SourceRepresentation.externalizeFileName(name); if (!dirname.endsWith("/")) dirname += "/"; @@ -53,7 +51,7 @@ public class PackageParser extends Type.LazyType { for (int i = 0; i < base.length; i++) { includeMembers( AbstractFile.open(base[i], dirname), - p, members, dirname != null, symFile); + p, members, symFile); } p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p)); if (dirname == null) @@ -81,9 +79,10 @@ public class PackageParser extends Type.LazyType { * in package/module scope */ protected void includeMembers(AbstractFile dir, Symbol p, Scope locals, - boolean inclClasses, HashMap symFile) { + HashMap symFile) { if (dir == null) return; + boolean inclClasses = p != global.definitions.ROOT_CLASS; String[] filenames = null; try { if ((filenames = dir.list()) == null) @@ -116,33 +115,6 @@ public class PackageParser extends Type.LazyType { } symFile.put(clazz, f); } - } else if (fname.endsWith("/") && !fname.equals("META-INF/")) { - Name n = Name.fromString(fname.substring(0, fname.length() - 1)); - if (locals.lookup(n) == Symbol.NONE) { - TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this); - locals.enter(module); - //todo: moduleClass needs to be entered? - locals.enter(module.moduleClass()); - } - -/* - } else if (inclClasses && fname.endsWith(".symbl")) { - //todo: compare dates between symbl and scala. - Name n = Name.fromString(fname.substring(0, fname.length() - 6)) - .toTypeName(); - Symbol sym = locals.lookup(n); - if (sym == Symbol.NONE || - sym.isPackage() || - sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser && - !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) { - ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion); - //todo: needed - clazz.allConstructors().setInfo(symblCompletion); - clazz.module().setInfo(symblCompletion); - locals.enter(clazz); - locals.enter(clazz.module()); - } -*/ } else if (inclClasses && fname.endsWith(".scala")) { Name n = Name.fromString(fname.substring(0, fname.length() - 6)) .toTypeName(); @@ -157,6 +129,14 @@ public class PackageParser extends Type.LazyType { locals.enter(clazz.module()); symFile.put(clazz, f); } + } else if (fname.endsWith("/") && !fname.equals("META-INF/")) { + Name n = Name.fromString(fname.substring(0, fname.length() - 1)); + if (locals.lookup(n) == Symbol.NONE) { + TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this); + locals.enter(module); + //todo: moduleClass needs to be entered? + locals.enter(module.moduleClass()); + } } } } catch (IOException e) { diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index 3d9d46c9cf..3cae85252a 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -16,7 +16,10 @@ import scalac.ast.*; import scalac.symtab.*; import Tree.*; import scalac.typechecker.DeSugarize ; -/** Make all functions into one-argument functions + +/** (1) Make all functions into one-argument functions + * (2) Convert `def' parameters to closures + * (3) Convert matches with non-visitor arguments to postfix applications */ public class UnCurry extends OwnerTransformer implements Modifiers { @@ -105,14 +108,26 @@ public class UnCurry extends OwnerTransformer Type ftype = fn.type; Tree fn1 = transform(fn); Tree[] args1 = transformArgs(tree.pos, args, ftype); - switch (fn1) { - case Apply(Tree fn2, Tree[] args2): - Tree[] newargs = new Tree[args1.length + args2.length]; - System.arraycopy(args2, 0, newargs, 0, args2.length); - System.arraycopy(args1, 0, newargs, args2.length, args1.length); - return copy.Apply(tree, fn2, newargs); - default: - return copy.Apply(tree, fn1, args1); + if (TreeInfo.methSymbol(fn1) == global.definitions.MATCH && + !(args1[0] instanceof Tree.Visitor)) { + switch (TreeInfo.methPart(fn1)) { + case Select(Tree qual, Name name): + assert name == Names.match; + return gen.postfixApply(qual, args1[0], currentOwner); + default: + throw new ApplicationError("illegal prefix for match: " + tree); + } + + } else { + switch (fn1) { + case Apply(Tree fn2, Tree[] args2): + Tree[] newargs = new Tree[args1.length + args2.length]; + System.arraycopy(args2, 0, newargs, 0, args2.length); + System.arraycopy(args1, 0, newargs, args2.length, args1.length); + return copy.Apply(tree, fn2, newargs); + default: + return copy.Apply(tree, fn1, args1); + } } case Select(_, _): diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 3718e377bb..11b715fe56 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -552,13 +552,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { private Type matchQualType(Tree fn) { switch (fn) { case Select(Tree qual, _): - if (fn.symbol() == definitions.OBJECT_TYPE.lookup(Names.match)) + if (fn.symbol() == definitions.MATCH) return qual.type.widen(); break; case TypeApply(Tree fn1, _): return matchQualType(fn1); case Ident(_): - if (fn.symbol() == definitions.OBJECT_TYPE.lookup(Names.match)) + if (fn.symbol() == definitions.MATCH) return context.enclClass.owner.typeOfThis(); break; } @@ -642,10 +642,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // Entering Symbols ---------------------------------------------------------- Tree transformPackageId(Tree tree) { + if (tree.type != null) return tree; switch (tree) { case Ident(Name name): return tree - .setSymbol(packageSymbol(tree.pos, definitions.ROOT, name)) + .setSymbol(packageSymbol(tree.pos, context.owner, name)) .setType(tree.symbol().type()); case Select(Tree qual, Name name): Tree qual1 = transformPackageId(qual); @@ -2225,7 +2226,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } } - // resolve overloading + // resolve overloading1g switch (fn1.type) { case OverloadedType(Symbol[] alts, Type[] alttypes): try { diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 1de733b798..472b6f0a27 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -61,7 +61,7 @@ public class DeSugarize implements Kinds, Modifiers { // Auxiliary definitions and functions ------------------------------------------- - /** introduce fresh variable of the form "deS$56" + /** introduce fresh variable of the form "ds$56" */ Name getvar() { return freshNameCreator.newName("ds", '$'); diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java index 0ae63c4006..c787c34ac8 100644 --- a/sources/scalac/util/Debug.java +++ b/sources/scalac/util/Debug.java @@ -506,7 +506,7 @@ public class DebugSymbol extends DebugAbstractHandler { public void append1(StringBuffer buffer, Symbol that) { if (that != Symbol.NONE && that != Symbol.ERROR) { - if (that.owner() != Global.instance.definitions.ROOT_CLASS) { + if (!that.owner().isRoot()) { Debug.append(buffer, that.owner()); buffer.append("."); } |