diff options
author | Martin Odersky <odersky@gmail.com> | 2009-10-27 13:01:17 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-10-27 13:01:17 +0000 |
commit | d4c63b2af19fb48730b3c3eeb55a3e702893d113 (patch) | |
tree | 3772c1e940edcc8127f5ac8c8ad40288845a037e | |
parent | 38c3ca67563a68e8f30fd84282b1b9c4cebadeaa (diff) | |
download | scala-d4c63b2af19fb48730b3c3eeb55a3e702893d113.tar.gz scala-d4c63b2af19fb48730b3c3eeb55a3e702893d113.tar.bz2 scala-d4c63b2af19fb48730b3c3eeb55a3e702893d113.zip |
Fixed #2494, plus some reorganization of swing ...
Fixed #2494, plus some reorganization of swing imports
26 files changed, 84 insertions, 56 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 6bd3fee3fb..f8f6ee2c55 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -1803,7 +1803,8 @@ trait Trees { /** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse */ - def resetAttrs[A<:Tree](x:A, strict: Boolean = false): A = {new ResetAttrsTraverser(strict).traverse(x); x} + def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x } + def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x } /** A traverser which resets symbol and tpe fields of all nodes in a given tree * except for (1) TypeTree nodes, whose <code>.tpe</code> field is kept and @@ -1812,26 +1813,39 @@ trait Trees { * * (bq:) This traverser has mutable state and should be discarded after use */ - class ResetAttrsTraverser(strict: Boolean) extends Traverser { - private val erasedSyms = new HashSet[Symbol]("erasedSyms", 8) + private class ResetAttrsTraverser extends Traverser { + protected def isLocal(sym: Symbol): Boolean = true + protected def resetDef(tree: Tree) { + tree.symbol = NoSymbol + tree.tpe = null + super.traverse(tree) + } override def traverse(tree: Tree): Unit = tree match { case EmptyTree | TypeTree() => ; - case Template(parents, self, body) => - tree.symbol = NoSymbol + case _: DefTree | Function(_, _) | Template(_, _, _) => + resetDef(tree) + case _ => + if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol tree.tpe = null - if (!strict) - for (stat <- body) - if (stat.isDef) erasedSyms.addEntry(stat.symbol) super.traverse(tree) - case _: DefTree | Function(_, _) => - if (!strict) erasedSyms.addEntry(tree.symbol) - tree.symbol = NoSymbol - tree.tpe = null + } + } + + private class ResetLocalAttrsTraverser extends ResetAttrsTraverser { + private val erasedSyms = new HashSet[Symbol](8) + override protected def isLocal(sym: Symbol) = + erasedSyms contains sym + override protected def resetDef(tree: Tree) { + erasedSyms addEntry tree.symbol + super.resetDef(tree) + } + override def traverse(tree: Tree): Unit = tree match { + case Template(parents, self, body) => + for (stat <- body) + if (stat.isDef) erasedSyms.addEntry(stat.symbol) super.traverse(tree) case _ => - if (tree.hasSymbol && (strict || erasedSyms.contains(tree.symbol))) tree.symbol = NoSymbol - tree.tpe = null super.traverse(tree) } } diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index b1a94b8162..a94ba17d8a 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1964,7 +1964,9 @@ trait Symbols { /** An exception for cyclic references of symbol definitions */ case class CyclicReference(sym: Symbol, info: Type) - extends TypeError("illegal cyclic reference involving " + sym) + extends TypeError("illegal cyclic reference involving " + sym) { + // printStackTrace() // debug + } /** A class for type histories */ private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) { diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 071f1baf29..710e7e1487 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -4861,7 +4861,7 @@ A type's typeSymbol should never be inspected directly. // Errors and Diagnostics ----------------------------------------------------- /** An exception signalling a type error */ - class TypeError(val pos: Position, val msg: String) extends java.lang.Error(msg) { + class TypeError(var pos: Position, val msg: String) extends java.lang.Error(msg) { def this(msg: String) = this(NoPosition, msg) } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 9752bb33ae..bc9c788804 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -344,7 +344,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { val substParam = new TreeSymSubstituter(List(fun.vparams.head.symbol), List(idparam)); def transformCase(cdef: CaseDef): CaseDef = substParam( - resetAttrs( + resetLocalAttrs( CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true)))) if (cases exists treeInfo.isDefaultCase) Literal(true) else diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index a32f945553..1e07442eee 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -100,6 +100,21 @@ self: Analyzer => tpeCache } + /** Does type `tp` contain an Error type as parameter or result? + */ + private def containsError(tp: Type): Boolean = tp match { + case PolyType(tparams, restpe) => containsError(restpe) + case MethodType(params, restpe) => (params map (_.tpe) exists (_.isError)) || containsError(restpe) + case _ => tp.isError + } + + def isCyclicOrErroneous = try { + containsError(tpe) + } catch { + case ex: CyclicReference => + true + } + override def equals(other: Any) = other match { case that: ImplicitInfo => this.name == that.name && @@ -218,14 +233,6 @@ self: Analyzer => case _ => tp } - /** Does type `tp` contain an Error type as parameter or result? - */ - private def containsError(tp: Type): Boolean = tp match { - case PolyType(tparams, restpe) => containsError(restpe) - case MethodType(params, restpe) => (params map (_.tpe) exists (_.isError)) || containsError(restpe) - case _ => tp.isError - } - /** Does type `dtor` dominate type `dted`? * This is the case if the stripped cores `dtor1` and `dted1` of both types are * the same wrt `=:=`, or if they overlap and the complexity of `dtor1` is higher @@ -508,7 +515,7 @@ self: Analyzer => * SearchFailure if not. */ def tryImplicit(info: ImplicitInfo): SearchResult = - if (containsError(info.tpe) || + if (info.isCyclicOrErroneous || (isLocal && shadowed.contains(info.name)) || (isView && (info.sym == Predef_identity || info.sym == Predef_conforms)) //@M this condition prevents no-op conversions, which are a problem (besides efficiency), // TODO: remove `info.sym == Predef_identity` once we have a new STARR that only has conforms as an implicit diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index c586729e22..f19f5516c0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -235,7 +235,7 @@ trait NamesDefaults { self: Analyzer => val (sym, byName) = symP // resetAttrs required for #2290. given a block { val x = 1; x }, when wrapping into a function // () => { val x = 1; x }, the owner of symbol x must change (to the apply method of the function). - val body = if (byName) blockTyper.typed(Function(List(), resetAttrs(arg))) + val body = if (byName) blockTyper.typed(Function(List(), resetLocalAttrs(arg))) else arg atPos(body.pos)(ValDef(sym, body).setType(NoType)) }) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6f85e8ab16..9c5edf7e86 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -241,9 +241,10 @@ trait Typers { self: Analyzer => * @param pos0 The position where to report the error * @param ex The exception that caused the error */ - def reportTypeError(pos0: Position, ex: TypeError) { + def reportTypeError(pos: Position, ex: TypeError) { + if (ex.pos == NoPosition) ex.pos = pos + if (!context.reportGeneralErrors) throw ex if (settings.debug.value) ex.printStackTrace() - val pos = if (ex.pos == NoPosition) pos0 else ex.pos ex match { case CyclicReference(sym, info: TypeCompleter) => val msg = @@ -256,11 +257,11 @@ trait Typers { self: Analyzer => case _ => ex.getMessage() } - context.error(pos, msg) + context.error(ex.pos, msg) if (sym == ObjectClass) throw new FatalError("cannot redefine root "+sym) case _ => - context.error(pos, ex) + context.error(ex.pos, ex) } } @@ -703,11 +704,11 @@ trait Typers { self: Analyzer => /** Utility method: Try op1 on tree. If that gives an error try op2 instead. */ def tryBoth(tree: Tree)(op1: (Typer, Tree) => Tree)(op2: (Typer, Tree) => Tree): Tree = - silent(op1(_, tree.duplicate)) match { + silent(op1(_, tree)) match { case result1: Tree => result1 case ex1: TypeError => - silent(op2(_, tree)) match { + silent(op2(_, resetAllAttrs(tree))) match { case result2: Tree => // println("snd succeeded: "+result2) result2 @@ -800,8 +801,8 @@ trait Typers { self: Analyzer => typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match { case result: Tree => result case ex: TypeError => - if (settings.debug.value) log("fallback on implicits: "+tree+"/"+resetAttrs(original, true)) - val tree1 = typed(resetAttrs(original, true), mode, WildcardType) + if (settings.debug.value) log("fallback on implicits: "+tree+"/"+resetAllAttrs(original)) + val tree1 = typed(resetAllAttrs(original), mode, WildcardType) tree1.tpe = addAnnotations(tree1, tree1.tpe) if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree) } @@ -1008,7 +1009,7 @@ trait Typers { self: Analyzer => /** Try to apply an implicit conversion to `qual' to that it contains * a method `name` which can be applied to arguments `args' with expected type `pt'. * If `pt' is defined, there is a fallback to try again with pt = ?. - * This helps avoiding propagating result information to far and solves + * This helps avoiding propagating result information too far and solves * #1756. * If no conversion is found, return `qual' unchanged. * @@ -3067,6 +3068,7 @@ trait Typers { self: Analyzer => try { newTyper(c).typedArgs(args, mode) } catch { + case ex: CyclicReference => throw ex case ex: TypeError => null } @@ -3417,7 +3419,7 @@ trait Typers { self: Analyzer => (!currentRun.compiles(defSym) || (context.unit ne null) && defSym.sourceFile != context.unit.source.file)) defSym = NoSymbol - else if (impSym.isError) + else if (impSym.isError || impSym.name == nme.CONSTRUCTOR) impSym = NoSymbol } if (defSym.exists) { diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index f4ed95489b..2feb892421 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -116,9 +116,7 @@ abstract class Enumeration(initial: Int, names: String*) { * or initialize each Enumeration with Value(String), * for valueOf to work. * @param s an enumeration name - * @return <tt>Some(Value)</tt> if an enumeration's name matches <var>s</var>, - * else <tt>None</tt> - * Note the change here is intentional. You should know whether + * Note the change here wrt 2.7 is intentional. You should know whether * a name is in an Enumeration beforehand. If not, just use find on values. */ def withName(s: String): Value = values.find(_.toString == s).get diff --git a/src/swing/scala/swing/AbstractButton.scala b/src/swing/scala/swing/AbstractButton.scala index c3258b4fc6..991d82fb55 100644 --- a/src/swing/scala/swing/AbstractButton.scala +++ b/src/swing/scala/swing/AbstractButton.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import java.awt.{Dimension, Insets} import javax.swing.{AbstractButton => JAbstractButton, Icon} -import event._ /** * Base class of all button-like widgets, such as push buttons, diff --git a/src/swing/scala/swing/Button.scala b/src/swing/scala/swing/Button.scala index 698924b18d..e3387ef271 100644 --- a/src/swing/scala/swing/Button.scala +++ b/src/swing/scala/swing/Button.scala @@ -11,8 +11,8 @@ package scala.swing -import javax.swing._ import event._ +import javax.swing._ object Button { def apply(text0: String)(op: => Unit) = new Button(Action(text0)(op)) diff --git a/src/swing/scala/swing/ButtonGroup.scala b/src/swing/scala/swing/ButtonGroup.scala index 4bf2cb21ff..8af67cdb3c 100644 --- a/src/swing/scala/swing/ButtonGroup.scala +++ b/src/swing/scala/swing/ButtonGroup.scala @@ -11,8 +11,8 @@ package scala.swing -import javax.swing.{AbstractButton => JAbstractButton,Icon} import event._ +import javax.swing.{AbstractButton => JAbstractButton,Icon} import scala.collection._ import scala.collection.mutable.Buffer diff --git a/src/swing/scala/swing/EditorPane.scala b/src/swing/scala/swing/EditorPane.scala index 7b93e2cdff..a258865508 100644 --- a/src/swing/scala/swing/EditorPane.scala +++ b/src/swing/scala/swing/EditorPane.scala @@ -10,11 +10,11 @@ package scala.swing +import event._ import javax.swing._ import javax.swing.text._ import java.awt.Color import java.awt.event._ -import event._ /** * A text component that allows multiline text input and display. diff --git a/src/swing/scala/swing/FormattedTextField.scala b/src/swing/scala/swing/FormattedTextField.scala index 6397de2621..623764dc76 100644 --- a/src/swing/scala/swing/FormattedTextField.scala +++ b/src/swing/scala/swing/FormattedTextField.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import javax.swing._ import java.awt.event._ -import event._ object FormattedTextField { /** diff --git a/src/swing/scala/swing/GUIApplication.scala b/src/swing/scala/swing/GUIApplication.scala index 0cce2cb176..a3965fcec8 100644 --- a/src/swing/scala/swing/GUIApplication.scala +++ b/src/swing/scala/swing/GUIApplication.scala @@ -11,8 +11,8 @@ package scala.swing -import javax.swing._ import event.Event +import javax.swing._ /** * Convenience class with utility methods for GUI applications. diff --git a/src/swing/scala/swing/ListView.scala b/src/swing/scala/swing/ListView.scala index 49b69396fe..0712f78d57 100644 --- a/src/swing/scala/swing/ListView.scala +++ b/src/swing/scala/swing/ListView.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import javax.swing._ import javax.swing.event._ -import event._ import java.awt.Color object ListView { diff --git a/src/swing/scala/swing/PasswordField.scala b/src/swing/scala/swing/PasswordField.scala index 0a77ff6f38..4fcc761be5 100644 --- a/src/swing/scala/swing/PasswordField.scala +++ b/src/swing/scala/swing/PasswordField.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import javax.swing._ import java.awt.event._ -import event._ /** * A password field, that displays a replacement character for each character in the password. diff --git a/src/swing/scala/swing/Table.scala b/src/swing/scala/swing/Table.scala index 2cedbd1050..88f19f5f02 100644 --- a/src/swing/scala/swing/Table.scala +++ b/src/swing/scala/swing/Table.scala @@ -11,11 +11,11 @@ package scala.swing +import event._ import javax.swing._ import javax.swing.table._ import javax.swing.event._ import java.awt.{Dimension, Color} -import event._ import scala.collection.mutable.{Set, IndexedSeq} object Table { diff --git a/src/swing/scala/swing/TextArea.scala b/src/swing/scala/swing/TextArea.scala index 08540845b6..4ff0a666da 100644 --- a/src/swing/scala/swing/TextArea.scala +++ b/src/swing/scala/swing/TextArea.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import javax.swing._ import java.awt.event._ -import event._ /** * A text component that allows multiline text input and display. diff --git a/src/swing/scala/swing/TextComponent.scala b/src/swing/scala/swing/TextComponent.scala index 70d6d8055c..3b81b567bb 100644 --- a/src/swing/scala/swing/TextComponent.scala +++ b/src/swing/scala/swing/TextComponent.scala @@ -11,11 +11,11 @@ package scala.swing +import event._ import javax.swing._ import javax.swing.text._ import javax.swing.event._ import java.awt.Color -import event._ object TextComponent { trait HasColumns extends TextComponent { diff --git a/src/swing/scala/swing/TextField.scala b/src/swing/scala/swing/TextField.scala index 201a97b724..acb34b9a1b 100644 --- a/src/swing/scala/swing/TextField.scala +++ b/src/swing/scala/swing/TextField.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import javax.swing._ import java.awt.event._ -import event._ /*object TextField { diff --git a/src/swing/scala/swing/ToggleButton.scala b/src/swing/scala/swing/ToggleButton.scala index 26958c94f8..608f2c02b7 100644 --- a/src/swing/scala/swing/ToggleButton.scala +++ b/src/swing/scala/swing/ToggleButton.scala @@ -11,8 +11,8 @@ package scala.swing -import javax.swing._ import event._ +import javax.swing._ /** * A two state button with a push button like user interface. diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala index a557535627..f8f050b3d6 100644 --- a/src/swing/scala/swing/UIElement.scala +++ b/src/swing/scala/swing/UIElement.scala @@ -11,11 +11,11 @@ package scala.swing +import event._ import java.awt.{Color, Cursor, Font, Dimension, Rectangle} import scala.collection.mutable.HashMap import scala.ref._ import java.util.WeakHashMap -import event._ object UIElement { private val ClientKey = "scala.swingWrapper" diff --git a/src/swing/scala/swing/Window.scala b/src/swing/scala/swing/Window.scala index e9fdfff7ca..bc333db9ca 100644 --- a/src/swing/scala/swing/Window.scala +++ b/src/swing/scala/swing/Window.scala @@ -11,9 +11,9 @@ package scala.swing +import event._ import java.awt.{Image, Point, Window => AWTWindow} import javax.swing._ -import event._ /** * A window with decoration such as a title, border, and action buttons. diff --git a/test/files/neg/t2494.check b/test/files/neg/t2494.check new file mode 100644 index 0000000000..6d43011e24 --- /dev/null +++ b/test/files/neg/t2494.check @@ -0,0 +1,4 @@ +t2494.scala:1: error: recursive value a needs type +object A { val a = { println("a = " + a); a = 1} } + ^ +one error found diff --git a/test/files/neg/t2494.scala b/test/files/neg/t2494.scala new file mode 100755 index 0000000000..71e6bc4bbf --- /dev/null +++ b/test/files/neg/t2494.scala @@ -0,0 +1 @@ +object A { val a = { println("a = " + a); a = 1} } diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index 1f92436628..008939cc9d 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -183,7 +183,7 @@ object Test extends Application { println(argName) // should be 4 test5 { argName = 5 } println(argName) // should be 5 - val a = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's + val a: Unit = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's // dependent types and copy method |