From 6b1d01b1b28d965586a54c1f4c1fe3adfc36545b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 17 Feb 2006 14:17:25 +0000 Subject: --- .../scala/tools/nsc/ast/parser/Parsers.scala | 135 +++++++++++---------- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 2 + .../scala/tools/nsc/backend/jvm/GenJVM.scala | 4 +- .../scala/tools/nsc/symtab/Definitions.scala | 13 +- src/compiler/scala/tools/nsc/symtab/Flags.scala | 1 + src/compiler/scala/tools/nsc/symtab/StdNames.scala | 3 - src/compiler/scala/tools/nsc/symtab/Symbols.scala | 8 +- .../tools/nsc/symtab/classfile/PickleFormat.scala | 2 +- .../scala/tools/nsc/transform/LambdaLift.scala | 25 +++- .../scala/tools/nsc/typechecker/RefChecks.scala | 3 +- .../tools/nsc/typechecker/SyntheticMethods.scala | 50 +++++++- .../scala/tools/nsc/typechecker/Typers.scala | 3 - src/compiler/scala/tools/nsc/util/ClassPath.scala | 2 +- src/library/scala/Function0.scala | 1 + src/library/scala/Function1.scala | 1 + src/library/scala/Function2.scala | 1 + src/library/scala/Function3.scala | 1 + src/library/scala/Function4.scala | 1 + src/library/scala/Function5.scala | 1 + src/library/scala/Function6.scala | 1 + src/library/scala/Function7.scala | 1 + src/library/scala/Function8.scala | 1 + src/library/scala/Function9.scala | 1 + src/library/scala/Predef.scala | 9 ++ src/library/scala/reflect/BeanProperty.scala | 12 ++ test/files/neg/forward.check | 10 ++ test/files/neg/forward.scala | 24 ++++ test/files/pos/bug530.scala | 30 +++++ test/files/pos/bug532.scala | 10 ++ test/files/run/exceptions-2.check | 4 +- 30 files changed, 269 insertions(+), 91 deletions(-) create mode 100644 src/library/scala/reflect/BeanProperty.scala create mode 100644 test/files/neg/forward.check create mode 100755 test/files/neg/forward.scala create mode 100755 test/files/pos/bug530.scala create mode 100644 test/files/pos/bug532.scala diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 467c6acf8b..133c432aef 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -134,8 +134,8 @@ mixin class Parsers requires SyntaxAnalyzer { pos; } - /** SEP = NL | `;' - * NL = `\n' // where allowed + /** StatementSeparator = NewLine | `;' + * NewLine = `\n' // where allowed */ def acceptStatSep(): unit = if (in.token == NEWLINE) in.nextToken() else accept(SEMI); @@ -337,11 +337,11 @@ mixin class Parsers requires SyntaxAnalyzer { Select(t, ident()) } - /** StableRef ::= StableId + /** Path ::= StableId * | [Ident `.'] this - * SimpleType ::= StableRef [`.' type] + * SimpleType ::= Path [`.' type] */ - def stableRef(thisOK: boolean, typeOK: boolean): Tree = { + def path(thisOK: boolean, typeOK: boolean): Tree = { var t: Tree = null; if (in.token == THIS) { t = atPos(in.skipToken()) { This(nme.EMPTY.toTypeName) } @@ -401,11 +401,11 @@ mixin class Parsers requires SyntaxAnalyzer { } /** StableId ::= Id - * | StableRef `.' Id + * | Path `.' Id * | [Id '.'] super [MixinQualifier] ` `.' Id */ def stableId(): Tree = - stableRef(false, false); + path(false, false); /** QualId ::= Id {`.' Id} */ @@ -546,7 +546,7 @@ mixin class Parsers requires SyntaxAnalyzer { /** SimpleType ::= SimpleType TypeArgs * | SimpleType `#' Id * | StableId - * | StableRef `.' type + * | Path `.' type * | `(' Type `)' */ def simpleType(): Tree = { @@ -558,7 +558,7 @@ mixin class Parsers requires SyntaxAnalyzer { accept(RPAREN); t } else { - val r = stableRef(false, true); + val r = path(false, true); val x = r match { case SingletonTypeTree(_) => r case _ => convertToTypeId(r); @@ -611,11 +611,11 @@ mixin class Parsers requires SyntaxAnalyzer { * | Expr1 * ResultExpr ::= Bindings `=>' Block * | Expr1 - * Expr1 ::= if (' Expr `)' [NL] Expr [[`;'] else Expr] + * Expr1 ::= if (' Expr `)' [NewLine] Expr [[`;'] else Expr] * | try `{' block `}' [catch `{' caseClauses `}'] [finally Expr] - * | while `(' Expr `)' [NL] Expr - * | do Expr [SEP] while `(' Expr `)' - * | for (`(' Enumerators `)' | '{' Enumerators '}') [NL] (yield) Expr + * | while `(' Expr `)' [NewLine] Expr + * | do Expr [StatementSeparator] while `(' Expr `)' + * | for (`(' Enumerators `)' | '{' Enumerators '}') [NewLine] (yield) Expr * | throw Expr * | return [Expr] * | [SimpleExpr `.'] Id `=' Expr @@ -742,9 +742,9 @@ mixin class Parsers requires SyntaxAnalyzer { t } - /** PostfixExpr ::= [`.'] InfixExpr [Id [NL]] + /** PostfixExpr ::= [`.'] InfixExpr [Id [NewLine]] * InfixExpr ::= PrefixExpr - * | InfixExpr Id [NL] InfixExpr + * | InfixExpr Id [NewLine] InfixExpr */ def postfixExpr(): Tree = { val base = opstack; @@ -789,7 +789,7 @@ mixin class Parsers requires SyntaxAnalyzer { * | SimpleExpr1 * SimpleExpr1 ::= literal * | xLiteral - * | StableRef + * | Path * | `(' [Expr] `)' * | BlockExpr * | SimpleExpr `.' Id @@ -807,7 +807,7 @@ mixin class Parsers requires SyntaxAnalyzer { t = xmlp.xLiteral; //Console.println("successfully parsed XML at "+t); // DEBUG case IDENTIFIER | THIS | SUPER => - t = stableRef(true, false); + t = path(true, false); case LPAREN => val pos = in.skipToken(); if (in.token == RPAREN) { @@ -927,8 +927,9 @@ mixin class Parsers requires SyntaxAnalyzer { makeCaseDef(pat, guard, atPos(accept(ARROW))(block())) } - /** Enumerators ::= Generator {SEP Enumerator} + /** Enumerators ::= Generator {StatementSeparator Enumerator} * Enumerator ::= Generator + * | val Pattern1 `=' Expr * | Expr */ def enumerators(): List[Enumerator] = { @@ -1175,11 +1176,11 @@ mixin class Parsers requires SyntaxAnalyzer { //////// PARAMETERS ////////////////////////////////////////////////////////// - /** ParamClauses ::= {[NL] `(' [Param {`,' Param}] ')'} - * [[NL] `(' implicit Param {`,' Param} `)'] + /** ParamClauses ::= {[NewLine] `(' [Param {`,' Param}] ')'} + * [[NewLine] `(' implicit Param {`,' Param} `)'] * Param ::= Id `:' ParamType - * ClassParamClauses ::= {[NL] `(' [ClassParam {`' ClassParam}] ')'} - * [[NL] [`(' implicit ClassParam {`,' ClassParam} `)'] + * ClassParamClauses ::= {[NewLine] `(' [ClassParam {`' ClassParam}] ')'} + * [[NewLine] `(' implicit ClassParam {`,' ClassParam} `)'] * ClassParam ::= [[modifiers] (val | var)] Param */ def paramClauses(owner: Name, implicitViews: List[Tree], ofCaseClass: boolean): List[List[ValDef]] = { @@ -1263,10 +1264,10 @@ mixin class Parsers requires SyntaxAnalyzer { } else t } - /** TypeParamClauseOpt ::= [[NL] `[' TypeParam {`,' TypeParam} `]'] - * TypeParam ::= [`+' | `-'] FunTypeParam - * FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]'] - * FunTypeParam ::= Id TypeBounds + /** TypeParamClauseOpt ::= [[NewLine] `[' VariantTypeParam {`,' VariantTypeParam} `]'] + * VariantTypeParam ::= [`+' | `-'] TypeParam + * FunTypeParamClauseOpt ::= [[NewLine] `[' TypeParam {`,' TypeParam} `]'] + * TypeParam ::= Id TypeBounds [<% Type] */ def typeParamClauseOpt(owner: Name, implicitViews: ListBuffer[Tree]): List[AbsTypeDef] = { def typeParam(): AbsTypeDef = { @@ -1400,15 +1401,15 @@ mixin class Parsers requires SyntaxAnalyzer { false } - /** Def ::= val PatDef {`,' PatDef} - * | var VarDef {`,' VatDef} - * | def FunDef {`,' FunDef} - * | type TypeDef {`,' TypeDef} + /** Def ::= val PatDef + * | var VarDef + * | def FunDef + * | type TypeDef * | TmplDef - * Dcl ::= val ValDcl {`,' ValDcl} - * | var ValDcl {`,' ValDcl} - * | def FunDcl {`,' FunDcl} - * | type TypeDcl {`,' TypeDcl} + * Dcl ::= val ValDcl + * | var ValDcl + * | def FunDcl + * | type TypeDcl */ def defOrDcl(mods: Modifiers): List[Tree] = { in.token match { @@ -1519,7 +1520,7 @@ mixin class Parsers requires SyntaxAnalyzer { } /** ConstrExpr ::= SelfInvocation - * | `{' SelfInvocation {SEP BlockStat} `}' + * | `{' SelfInvocation {StatementSeparator BlockStat} `}' * SelfInvocation ::= this ArgumentExpr */ def constrExpr(): Tree = @@ -1541,7 +1542,7 @@ mixin class Parsers requires SyntaxAnalyzer { def selfInvocation(): Tree = atPos(accept(THIS)) { Apply(Ident(nme.CONSTRUCTOR), argumentExprs()) } - /** TypeDef ::= Id `=' Type + /** TypeDef ::= Id [TypeParamClause] `=' Type * TypeDcl ::= Id TypeBounds */ def typeDefOrDcl(mods: Modifiers): Tree = @@ -1563,30 +1564,30 @@ mixin class Parsers requires SyntaxAnalyzer { } } - /** TmplDef ::= ([case] class | trait) ClassDef - * | [case] object ObjectDef - */ - def tmplDef(mods: Modifiers): Tree = { - val mods1 = if (mods.hasFlag(Flags.MIXIN)) mods | Flags.ABSTRACT else mods; - in.token match { - case TRAIT => - classDef(mods1 | Flags.MIXIN | Flags.ABSTRACT); - case CLASS => - classDef(mods1); - case CASECLASS => - classDef(mods1 | Flags.CASE); - case OBJECT => - objectDef(mods1); - case CASEOBJECT => - objectDef(mods1 | Flags.CASE); - case _ => - syntaxError("illegal start of definition", true); - EmptyTree - } + /** TmplDef ::= ([case] class | trait) ClassDef + * | [case] object ObjectDef + */ + def tmplDef(mods: Modifiers): Tree = { + val mods1 = if (mods.hasFlag(Flags.MIXIN)) mods | Flags.ABSTRACT else mods; + in.token match { + case TRAIT => + classDef(mods1 | Flags.MIXIN | Flags.ABSTRACT); + case CLASS => + classDef(mods1); + case CASECLASS => + classDef(mods1 | Flags.CASE); + case OBJECT => + objectDef(mods1); + case CASEOBJECT => + objectDef(mods1 | Flags.CASE); + case _ => + syntaxError("illegal start of definition", true); + EmptyTree } + } /** ClassDef ::= ClassSig RequiresTypeOpt ClassTemplate - * ClassSig ::= Id [TypeParamClause] {ClassParamClause} + * ClassSig ::= Id [TypeParamClause] ClassParamClauses */ def classDef(mods: Modifiers): Tree = atPos(in.skipToken()) { @@ -1612,7 +1613,7 @@ mixin class Parsers requires SyntaxAnalyzer { ModuleDef(mods, name, template) } - /** ClassTemplate ::= [`extends' TemplateParents] [[NL] TemplateBody] + /** ClassTemplate ::= [`extends' TemplateParents] [[NewLine] TemplateBody] * TemplateParents ::= SimpleType {`(' [Exprs] `)'} {`with' SimpleType} */ def classTemplate(mods: Modifiers, name: Name, vparamss: List[List[ValDef]]): Template = @@ -1658,7 +1659,7 @@ mixin class Parsers requires SyntaxAnalyzer { ////////// TEMPLATES //////////////////////////////////////////////////////////// - /** TemplateBody ::= `{' [TemplateStat {SEP TemplateStat}] `}' + /** TemplateBody ::= `{' [TemplateStat {StatementSeparator TemplateStat}] `}' */ def templateBody(): List[Tree] = { accept(LBRACE); @@ -1668,7 +1669,7 @@ mixin class Parsers requires SyntaxAnalyzer { body } - /** Refinement ::= `{' [RefineStat {SEP RefineStat}] `}' + /** Refinement ::= `{' [RefineStat {StatementSeparator RefineStat}] `}' */ def refinement(): List[Tree] = { accept(LBRACE); @@ -1691,8 +1692,8 @@ mixin class Parsers requires SyntaxAnalyzer { } } - /** TopStatSeq ::= [TopStat {SEP TopStat}] - * TopStat ::= AttributeClauses Modifiers ClsDef + /** TopStatSeq ::= [TopStat {StatementSeparator TopStat}] + * TopStat ::= AttributeClauses Modifiers TmplDef * | Packaging * | Import * | @@ -1722,7 +1723,7 @@ mixin class Parsers requires SyntaxAnalyzer { stats.toList } - /** TemplateStatSeq ::= TemplateStat {SEP TemplateStat} + /** TemplateStatSeq ::= TemplateStat {StatementSeparator TemplateStat} * TemplateStat ::= Import * | AttributeClauses Modifiers Def * | AttributeClauses Modifiers Dcl @@ -1749,7 +1750,7 @@ mixin class Parsers requires SyntaxAnalyzer { } /** AttributeClauses ::= {AttributeClause} - * AttributeClause ::= `[' Attribute {`,' Attribute} `]' [NL] + * AttributeClause ::= `[' Attribute {`,' Attribute} `]' [NewLine] */ def attributeClauses(): List[Tree] = { var attrs = new ListBuffer[Tree]; @@ -1792,7 +1793,7 @@ mixin class Parsers requires SyntaxAnalyzer { defs map (defn => (attrs :\ defn) ((attr, tree) => Attributed(attr, tree) setPos attr.pos)); - /** RefineStatSeq ::= RefineStat {SEP RefineStat} + /** RefineStatSeq ::= RefineStat {StatementSeparator RefineStat} * RefineStat ::= Dcl * | type TypeDef * | @@ -1810,7 +1811,7 @@ mixin class Parsers requires SyntaxAnalyzer { stats.toList } - /** BlockStatSeq ::= { BlockStat SEP } [Expr] + /** BlockStatSeq ::= { BlockStat StatementSeparator } [Expr] * BlockStat ::= Import * | Def * | LocalModifiers TmplDef @@ -1846,7 +1847,7 @@ mixin class Parsers requires SyntaxAnalyzer { stats.toList } - /** CompilationUnit ::= package QualId SEP TopStatSeq + /** CompilationUnit ::= package QualId StatementSeparator TopStatSeq * | package QualId `{' TopStatSeq `}' * | TopStatSeq */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 8a91c603d6..0a72c94845 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -271,6 +271,8 @@ abstract class TreeBuilder { List(ValFrom(pos, makeBind(pat.duplicate), rhs)), Block(pdefs, makeTupleTerm(ids))) makeFor(mapName, flatMapName, ValFrom(pos, makeTuple(pat :: pats, true), rhs1) :: rest1, body) + case _ => + EmptyTree //may happen for erroneous input } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 7b56547433..9f98e7eb5b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -59,13 +59,13 @@ abstract class GenJVM extends SubComponent { val toStringType = new JMethodType(JObjectType.JAVA_LANG_STRING, JType.EMPTY_ARRAY); // Scala attributes - val SerializableAttr = definitions.SerializableAttr; + val SerializableAttr = definitions.SerializableAttr.tpe; + val BeanPropertyAttr = definitions.BeanPropertyAttr.tpe; val SerialVersionUID = definitions.getClass("scala.SerialVersionUID").tpe; val CloneableAttr = definitions.getClass("scala.cloneable").tpe; val TransientAtt = definitions.getClass("scala.transient").tpe; val VolatileAttr = definitions.getClass("scala.volatile").tpe; val RemoteAttr = definitions.getClass("scala.remote").tpe; - val BeanPropertyAttr = definitions.BeanPropertyAttr; val CloneableClass = definitions.getClass("java.lang.Cloneable"); val RemoteInterface = definitions.getClass("java.rmi.Remote"); diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 616070bc29..5875373d73 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -172,8 +172,8 @@ mixin class Definitions requires SymbolTable { var ObjectRefClass: Symbol = _; // special attributes - var SerializableAttr: Type = _; - var BeanPropertyAttr: Type = _; + var SerializableAttr: Symbol = _; + var BeanPropertyAttr: Symbol = _; def getModule(fullname: Name): Symbol = getModuleOrClass(fullname, true); @@ -200,8 +200,11 @@ mixin class Definitions requires SymbolTable { val result = if (module) sym.info.member(fullname.subName(i, j)).suchThat(.hasFlag(MODULE)); else sym.info.member(fullname.subName(i, j).toTypeName); - if (result == NoSymbol) + if (result == NoSymbol) { + System.out.println(sym.info); + System.out.println(sym.info.members); throw new FatalError((if (module) "object " else "class ") + fullname + " not found."); + } result } @@ -419,8 +422,8 @@ mixin class Definitions requires SymbolTable { BoxedUnitModule = getModule("scala.runtime.BoxedUnit"); ObjectRefClass = getClass("scala.runtime.ObjectRef"); - SerializableAttr = getClass("scala.serializable").tpe; - BeanPropertyAttr = getClass("scala.runtime.compat.BeanProperty").tpe; + SerializableAttr = getClass("scala.serializable"); + BeanPropertyAttr = getClass("scala.reflect.BeanProperty"); } } } diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala index c1a893a351..2c9bc04b69 100644 --- a/src/compiler/scala/tools/nsc/symtab/Flags.scala +++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala @@ -55,6 +55,7 @@ object Flags { final val SUPERACCESSOR = 0x10000000; // a super accessor final val PARAMACCESSOR = 0x20000000; // for value definitions: is an access method for a final val parameter // for parameters: is a val parameter + final val MODULEVAR = 0x40000000; final val IS_ERROR = 0x100000000L; // symbol is an error symbol final val OVERLOADED = 0x200000000L; // symbol is overloaded diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 6a6bbafdf1..48ea376b21 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -129,9 +129,6 @@ mixin class StdNames requires SymbolTable { def moduleVarName(name: Name): Name = newTermName(name.toString() + MODULE_SUFFIX); - def isModuleVarName(name: Name): boolean = - name.endsWith(MODULE_SUFFIX); - def superName(name: Name) = newTermName("super$" + name); val ERROR = newTermName(""); diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 4fd9c762ed..d9cecbe1e0 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -133,7 +133,7 @@ mixin class Symbols requires SymbolTable { final def newAnonymousFunctionClass(pos: int) = { val anonfun = newClass(pos, nme.ANON_FUN_NAME.toTypeName); anonfun.attributes = - Pair(definitions.SerializableAttr, List()) :: anonfun.attributes; + Pair(definitions.SerializableAttr.tpe, List()) :: anonfun.attributes; anonfun } final def newRefinementClass(pos: int) = @@ -156,6 +156,7 @@ mixin class Symbols requires SymbolTable { final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod; final def isCapturedVariable = isVariable && hasFlag(CAPTURED); + final def isGetter = isTerm && hasFlag(ACCESSOR) && !nme.isSetterName(name); final def isSetter = isTerm && hasFlag(ACCESSOR) && nme.isSetterName(name); //todo: make independent of name, as this can be forged. final def hasGetter = isTerm && nme.isLocalName(name); @@ -211,7 +212,7 @@ mixin class Symbols requires SymbolTable { ); /** Is this symbol a module variable ? */ - final def isModuleVar: boolean = isVariable && nme.isModuleVarName(name); + final def isModuleVar: boolean = isVariable && hasFlag(MODULEVAR); /** Is this symbol static (i.e. with no outer instance)? */ final def isStatic: boolean = @@ -436,6 +437,9 @@ mixin class Symbols requires SymbolTable { rawInfo.load(this); rawInfo.typeParams } + def getAttributes(clazz: Symbol): List[AttrInfo] = + attributes.filter(._1.symbol.isSubClass(clazz)); + /** Reset symbol to initial state */ def reset(completer: Type): unit = { diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala index f5d776041e..fc7dc39a7a 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala @@ -44,7 +44,7 @@ object PickleFormat { * | 33 LITERALstring len_Nat name_Ref * | 34 LITERALnull len_Nat * | 35 LITERALzero len_Nat - * | 36 ATTRIBUTE sym_Ref type_Ref {constant_Ref} + * | 40 ATTRIBUTE sym_Ref type_Ref {constant_Ref} * | 72 PosTYPEsym len_Nat pos_Nat SymbolInfo * | 73 PosALIASsym len_Nat pos_Nat SymbolInfo * | 74 PosCLASSsym len_Nat pos_Nat SymbolInfo [thistype_Ref] diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 67f2e4af88..22057d7854 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -112,6 +112,24 @@ abstract class LambdaLift extends InfoTransform { } } + private def markCalled(sym: Symbol, owner: Symbol): unit = { + if (settings.debug.value) log("mark " + sym + " of " + sym.owner + " called by " + owner); + symSet(called, owner) addEntry sym; + } +/* + + if (owner == enclMethOrClass(sym.owner)) true + else if (owner.isPackageClass || !markCalled(sym, enclMethOrClass(outer(owner)))) false + else { + val ss = symSet(called, owner); + if (!(ss contains sym)) { + ss addEntry sym; + if (settings.debug.value) log("" + sym + " is called by " + owner); + } + !owner.isClass + } + } +*/ def freeVars(sym: Symbol): Iterator[Symbol] = free.get(sym) match { case Some(ss) => ss.elements case None => Iterator.empty @@ -139,12 +157,13 @@ abstract class LambdaLift extends InfoTransform { } else if (sym.isLocal) { val owner = enclMethOrClass(currentOwner); if (sym.isTerm && !sym.isMethod) markFree(sym, owner) - else if (owner.isMethod && sym.isMethod) symSet(called, owner) addEntry sym; + else if (sym.isMethod) markCalled(sym, owner) + //symSet(called, owner) addEntry sym; } case Select(_, _) => if (sym.isConstructor && sym.owner.isLocal) { val owner = enclMethOrClass(currentOwner); - if (owner.isMethod) symSet(called, owner) addEntry sym; + markCalled(sym, owner) //symSet(called, owner) addEntry sym; } case _ => } @@ -174,7 +193,7 @@ abstract class LambdaLift extends InfoTransform { } while (changedFreeVars); for (val sym <- renamable.elements) { - sym.name = unit.fresh.newName(sym.name.toString()); + sym.name = unit.fresh.newName(sym.name.toString() + "$"); if (settings.debug.value) log("renamed: " + sym.name); } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 5c43c640ec..d4628fd27d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -50,7 +50,8 @@ abstract class RefChecks extends InfoTransform { // var m$: T = null; or, if class member: local var m$: T = _; def newModuleVarDef(accessor: Symbol) = { val mvar = accessor.owner.newVariable(accessor.pos, nme.moduleVarName(accessor.name)) - .setInfo(accessor.tpe.finalResultType); + .setInfo(accessor.tpe.finalResultType) + .setFlag(MODULEVAR); if (mvar.owner.isClass) { mvar setFlag (PRIVATE | LOCAL | SYNTHETIC); mvar.owner.info.decls.enter(mvar); diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 28d36b2494..c53d1b3e99 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -86,7 +86,7 @@ mixin class SyntheticMethods requires Analyzer { Apply(gen.mkRef(target), This(clazz) :: (vparamss.head map Ident)))); } - val SerializableAttr = definitions.SerializableAttr; + val SerializableAttr = definitions.SerializableAttr.tpe; def isSerializable(clazz: Symbol): Boolean = clazz.attributes.exists(p => p match { @@ -113,7 +113,47 @@ mixin class SyntheticMethods requires Analyzer { result } + def beanSetterOrGetter(sym: Symbol): Symbol = + if (!Character.isLetter(sym.name(0))) { + unit.error(sym.pos, "attribute `BeanProperty' can be applied only to fields that start with a letter"); + NoSymbol + } else { + var name0 = sym.name; + if (sym.isSetter) name0 = nme.setterToGetter(name0); + val prefix = if (sym.isSetter) "set" else "get"; + val arity = if (sym.isSetter) 1 else 0; + val name1 = prefix + Character.toUpperCase(name0(0)) + name0.subName(1, name0.length); + val sym1 = clazz.info.decl(name1); + if (sym1 != NoSymbol && sym1.tpe.paramTypes.length == arity) { + unit.error(sym.pos, "a definition of `"+name1+"' already exists in " + clazz); + NoSymbol + } else { + clazz.newMethod(sym.pos, name1) + .setInfo(sym.info) + .setFlag(sym.getFlag(DEFERRED | OVERRIDE | STATIC)) + } + } + val ts = new ListBuffer[Tree]; + + def addBeanGetterMethod(sym: Symbol) = { + val getter = beanSetterOrGetter(sym); + if (getter != NoSymbol) + ts += typed(DefDef( + getter, + vparamss => if (sym hasFlag DEFERRED) EmptyTree else gen.mkRef(sym))) + } + + def addBeanSetterMethod(sym: Symbol) = { + val setter = beanSetterOrGetter(sym); + if (setter != NoSymbol) + ts += typed(DefDef( + setter, + vparamss => + if (sym hasFlag DEFERRED) EmptyTree + else Apply(gen.mkRef(sym), List(Ident(vparamss.head.head))))) + } + if ((clazz hasFlag CASE) && !phase.erasedTypes) { // case classes are implicitly declared serializable clazz.attributes = Pair(SerializableAttr, List()) :: clazz.attributes; @@ -145,6 +185,14 @@ mixin class SyntheticMethods requires Analyzer { // jw-04-2003/jw-0425-designpatterns_p.html) if (!hasImplementation(nme.readResolve)) ts += readResolveMethod; } + for (val sym <- clazz.info.decls.toList) + if (!sym.getAttributes(BeanPropertyAttr).isEmpty) + if (sym.isGetter) + addBeanGetterMethod(sym) + else if (sym.isSetter) + addBeanSetterMethod(sym) + else if (sym.isMethod || sym.isType) + unit.error(sym.pos, "attribute `BeanProperty' is not applicable to " + sym); val synthetics = ts.toList; copy.Template( templ, templ.parents, if (synthetics.isEmpty) templ.body else templ.body ::: synthetics) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d84c7939dd..da4a8c2e8a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -16,15 +16,12 @@ mixin class Typers requires Analyzer { import definitions._ import posAssigner.atPos - var appcnt = 0 var idcnt = 0 var selcnt = 0 var implcnt = 0 var impltime = 0l - - private val transformed = new HashMap[Tree, Tree] private val superDefs = new HashMap[Symbol, ListBuffer[Tree]] diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 1cd1c757a0..1299737036 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -66,7 +66,7 @@ class ClassPath(onlyPresentation : Boolean) { } if (clazz == null && source0 == null) ret; else { - object entry extends Entry(clazz) { + val entry = new Entry(clazz) { override def source = if (source0 == null) null; else new Source(source0, head.source.compile); diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index f689152741..6b42362baf 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -10,4 +10,5 @@ package scala; trait Function0[+R] extends AnyRef { def apply(): R; + override def toString() = ""; } diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index cfb5897a2c..5841a6b993 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -10,4 +10,5 @@ package scala; trait Function1[-T0, +R] extends AnyRef { def apply(v0: T0): R; + override def toString() = ""; } diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index fd5eedc497..9904f18d64 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -10,4 +10,5 @@ package scala; trait Function2[-T0, -T1, +R] extends AnyRef { def apply(v0: T0, v1: T1): R; + override def toString() = ""; } diff --git a/src/library/scala/Function3.scala b/src/library/scala/Function3.scala index 9212945a4e..97ded234da 100644 --- a/src/library/scala/Function3.scala +++ b/src/library/scala/Function3.scala @@ -10,4 +10,5 @@ package scala; trait Function3[-T0, -T1, -T2, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2): R; + override def toString() = ""; } diff --git a/src/library/scala/Function4.scala b/src/library/scala/Function4.scala index 4731986c30..bd758ff266 100644 --- a/src/library/scala/Function4.scala +++ b/src/library/scala/Function4.scala @@ -10,4 +10,5 @@ package scala; trait Function4[-T0, -T1, -T2, -T3, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3): R; + override def toString() = ""; } diff --git a/src/library/scala/Function5.scala b/src/library/scala/Function5.scala index 17abc7eb7f..841be2fe4b 100644 --- a/src/library/scala/Function5.scala +++ b/src/library/scala/Function5.scala @@ -10,4 +10,5 @@ package scala; trait Function5[-T0, -T1, -T2, -T3, -T4, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4): R; + override def toString() = ""; } diff --git a/src/library/scala/Function6.scala b/src/library/scala/Function6.scala index 02f6c94af2..10ddb9548a 100644 --- a/src/library/scala/Function6.scala +++ b/src/library/scala/Function6.scala @@ -10,4 +10,5 @@ package scala; trait Function6[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5): R; + override def toString() = ""; } diff --git a/src/library/scala/Function7.scala b/src/library/scala/Function7.scala index e97dc787ec..2054cce506 100644 --- a/src/library/scala/Function7.scala +++ b/src/library/scala/Function7.scala @@ -10,4 +10,5 @@ package scala; trait Function7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6): R; + override def toString() = ""; } diff --git a/src/library/scala/Function8.scala b/src/library/scala/Function8.scala index f905cae58d..3a38a97dfc 100644 --- a/src/library/scala/Function8.scala +++ b/src/library/scala/Function8.scala @@ -10,4 +10,5 @@ package scala; trait Function8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7): R; + override def toString() = ""; } diff --git a/src/library/scala/Function9.scala b/src/library/scala/Function9.scala index 8ae0a5d658..7263baeeeb 100644 --- a/src/library/scala/Function9.scala +++ b/src/library/scala/Function9.scala @@ -10,4 +10,5 @@ package scala; trait Function9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends AnyRef { def apply(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8): R; + override def toString() = ""; } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 94bd73b79d..128b39ff67 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -38,6 +38,15 @@ object Predef { type Triple[+a, +b, +c] = Tuple3[a, b, c]; def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z); + def Tuple[a1, a2](x1: a1, x2: a2) = Tuple2(x1, x2); + def Tuple[a1, a2, a3](x1: a1, x2: a2, x3: a3) = Tuple3(x1, x2, x3); + def Tuple[a1, a2, a3, a4](x1: a1, x2: a2, x3: a3, x4: a4) = Tuple4(x1, x2, x3, x4); + def Tuple[a1, a2, a3, a4, a5](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5) = Tuple5(x1, x2, x3, x4, x5); + def Tuple[a1, a2, a3, a4, a5, a6](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6) = Tuple6(x1, x2, x3, x4, x5, x6); + def Tuple[a1, a2, a3, a4, a5, a6, a7](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7) = Tuple7(x1, x2, x3, x4, x5, x6, x7); + def Tuple[a1, a2, a3, a4, a5, a6, a7, a8](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8) = Tuple8(x1, x2, x3, x4, x5, x6, x7, x8); + def Tuple[a1, a2, a3, a4, a5, a6, a7, a8, a9](x1: a1, x2: a2, x3: a3, x4: a4, x5: a5, x6: a6, x7: a7, x8: a8, x9: a9) = Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9); + def id[a](x: a): a = x; def fst[a](x: a, y: Any): a = x; def scd[a](x: Any, y: a): a = y; diff --git a/src/library/scala/reflect/BeanProperty.scala b/src/library/scala/reflect/BeanProperty.scala new file mode 100644 index 0000000000..aa9c77c514 --- /dev/null +++ b/src/library/scala/reflect/BeanProperty.scala @@ -0,0 +1,12 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2005, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id: serializable.scala 5390 2005-12-19 13:49:03Z dubochet $ +*/ + +package scala.reflect; + +class BeanProperty extends Attribute {} diff --git a/test/files/neg/forward.check b/test/files/neg/forward.check new file mode 100644 index 0000000000..df847a0e86 --- /dev/null +++ b/test/files/neg/forward.check @@ -0,0 +1,10 @@ +forward.scala:6 error: forward reference extends over definition of value x + def f: int = x; + ^ +forward.scala:10 error: forward reference extends over definition of value x + def f: int = g; + ^ +forward.scala:15 error: forward reference extends over definition of variable x + def f: int = g; + ^ +three errors found diff --git a/test/files/neg/forward.scala b/test/files/neg/forward.scala new file mode 100755 index 0000000000..5e21e4c1fe --- /dev/null +++ b/test/files/neg/forward.scala @@ -0,0 +1,24 @@ +object Test { + def f: int = x; + val x: int = f; + + { + def f: int = x; + val x: int = f; + } + { + def f: int = g; + val x: int = f; + def g: int = x; + } + { + def f: int = g; + var x: int = f; + def g: int = x; + } + { + def f: int = g; + System.out.println("foo"); + def g: int = f; + } +} diff --git a/test/files/pos/bug530.scala b/test/files/pos/bug530.scala new file mode 100755 index 0000000000..6c887d6821 --- /dev/null +++ b/test/files/pos/bug530.scala @@ -0,0 +1,30 @@ +// scala.tools.nsc.Main.scala +package test; + +/** The main class for NSC, a compiler for the programming + * language Scala. + */ +object Test { +/* + def process(): AnyRef = { + class Compiler; + var compiler$module: Compiler = new Compiler; + def compiler() = compiler$module; + class Generator { + val c : Compiler = compiler() + } + var generator$module: Generator = new Generator; + def generator() = generator$module; + generator() + } +*/ + def process1(): AnyRef = { + object generator { + val c = compiler + } + object compiler; + generator + } + + +} diff --git a/test/files/pos/bug532.scala b/test/files/pos/bug532.scala new file mode 100644 index 0000000000..82da9c817f --- /dev/null +++ b/test/files/pos/bug532.scala @@ -0,0 +1,10 @@ +object Test extends Application { + import scala.reflect._; + def titi: Unit = { + var truc = 0 + val tata: TypedCode[()=>Unit] = () => { + truc = 6 + } + () + } +} diff --git a/test/files/run/exceptions-2.check b/test/files/run/exceptions-2.check index 40edd78ca2..3ec0dfcc1c 100644 --- a/test/files/run/exceptions-2.check +++ b/test/files/run/exceptions-2.check @@ -17,8 +17,8 @@ method3: Exception occurred with stack trace: java.lang.NullPointerException at Test$.method3(exceptions-2.scala:108) - at Test$$anonfun5.apply(exceptions-2.scala:151) - at Test$$anonfun5.apply(exceptions-2.scala:151) + at Test$$anonfun$5.apply(exceptions-2.scala:151) + at Test$$anonfun$5.apply(exceptions-2.scala:151) at Test$.execute(exceptions-2.scala:128) at Test$.main(exceptions-2.scala:151) at Test.main(exceptions-2.scala) -- cgit v1.2.3