summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaReference.tex554
-rw-r--r--sources/scalac/ast/TreeGen.java25
-rw-r--r--sources/scalac/ast/TreeInfo.java22
-rw-r--r--sources/scalac/symtab/Definitions.java15
-rw-r--r--sources/scalac/symtab/classfile/PackageParser.java44
-rw-r--r--sources/scalac/transformer/UnCurry.java33
-rw-r--r--sources/scalac/typechecker/Analyzer.java9
-rw-r--r--sources/scalac/typechecker/DeSugarize.java2
-rw-r--r--sources/scalac/util/Debug.java2
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(".");
}