diff options
45 files changed, 703 insertions, 150 deletions
diff --git a/build.number b/build.number index b5c4e61d13..f28886751b 100644 --- a/build.number +++ b/build.number @@ -1,7 +1,7 @@ #Tue Sep 11 19:21:09 CEST 2007 version.major=2 version.minor=10 -version.patch=0 +version.patch=1 # This is the -N part of a version. if it's 0, it's dropped from maven versions. version.bnum=0 diff --git a/docs/examples/swing/ColorChooserDemo.scala b/docs/examples/swing/ColorChooserDemo.scala new file mode 100644 index 0000000000..1cb2bdefa2 --- /dev/null +++ b/docs/examples/swing/ColorChooserDemo.scala @@ -0,0 +1,61 @@ +package examples.swing + +import java.awt.{Color, Font, Dimension} +import swing._ +import event._ +import Swing._ +import BorderPanel._ + +/** + * Demo for ColorChooser. + * Based on http://download.oracle.com/javase/tutorial/uiswing/components/colorchooser.html + * + * @author andy@hicks.net + */ +object ColorChooserDemo extends SimpleSwingApplication { + def top = new MainFrame { + title = "ColorChooser Demo" + size = new Dimension(400, 400) + + contents = ui + } + + def ui = new BorderPanel { + val colorChooser = new ColorChooser { + reactions += { + case ColorChanged(_, c) => + banner.foreground = c + } + } + + colorChooser.border = TitledBorder(EtchedBorder, "Choose Text Color") + + val banner = new Label("Welcome to Scala Swing") { + horizontalAlignment = Alignment.Center + foreground = Color.yellow + background = Color.blue + opaque = true + font = new Font("SansSerif", Font.BOLD, 24) + } + + val bannerArea = new BorderPanel { + layout(banner) = Position.Center + border = TitledBorder(EtchedBorder, "Banner") + } + + // Display a color selection dialog when button pressed + val selectColor = new Button("Choose Background Color") { + reactions += { + case ButtonClicked(_) => + ColorChooser.showDialog(this, "Test", Color.red) match { + case Some(c) => banner.background = c + case None => + } + } + } + + layout(bannerArea) = Position.North + layout(colorChooser) = Position.Center + layout(selectColor) = Position.South + } +}
\ No newline at end of file diff --git a/docs/examples/swing/PopupDemo.scala b/docs/examples/swing/PopupDemo.scala new file mode 100644 index 0000000000..6a9eeb125b --- /dev/null +++ b/docs/examples/swing/PopupDemo.scala @@ -0,0 +1,33 @@ +package examples.swing + +import swing._ +import event._ +import Swing._ + +/** + * @author John Sullivan + * @author Ingo Maier + */ +object PopupDemo extends SimpleSwingApplication { + def top = new MainFrame { + val popupMenu = new PopupMenu { + contents += new Menu("menu 1") { + contents += new RadioMenuItem("radio 1.1") + contents += new RadioMenuItem("radio 1.2") + } + contents += new Menu("menu 2") { + contents += new RadioMenuItem("radio 2.1") + contents += new RadioMenuItem("radio 2.2") + } + } + val button = new Button("Show Popup Menu") + reactions += { + case ButtonClicked(b) => popupMenu.show(b, 0, b.bounds.height) + case PopupMenuCanceled(m) => println("Menu " + m + " canceled.") + } + listenTo(popupMenu) + listenTo(button) + + contents = new FlowPanel(button) + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index c25112941c..b8b5f8033b 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -71,4 +71,9 @@ trait Errors { val msg = "internal error: erroneous reifees are not supported, make sure that your reifee has typechecked successfully before passing it to the reifier" throw new UnexpectedReificationException(defaultErrorPosition, msg) } + + def CannotReifyInvalidLazyVal(tree: ValDef) = { + val msg = "internal error: could not reconstruct original lazy val due to missing accessor" + throw new UnexpectedReificationException(tree.pos, msg) + } } diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index b5894e8eb6..1b7509fdbe 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -46,13 +46,13 @@ trait Reshape { if (discard) hk else ta case classDef @ ClassDef(mods, name, params, impl) => val Template(parents, self, body) = impl - var body1 = trimAccessors(classDef, body) + var body1 = trimAccessors(classDef, reshapeLazyVals(body)) body1 = trimSyntheticCaseClassMembers(classDef, body1) var impl1 = Template(parents, self, body1).copyAttrs(impl) ClassDef(mods, name, params, impl1).copyAttrs(classDef) case moduledef @ ModuleDef(mods, name, impl) => val Template(parents, self, body) = impl - var body1 = trimAccessors(moduledef, body) + var body1 = trimAccessors(moduledef, reshapeLazyVals(body)) body1 = trimSyntheticCaseClassMembers(moduledef, body1) var impl1 = Template(parents, self, body1).copyAttrs(impl) ModuleDef(mods, name, impl1).copyAttrs(moduledef) @@ -60,15 +60,11 @@ trait Reshape { val discardedParents = parents collect { case tt: TypeTree => tt } filter isDiscarded if (reifyDebug && discardedParents.length > 0) println("discarding parents in Template: " + discardedParents.mkString(", ")) val parents1 = parents diff discardedParents - val body1 = trimSyntheticCaseClassCompanions(body) + val body1 = reshapeLazyVals(trimSyntheticCaseClassCompanions(body)) Template(parents1, self, body1).copyAttrs(template) case block @ Block(stats, expr) => - val stats1 = trimSyntheticCaseClassCompanions(stats) + val stats1 = reshapeLazyVals(trimSyntheticCaseClassCompanions(stats)) Block(stats1, expr).copyAttrs(block) - case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy => - if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree) - val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name - ValDef(mods, name1, tpt, rhs).copyAttrs(valdef) case unapply @ UnApply(fun, args) => def extractExtractor(tree: Tree): Tree = { val Apply(fun, args) = tree @@ -248,6 +244,20 @@ trait Reshape { New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args)) } + private def toPreTyperLazyVal(ddef: DefDef): ValDef = { + def extractRhs(rhs: Tree) = rhs match { + case Block(Assign(lhs, rhs)::Nil, _) if lhs.symbol.isLazy => rhs + case _ => rhs // unit or trait case + } + val DefDef(mods0, name0, _, _, tpt0, rhs0) = ddef + val name1 = nme.dropLocalSuffix(name0) + val Modifiers(flags0, privateWithin0, annotations0) = mods0 + var flags1 = (flags0 & GetterFlags) & ~(STABLE | ACCESSOR | METHOD) + val mods1 = Modifiers(flags1, privateWithin0, annotations0) setPositions mods0.positions + val mods2 = toPreTyperModifiers(mods1, ddef.symbol) + ValDef(mods2, name1, tpt0, extractRhs(rhs0)) + } + private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { val symdefs = (stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff)).toMap val accessors = scala.collection.mutable.Map[ValDef, List[DefDef]]() @@ -270,7 +280,7 @@ trait Reshape { }); var stats1 = stats flatMap { - case vdef @ ValDef(mods, name, tpt, rhs) => + case vdef @ ValDef(mods, name, tpt, rhs) if !mods.isLazy => val mods1 = if (accessors.contains(vdef)) { val ddef = accessors(vdef)(0) // any accessor will do val Modifiers(flags, privateWithin, annotations) = mods @@ -287,7 +297,9 @@ trait Reshape { val vdef1 = ValDef(mods2, name1, tpt, rhs) if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1)) Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are now out of sync - case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => + case ddef: DefDef if !ddef.mods.isLazy => + // lazy val accessors are removed in reshapeLazyVals + // as they are needed to recreate lazy vals if (accessors.values.exists(_.contains(ddef))) { if (reifyDebug) println("discarding accessor method: " + ddef) None @@ -301,6 +313,34 @@ trait Reshape { stats1 } + private def reshapeLazyVals(stats: List[Tree]): List[Tree] = { + val lazyvaldefs:Map[Symbol, DefDef] = stats.collect({ case ddef: DefDef if ddef.mods.isLazy => ddef }). + map((ddef: DefDef) => ddef.symbol -> ddef).toMap + // lazy valdef and defdef are in the same block. + // only that valdef needs to have its rhs rebuilt from defdef + stats flatMap (stat => stat match { + case vdef: ValDef if vdef.symbol.isLazy => + if (reifyDebug) println(s"reconstructing original lazy value for $vdef") + val ddefSym = vdef.symbol.lazyAccessor + val vdef1 = lazyvaldefs.get(ddefSym) match { + case Some(ddef) => + toPreTyperLazyVal(ddef) + case None => + CannotReifyInvalidLazyVal(vdef) + } + if (reifyDebug) println(s"reconstructed lazy val is $vdef1") + vdef1::Nil + case ddef: DefDef if ddef.symbol.isLazy => + def hasUnitType(sym: Symbol) = (sym.tpe.typeSymbol == UnitClass) && sym.tpe.annotations.isEmpty + if (hasUnitType(ddef.symbol)) { + // since lazy values of type Unit don't have val's + // we need to create them from scratch + toPreTyperLazyVal(ddef) :: Nil + } else Nil + case _ => stat::Nil + }) + } + private def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]): List[Tree] = stats filterNot (memberDef => memberDef.isDef && { val isSynthetic = memberDef.symbol.isSynthetic diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala index 4c9a3178aa..642e330a57 100644 --- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala @@ -39,9 +39,6 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor phasesSet += analyzer.namerFactory phasesSet += analyzer.packageObjects phasesSet += analyzer.typerFactory - phasesSet += superAccessors - phasesSet += pickler - phasesSet += refChecks } override def forScaladoc = true } diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala index 7cc99ba50e..10a0d8d879 100644 --- a/src/compiler/scala/tools/nsc/doc/Settings.scala +++ b/src/compiler/scala/tools/nsc/doc/Settings.scala @@ -7,6 +7,7 @@ package scala.tools.nsc package doc import java.io.File +import java.net.URI import java.lang.System import scala.language.postfixOps @@ -71,6 +72,12 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) "" ) + val docExternalUris = MultiStringSetting ( + "-doc-external-uris", + "external-doc", + "comma-separated list of file://classpath_entry_path#doc_URL URIs for external dependencies" + ) + val useStupidTypes = BooleanSetting ( "-Yuse-stupid-types", "Print the types of inherited members as seen from their original definition context. Hint: you don't want to do that!" @@ -197,7 +204,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) val docExternalUrls = MultiStringSetting ( "-external-urls", "externalUrl(s)", - "comma-separated list of package_names=doc_URL for external dependencies, where package names are ':'-separated" + "(deprecated) comma-separated list of package_names=doc_URL for external dependencies, where package names are ':'-separated" ) val docGroups = BooleanSetting ( @@ -244,22 +251,25 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) } } - // TODO: Enable scaladoc to scoop up the package list from another scaladoc site, just as javadoc does - // -external-urls 'http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library' - // should trigger scaldoc to fetch the package-list file. The steps necessary: - // 1 - list all packages generated in scaladoc in the package-list file, exactly as javadoc: - // see http://docs.oracle.com/javase/6/docs/api/package-list for http://docs.oracle.com/javase/6/docs/api - // 2 - download the file and add the packages to the list - lazy val extUrlMapping: Map[String, String] = (Map.empty[String, String] /: docExternalUrls.value) { + def appendIndex(url: String): String = { + val index = "/index.html" + if (url.endsWith(index)) url else url + index + } + + // Deprecated together with 'docExternalUrls' option. + lazy val extUrlPackageMapping: Map[String, String] = (Map.empty[String, String] /: docExternalUrls.value) { case (map, binding) => val idx = binding indexOf "=" val pkgs = binding substring (0, idx) split ":" - var url = binding substring (idx + 1) - val index = "/index.html" - url = if (url.endsWith(index)) url else url + index + val url = appendIndex(binding substring (idx + 1)) map ++ (pkgs map (_ -> url)) } + lazy val extUrlMapping: Map[String, String] = docExternalUris.value map { s => + val uri = new URI(s) + uri.getSchemeSpecificPart -> appendIndex(uri.getFragment) + } toMap + /** * This is the hardcoded area of Scaladoc. This is where "undesirable" stuff gets eliminated. I know it's not pretty, * but ultimately scaladoc has to be useful. :) diff --git a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala index 1c783a7d2c..5257db1610 100644 --- a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala +++ b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala @@ -48,9 +48,9 @@ trait MemberLookup { } if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage) - findExternalLink(linkName(sym)) + findExternalLink(sym, linkName(sym)) else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage) - findExternalLink(linkName(owner) + "@" + externalSignature(sym)) + findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym)) else None } @@ -171,7 +171,7 @@ trait MemberLookup { // and removing NoType classes def cleanupBogusClasses(syms: List[Symbol]) = { syms.filter(_.info != NoType) } - def syms(name: Name) = container.info.nonPrivateMember(name).alternatives + def syms(name: Name) = container.info.nonPrivateMember(name.encodedName).alternatives def termSyms = cleanupBogusClasses(syms(newTermName(name))) def typeSyms = cleanupBogusClasses(syms(newTypeName(name))) diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index b4df7b8354..8dd7e7801e 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -28,7 +28,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { with MemberLookup => import global._ - import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass } + import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass, ListClass } import rootMirror.{ RootPackage, RootClass, EmptyPackage } // Defaults for member grouping, that may be overridden by the template @@ -1097,12 +1097,27 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { { val rawComment = global.expandedDocComment(bSym, inTpl.sym) rawComment.contains("@template") || rawComment.contains("@documentable") } - def findExternalLink(name: String): Option[LinkTo] = - settings.extUrlMapping find { - case (pkg, _) => name startsWith pkg - } map { - case (_, url) => LinkToExternal(name, url + "#" + name) + def findExternalLink(sym: Symbol, name: String): Option[LinkTo] = { + val sym1 = + if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass + else if (sym.isPackage) + /* Get package object which has associatedFile ne null */ + sym.info.member(newTermName("package")) + else sym + Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src => + val path = src.path + settings.extUrlMapping get path map { url => + LinkToExternal(name, url + "#" + name) + } + } orElse { + // Deprecated option. + settings.extUrlPackageMapping find { + case (pkg, _) => name startsWith pkg + } map { + case (_, url) => LinkToExternal(name, url + "#" + name) + } } + } def externalSignature(sym: Symbol) = { sym.info // force it, otherwise we see lazy types diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala index a07865f7a3..942ccaf1ba 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala @@ -104,7 +104,7 @@ trait ModelFactoryTypeSupport { if (!bSym.owner.isPackage) Tooltip(name) else - findExternalLink(name).getOrElse ( + findExternalLink(bSym, name).getOrElse ( // (3) if we couldn't find neither the owner nor external URL to link to, show a tooltip with the qualified name Tooltip(name) ) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 83f661e1de..bacd8c39e1 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -231,9 +231,8 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => extends ChangeOwnerTraverser(oldowner, newowner) { override def traverse(tree: Tree) { tree match { - case Return(expr) => - if (tree.symbol == oldowner) tree.symbol = newowner - case _ => + case _: Return => change(tree.symbol) + case _ => } super.traverse(tree) } diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 12e2433e0d..21213cf9d9 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -94,6 +94,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD } else sym.owner } + debuglog(s"determined enclosing class/dummy/method for lazy val as $enclosingClassOrDummyOrMethod given symbol $sym") val idx = lazyVals(enclosingClassOrDummyOrMethod) lazyVals(enclosingClassOrDummyOrMethod) = idx + 1 val (rhs1, sDef) = mkLazyDef(enclosingClassOrDummyOrMethod, transform(rhs), idx, sym) @@ -194,6 +195,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name), lzyVal.pos, STABLE | PRIVATE) defSym setInfo MethodType(List(), lzyVal.tpe.resultType) defSym.owner = lzyVal.owner + debuglog(s"crete slow compute path $defSym with owner ${defSym.owner} for lazy val $lzyVal") if (bitmaps.contains(lzyVal)) bitmaps(lzyVal).map(_.owner = defSym) val rhs: Tree = (gen.mkSynchronizedCheck(clazz, cond, syncBody, stats)).changeOwner(currentOwner -> defSym) @@ -248,6 +250,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD def mkBlock(stmt: Tree) = BLOCK(stmt, mkSetFlag(bitmapSym, mask, bitmapRef), UNIT) + debuglog(s"create complete lazy def in $methOrClass for $lazyVal") val (block, res) = tree match { case Block(List(assignment), res) if !lazyUnit(lazyVal) => (mkBlock(assignment), res) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 6448c28e21..e8a2c9f43c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -198,13 +198,14 @@ trait MethodSynthesis { if (nme.isSetterName(name)) ValOrValWithSetterSuffixError(tree) - val getter = Getter(tree).createAndEnterSymbol() - tree.symbol = ( - if (mods.isLazy) enterLazyVal(tree, getter) - else { + if (mods.isLazy) { + val lazyValGetter = LazyValGetter(tree).createAndEnterSymbol() + enterLazyVal(tree, lazyValGetter) + } else { if (mods.isPrivateLocal) PrivateThisCaseClassParameterError(tree) + val getter = Getter(tree).createAndEnterSymbol() // Create the setter if necessary. if (mods.isMutable) Setter(tree).createAndEnterSymbol() @@ -219,7 +220,7 @@ trait MethodSynthesis { } def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { - case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) && !vd.symbol.isLazy => + case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations ( allValDefDerived(vd) @@ -247,6 +248,7 @@ trait MethodSynthesis { def standardAccessors(vd: ValDef): List[DerivedFromValDef] = ( if (vd.mods.isMutable && !vd.mods.isLazy) List(Getter(vd), Setter(vd)) + else if (vd.mods.isLazy) List(LazyValGetter(vd)) else List(Getter(vd)) ) def beanAccessors(vd: ValDef): List[DerivedFromValDef] = { @@ -259,10 +261,15 @@ trait MethodSynthesis { else Nil } def allValDefDerived(vd: ValDef) = { - val field = if (vd.mods.isDeferred) Nil else List(Field(vd)) + val field = if (vd.mods.isDeferred || (vd.mods.isLazy && hasUnitType(vd.symbol))) Nil + else List(Field(vd)) field ::: standardAccessors(vd) ::: beanAccessors(vd) } + // Take into account annotations so that we keep annotated unit lazy val + // to get better error message already from the cps plugin itself + def hasUnitType(sym: Symbol) = (sym.tpe.typeSymbol == UnitClass) && sym.tpe.annotations.isEmpty + /** This trait assembles what's needed for synthesizing derived methods. * Important: Typically, instances of this trait are created TWICE for each derived * symbol; once form Namers in an enter method, and once from Typers in addDerivedTrees. @@ -388,16 +395,12 @@ trait MethodSynthesis { def name: TermName = tree.name.toTermName } - case class Getter(tree: ValDef) extends DerivedGetter { + abstract class BaseGetter(tree: ValDef) extends DerivedGetter { def name = tree.name def category = GetterTargetClass def flagsMask = GetterFlags def flagsExtra = ACCESSOR | ( if (tree.mods.isMutable) 0 else STABLE ) - override def derivedSym = ( - if (mods.isDeferred) basisSym - else basisSym.getter(enclClass) - ) override def validate() { assert(derivedSym != NoSymbol, tree) if (derivedSym.isOverloaded) @@ -405,6 +408,13 @@ trait MethodSynthesis { super.validate() } + } + case class Getter(tree: ValDef) extends BaseGetter(tree) { + override def derivedSym = ( + if (mods.isDeferred) basisSym + else basisSym.getter(enclClass) + ) + override def derivedTree: DefDef = { // For existentials, don't specify a type for the getter, even one derived // from the symbol! This leads to incompatible existentials for the field and @@ -437,6 +447,45 @@ trait MethodSynthesis { } } } + /** Implements lazy value accessors: + * - for lazy values of type Unit and all lazy fields inside traits, + * the rhs is the initializer itself + * - for all other lazy values z the accessor is a block of this form: + * { z = <rhs>; z } where z can be an identifier or a field. + */ + case class LazyValGetter(tree: ValDef) extends BaseGetter(tree) { + class ChangeOwnerAndModuleClassTraverser(oldowner: Symbol, newowner: Symbol) + extends ChangeOwnerTraverser(oldowner, newowner) { + + override def traverse(tree: Tree) { + tree match { + case _: DefTree => change(tree.symbol.moduleClass) + case _ => + } + super.traverse(tree) + } + } + + // todo: in future this should be enabled but now other phases still depend on the flag for various reasons + //override def flagsMask = (super.flagsMask & ~LAZY) + override def derivedSym = basisSym.lazyAccessor + override def derivedTree: DefDef = { + val ValDef(_, _, tpt0, rhs0) = tree + val rhs1 = transformed.getOrElse(rhs0, rhs0) + val body = ( + if (tree.symbol.owner.isTrait || hasUnitType(basisSym)) rhs1 + else gen.mkAssignAndReturn(basisSym, rhs1) + ) + derivedSym.setPos(tree.pos) // cannot set it at createAndEnterSymbol because basisSym can possible stil have NoPosition + val ddefRes = atPos(tree.pos)(DefDef(derivedSym, new ChangeOwnerAndModuleClassTraverser(basisSym, derivedSym)(body))) + // ValDef will have its position focused whereas DefDef will have original correct rangepos + // ideally positions would be correct at the creation time but lazy vals are really a special case + // here so for the sake of keeping api clean we fix positions manually in LazyValGetter + ddefRes.tpt.setPos(tpt0.pos) + tpt0.setPos(tpt0.pos.focus) + ddefRes + } + } case class Setter(tree: ValDef) extends DerivedSetter { def name = nme.getterToSetter(tree.name) def category = SetterTargetClass @@ -455,6 +504,7 @@ trait MethodSynthesis { override def keepClean = !mods.isParamAccessor override def derivedTree = ( if (mods.isDeferred) EmptyTree + else if (mods.isLazy) copyValDef(tree)(mods = mods | flagsExtra, name = this.name, rhs = EmptyTree).setPos(tree.pos.focus) else copyValDef(tree)(mods = mods | flagsExtra, name = this.name) ) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index e3b1ae50e4..f5d4df14fe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -113,10 +113,8 @@ trait Namers extends MethodSynthesis { || (context.unit.isJava) ) def noFinishGetterSetter(vd: ValDef) = ( - vd.mods.isPrivateLocal - || vd.symbol.isModuleVar - || vd.symbol.isLazy - ) + (vd.mods.isPrivateLocal && !vd.mods.isLazy) // all lazy vals need accessors, even private[this] + || vd.symbol.isModuleVar) def setPrivateWithin[T <: Symbol](tree: Tree, sym: T, mods: Modifiers): T = if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym @@ -400,7 +398,7 @@ trait Namers extends MethodSynthesis { * a module definition or a class definition. */ def enterModuleSymbol(tree : ModuleDef): Symbol = { - var m: Symbol = context.scope.lookup(tree.name) + var m: Symbol = context.scope lookupAll tree.name find (_.isModule) getOrElse NoSymbol val moduleFlags = tree.mods.flags | MODULE if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) { updatePosFlags(m, tree.pos, moduleFlags) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 5beba77155..7d504d8c81 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1376,10 +1376,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL t.symbol.owner = currentOwner case d : DefTree if (d.symbol != NoSymbol) && ((d.symbol.owner == NoSymbol) || (d.symbol.owner == origOwner)) => // don't indiscriminately change existing owners! (see e.g., pos/t3440, pos/t3534, pos/unapplyContexts2) patmatDebug("def: "+ (d, d.symbol.ownerChain, currentOwner.ownerChain)) - if(d.symbol.isLazy) { // for lazy val's accessor -- is there no tree?? - assert(d.symbol.lazyAccessor != NoSymbol && d.symbol.lazyAccessor.owner == d.symbol.owner, d.symbol.lazyAccessor) - d.symbol.lazyAccessor.owner = currentOwner - } if(d.symbol.moduleClass ne NoSymbol) d.symbol.moduleClass.owner = currentOwner diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 9aec8c142b..c1dc91dbfc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1024,15 +1024,18 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans private def enterSyms(stats: List[Tree]) { var index = -1 for (stat <- stats) { - index = index + 1; + index = index + 1 + def enterSym(sym: Symbol) = if (sym.isLocal) { + currentLevel.scope.enter(sym) + symIndex(sym) = index + } + stat match { + case DefDef(_, _, _, _, _, _) if stat.symbol.isLazy => + enterSym(stat.symbol) case ClassDef(_, _, _, _) | DefDef(_, _, _, _, _, _) | ModuleDef(_, _, _) | ValDef(_, _, _, _) => //assert(stat.symbol != NoSymbol, stat);//debug - val sym = stat.symbol.lazyAccessorOrSelf - if (sym.isLocal) { - currentLevel.scope.enter(sym) - symIndex(sym) = index; - } + enterSym(stat.symbol.lazyAccessorOrSelf) case _ => } } @@ -1297,34 +1300,6 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans }) } - /** Implements lazy value accessors: - * - for lazy values of type Unit and all lazy fields inside traits, - * the rhs is the initializer itself - * - for all other lazy values z the accessor is a block of this form: - * { z = <rhs>; z } where z can be an identifier or a field. - */ - private def makeLazyAccessor(tree: Tree, rhs: Tree): List[Tree] = { - val vsym = tree.symbol - assert(vsym.isTerm, vsym) - val hasUnitType = vsym.tpe.typeSymbol == UnitClass - val lazySym = vsym.lazyAccessor - assert(lazySym != NoSymbol, vsym) - - // for traits, this is further transformed in mixins - val body = ( - if (tree.symbol.owner.isTrait || hasUnitType) rhs - else gen.mkAssignAndReturn(vsym, rhs) - ) - val lazyDef = atPos(tree.pos)(DefDef(lazySym, body.changeOwner(vsym -> lazySym))) - debuglog("Created lazy accessor: " + lazyDef) - - if (hasUnitType) List(typed(lazyDef)) - else List( - typed(ValDef(vsym)), - afterRefchecks(typed(lazyDef)) - ) - } - def transformStat(tree: Tree, index: Int): List[Tree] = tree match { case t if treeInfo.isSelfConstrCall(t) => assert(index == 0, index) @@ -1337,8 +1312,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case ModuleDef(_, _, _) => eliminateModuleDefs(tree) case ValDef(_, _, _, _) => val tree1 @ ValDef(_, _, _, rhs) = transform(tree) // important to do before forward reference check - if (tree.symbol.isLazy) - makeLazyAccessor(tree, rhs) + if (tree1.symbol.isLazy) tree1 :: Nil else { val lazySym = tree.symbol.lazyAccessorOrSelf if (lazySym.isLocal && index <= currentLevel.maxindex) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d51ebc7d08..df3731794a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1423,9 +1423,6 @@ trait Typers extends Modes with Adaptations with Tags { //see https://issues.scala-lang.org/browse/SI-6463 case _: ClassDef => implRestriction(tree, "nested class") - case x: ValDef if x.mods.isLazy => - //see https://issues.scala-lang.org/browse/SI-6358 - implRestriction(tree, "lazy val") case Select(sup @ Super(qual, mix), selector) if selector != nme.CONSTRUCTOR && qual.symbol == clazz && mix != tpnme.EMPTY => //see https://issues.scala-lang.org/browse/SI-6483 implRestriction(sup, "qualified super reference") @@ -1911,7 +1908,7 @@ trait Typers extends Modes with Adaptations with Tags { } val rhs1 = if (vdef.rhs.isEmpty) { - if (sym.isVariable && sym.owner.isTerm && !isPastTyper) + if (sym.isVariable && sym.owner.isTerm && !sym.isLazy && !isPastTyper) LocalVarUninitializedError(vdef) vdef.rhs } else { @@ -2337,9 +2334,15 @@ trait Typers extends Modes with Adaptations with Tags { case _ => } } - val stats1 = typedStats(block.stats, context.owner) + val stats1 = if (isPastTyper) block.stats else + block.stats.flatMap(stat => stat match { + case vd@ValDef(_, _, _, _) if vd.symbol.isLazy => + namer.addDerivedTrees(Typer.this, vd) + case _ => stat::Nil + }) + val stats2 = typedStats(stats1, context.owner) val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt) - treeCopy.Block(block, stats1, expr1) + treeCopy.Block(block, stats2, expr1) .setType(if (treeInfo.isExprSafeToInline(block)) expr1.tpe else expr1.tpe.deconst) } finally { // enable escaping privates checking from the outside and recycle diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index 66987d833b..dde53dc640 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -100,10 +100,10 @@ object DocStrings { * can override the parent symbol's sections */ def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = { - idxs.indexWhere(str.substring(_).startsWith("@usecase")) match { + idxs.indexWhere(str.startsWith("@usecase", _)) match { case firstUCIndex if firstUCIndex != -1 => val commentSections = idxs.take(firstUCIndex) - val usecaseSections = idxs.drop(firstUCIndex).filter(str.substring(_).startsWith("@usecase")) + val usecaseSections = idxs.drop(firstUCIndex).filter(str.startsWith("@usecase", _)) commentSections ::: usecaseSections case _ => idxs @@ -114,7 +114,7 @@ object DocStrings { * Merge the inheritdoc sections, as they never make sense on their own */ def mergeInheritdocSections(str: String, idxs: List[Int]): List[Int] = - idxs.filterNot(str.substring(_).startsWith("@inheritdoc")) + idxs.filterNot(str.startsWith("@inheritdoc", _)) /** Does interval `iv` start with given `tag`? */ @@ -190,11 +190,12 @@ object DocStrings { /** Extract the section parameter */ def extractSectionParam(str: String, section: (Int, Int)): String = { - assert(str.substring(section._1).startsWith("@param") || - str.substring(section._1).startsWith("@tparam") || - str.substring(section._1).startsWith("@throws")) + val (beg, _) = section + assert(str.startsWith("@param", beg) || + str.startsWith("@tparam", beg) || + str.startsWith("@throws", beg)) - val start = skipWhitespace(str, skipTag(str, section._1)) + val start = skipWhitespace(str, skipTag(str, beg)) val finish = skipIdent(str, start) str.substring(start, finish) @@ -202,12 +203,13 @@ object DocStrings { /** Extract the section text, except for the tag and comment newlines */ def extractSectionText(str: String, section: (Int, Int)): (Int, Int) = { - if (str.substring(section._1).startsWith("@param") || - str.substring(section._1).startsWith("@tparam") || - str.substring(section._1).startsWith("@throws")) - (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, section._1)))), section._2) + val (beg, end) = section + if (str.startsWith("@param", beg) || + str.startsWith("@tparam", beg) || + str.startsWith("@throws", beg)) + (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, beg)))), end) else - (skipWhitespace(str, skipTag(str, section._1)), section._2) + (skipWhitespace(str, skipTag(str, beg)), end) } /** Cleanup section text */ diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index b373b3d0de..15025f85e3 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -496,7 +496,11 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { case ValDef(mods, name, tpt, rhs) => vprintln("[checker] checking valdef " + name + "/"+tpe+"/"+tpt+"/"+tree.symbol.tpe) // ValDef symbols must *not* have annotations! - if (hasAnswerTypeAnn(tree.symbol.info)) { // is it okay to modify sym here? + // lazy vals are currently not supported + // but if we erase here all annotations, compiler will complain only + // when generating bytecode. + // This way lazy vals will be reported as unsupported feature later rather than weird type error. + if (hasAnswerTypeAnn(tree.symbol.info) && !mods.isLazy) { // is it okay to modify sym here? vprintln("removing annotation from sym " + tree.symbol + "/" + tree.symbol.tpe + "/" + tpt) tpt modifyType removeAllCPSAnnotations tree.symbol modifyInfo removeAllCPSAnnotations diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index ba87cadfeb..8b39bf3961 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -195,9 +195,12 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with case _ => if (hasAnswerTypeAnn(tree.tpe)) { - if (!cpsAllowed) - unit.error(tree.pos, "cps code not allowed here / " + tree.getClass + " / " + tree) - + if (!cpsAllowed) { + if (tree.symbol.isLazy) + unit.error(tree.pos, "implementation restriction: cps annotations not allowed on lazy value definitions") + else + unit.error(tree.pos, "cps code not allowed here / " + tree.getClass + " / " + tree) + } log(tree) } diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index f72547724d..8be0cb1619 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -120,7 +120,7 @@ case class StringContext(parts: String*) { val bldr = new java.lang.StringBuilder(process(pi.next())) while (ai.hasNext) { bldr append ai.next - bldr append treatEscapes(pi.next()) + bldr append process(pi.next()) } bldr.toString } diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 84f6f0be9c..d3f8df9110 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -95,7 +95,10 @@ package object scala { val Equiv = scala.math.Equiv type Fractional[T] = scala.math.Fractional[T] + val Fractional = scala.math.Fractional + type Integral[T] = scala.math.Integral[T] + val Integral = scala.math.Integral type Numeric[T] = scala.math.Numeric[T] val Numeric = scala.math.Numeric diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala index 2e494cc82f..c21c0daa5e 100644 --- a/src/library/scala/sys/process/ProcessImpl.scala +++ b/src/library/scala/sys/process/ProcessImpl.scala @@ -222,7 +222,10 @@ private[process] trait ProcessImpl { p.exitValue() } override def destroy() = { - try p.destroy() + try{ + outputThreads foreach (_.stop()) + p.destroy() + } finally inputThread.interrupt() } } diff --git a/src/manual/scala/man1/scaladoc.scala b/src/manual/scala/man1/scaladoc.scala index a9facf1433..34c58b6b8e 100644 --- a/src/manual/scala/man1/scaladoc.scala +++ b/src/manual/scala/man1/scaladoc.scala @@ -75,7 +75,10 @@ object scaladoc extends Command { "Define the overall version number of the documentation, typically the version of the library being documented."), Definition( CmdOption("doc-source-url", Argument("url")), - "Define a URL to be concatenated with source locations for link to source files."))), + "Define a URL to be concatenated with source locations for link to source files."), + Definition( + CmdOption("doc-external-uris", Argument("external-doc")), + "Define comma-separated list of file://classpath_entry_path#doc_URL URIs for linking to external dependencies."))), Section("Compiler Options", DefinitionList( diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 53b40da8f6..74bde132cb 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1300,25 +1300,26 @@ trait Trees extends api.Trees { self: SymbolTable => } class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser { - def changeOwner(tree: Tree) = tree match { - case Return(expr) => - if (tree.symbol == oldowner) { - // SI-5612 - if (newowner hasTransOwner oldowner) - log("NOT changing owner of %s because %s is nested in %s".format(tree, newowner, oldowner)) - else { - log("changing owner of %s: %s => %s".format(tree, oldowner, newowner)) - tree.symbol = newowner - } - } - case _: DefTree | _: Function => - if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner) { - tree.symbol.owner = newowner - } - case _ => + final def change(sym: Symbol) = { + if (sym != NoSymbol && sym.owner == oldowner) + sym.owner = newowner } override def traverse(tree: Tree) { - changeOwner(tree) + tree match { + case _: Return => + if (tree.symbol == oldowner) { + // SI-5612 + if (newowner hasTransOwner oldowner) + log("NOT changing owner of %s because %s is nested in %s".format(tree, newowner, oldowner)) + else { + log("changing owner of %s: %s => %s".format(tree, oldowner, newowner)) + tree.symbol = newowner + } + } + case _: DefTree | _: Function => + change(tree.symbol) + case _ => + } super.traverse(tree) } } diff --git a/src/swing/scala/swing/ColorChooser.scala b/src/swing/scala/swing/ColorChooser.scala new file mode 100644 index 0000000000..9bd71e1df0 --- /dev/null +++ b/src/swing/scala/swing/ColorChooser.scala @@ -0,0 +1,45 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2012, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.swing + +import javax.swing.JColorChooser +import event._ + +/** + * Wrapper for JColorChooser. Publishes `ColorChanged` events, when the color selection changes. + * + * @author andy@hicks.net + * @author Ingo Maier + * @see javax.swing.JColorChooser + */ +object ColorChooser { + def showDialog(parent: Component, title: String, color: Color): scala.Option[Color] = { + toOption[Color](javax.swing.JColorChooser.showDialog(parent.peer, title, color)) + } +} + +class ColorChooser(color0: Color) extends Component { + def this() = this(java.awt.Color.white) + + override lazy val peer: JColorChooser = new JColorChooser(color0) with SuperMixin + + peer.getSelectionModel.addChangeListener(new javax.swing.event.ChangeListener { + def stateChanged(e: javax.swing.event.ChangeEvent) { + publish(ColorChanged(ColorChooser.this, peer.getColor)) + } + }) + + def color: Color = peer.getColor + def color_=(c: Color) = peer.setColor(c) + + def dragEnabled: Boolean = peer.getDragEnabled + def dragEnabled_=(b: Boolean) = peer.setDragEnabled(b) +}
\ No newline at end of file diff --git a/src/swing/scala/swing/PopupMenu.scala b/src/swing/scala/swing/PopupMenu.scala new file mode 100644 index 0000000000..0f292b11a2 --- /dev/null +++ b/src/swing/scala/swing/PopupMenu.scala @@ -0,0 +1,65 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2012, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.swing + +import javax.swing.JPopupMenu +import javax.swing.event.{PopupMenuListener, PopupMenuEvent} +import event._ + +/** + * A popup menu. + * + * Example usage: + * + * {{{ + * val popupMenu = new PopupMenu { + * contents += new Menu("menu 1") { + * contents += new RadioMenuItem("radio 1.1") + * contents += new RadioMenuItem("radio 1.2") + * } + * contents += new Menu("menu 2") { + * contents += new RadioMenuItem("radio 2.1") + * contents += new RadioMenuItem("radio 2.2") + * } + * } + * val button = new Button("Show Popup Menu") + * reactions += { + * case e: ButtonClicked => popupMenu.show(button, 0, button.bounds.height) + * } + * listenTo(button) + * }}} + * + * @author John Sullivan + * @author Ingo Maier + * @see javax.swing.JPopupMenu + */ +class PopupMenu extends Component with SequentialContainer.Wrapper with Publisher { + override lazy val peer: JPopupMenu = new JPopupMenu with SuperMixin + + peer.addPopupMenuListener(new PopupMenuListener { + def popupMenuCanceled(e: PopupMenuEvent) { + publish(PopupMenuCanceled(PopupMenu.this)) + } + def popupMenuWillBecomeInvisible(e: PopupMenuEvent) { + publish(PopupMenuWillBecomeInvisible(PopupMenu.this)) + } + def popupMenuWillBecomeVisible(e: PopupMenuEvent) { + publish(PopupMenuWillBecomeVisible(PopupMenu.this)) + } + }) + + def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y) + + def margin: Insets = peer.getMargin + def label: String = peer.getLabel + def label_=(s: String) { peer.setLabel(s) } +} + diff --git a/src/swing/scala/swing/event/ColorChanged.scala b/src/swing/scala/swing/event/ColorChanged.scala new file mode 100644 index 0000000000..44387aa864 --- /dev/null +++ b/src/swing/scala/swing/event/ColorChanged.scala @@ -0,0 +1,14 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.swing +package event + +case class ColorChanged(source: Component, c: Color) extends ComponentEvent with SelectionEvent diff --git a/src/swing/scala/swing/event/PopupMenuEvent.scala b/src/swing/scala/swing/event/PopupMenuEvent.scala new file mode 100644 index 0000000000..f7083c06de --- /dev/null +++ b/src/swing/scala/swing/event/PopupMenuEvent.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2012, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + + +package scala.swing +package event + +abstract class PopupMenuEvent extends ComponentEvent + +case class PopupMenuCanceled(source: PopupMenu) extends PopupMenuEvent +case class PopupMenuWillBecomeInvisible(source: PopupMenu) extends PopupMenuEvent +case class PopupMenuWillBecomeVisible(source: PopupMenu) extends PopupMenuEvent
\ No newline at end of file diff --git a/test/files/continuations-neg/lazy.check b/test/files/continuations-neg/lazy.check index b8c6887409..3c460546be 100644 --- a/test/files/continuations-neg/lazy.check +++ b/test/files/continuations-neg/lazy.check @@ -1,6 +1,4 @@ -lazy.scala:5: error: type mismatch; - found : Unit @scala.util.continuations.cpsParam[Unit,Unit] - required: Unit - def foo() = { - ^ +lazy.scala:6: error: implementation restriction: cps annotations not allowed on lazy value definitions + lazy val x = shift((k:Unit=>Unit)=>k()) + ^ one error found diff --git a/test/files/neg/t6597.check b/test/files/neg/t6597.check new file mode 100644 index 0000000000..1d52519d1d --- /dev/null +++ b/test/files/neg/t6597.check @@ -0,0 +1,4 @@ +t6597.scala:3: error: illegal combination of modifiers: implicit and case for: class Quux + implicit case class Quux(value: Int) extends AnyVal with T + ^ +one error found diff --git a/test/files/neg/t6597.scala b/test/files/neg/t6597.scala new file mode 100644 index 0000000000..dde53bcc89 --- /dev/null +++ b/test/files/neg/t6597.scala @@ -0,0 +1,5 @@ +object Test { + trait T extends Any + implicit case class Quux(value: Int) extends AnyVal with T + object Quux +} diff --git a/test/files/neg/valueclasses-impl-restrictions.check b/test/files/neg/valueclasses-impl-restrictions.check index 17d07ba960..63924493aa 100644 --- a/test/files/neg/valueclasses-impl-restrictions.check +++ b/test/files/neg/valueclasses-impl-restrictions.check @@ -2,20 +2,16 @@ valueclasses-impl-restrictions.scala:3: error: implementation restriction: neste This restriction is planned to be removed in subsequent releases. object X ^ -valueclasses-impl-restrictions.scala:4: error: implementation restriction: lazy val is not allowed in value class -This restriction is planned to be removed in subsequent releases. - lazy val y = 1 - ^ -valueclasses-impl-restrictions.scala:10: error: implementation restriction: nested trait is not allowed in value class +valueclasses-impl-restrictions.scala:9: error: implementation restriction: nested trait is not allowed in value class This restriction is planned to be removed in subsequent releases. trait I2 { ^ -valueclasses-impl-restrictions.scala:16: error: implementation restriction: nested class is not allowed in value class +valueclasses-impl-restrictions.scala:15: error: implementation restriction: nested class is not allowed in value class This restriction is planned to be removed in subsequent releases. val i2 = new I2 { val q = x.s } ^ -valueclasses-impl-restrictions.scala:22: error: implementation restriction: nested class is not allowed in value class +valueclasses-impl-restrictions.scala:21: error: implementation restriction: nested class is not allowed in value class This restriction is planned to be removed in subsequent releases. private[this] class I2(val q: String) ^ -5 errors found +four errors found diff --git a/test/files/neg/valueclasses-impl-restrictions.scala b/test/files/neg/valueclasses-impl-restrictions.scala index 53396db958..137f3f854c 100644 --- a/test/files/neg/valueclasses-impl-restrictions.scala +++ b/test/files/neg/valueclasses-impl-restrictions.scala @@ -1,7 +1,6 @@ class M(val t: Int) extends AnyVal { def lazyString = { object X - lazy val y = 1 () => X } } diff --git a/test/files/pos/t6358.scala b/test/files/pos/t6358.scala new file mode 100644 index 0000000000..25539c885e --- /dev/null +++ b/test/files/pos/t6358.scala @@ -0,0 +1,6 @@ +class L(val t: Int) extends AnyVal { + def lazyString = { + lazy val x = t.toString + () => x + } +} diff --git a/test/files/pos/t6358_2.scala b/test/files/pos/t6358_2.scala new file mode 100644 index 0000000000..7c2beb60d0 --- /dev/null +++ b/test/files/pos/t6358_2.scala @@ -0,0 +1,6 @@ +class Y[T](val i: Option[T]) extends AnyVal { + def q: List[T] = { + lazy val e: List[T] = i.toList + e + } +} diff --git a/test/files/run/reify_lazyunit.check b/test/files/run/reify_lazyunit.check new file mode 100644 index 0000000000..1b46c909be --- /dev/null +++ b/test/files/run/reify_lazyunit.check @@ -0,0 +1,3 @@ +12 +one +two diff --git a/test/files/run/reify_lazyunit.scala b/test/files/run/reify_lazyunit.scala new file mode 100644 index 0000000000..78b00cde28 --- /dev/null +++ b/test/files/run/reify_lazyunit.scala @@ -0,0 +1,13 @@ +import scala.reflect.runtime.universe._ +import scala.tools.reflect.Eval + +object Test extends App { + reify { + lazy val x = { 0; println("12")} + x + println("one") + x + println("two") + }.eval +} + diff --git a/test/files/run/t6488.check b/test/files/run/t6488.check new file mode 100644 index 0000000000..35821117c8 --- /dev/null +++ b/test/files/run/t6488.check @@ -0,0 +1 @@ +Success diff --git a/test/files/run/t6488.scala b/test/files/run/t6488.scala new file mode 100644 index 0000000000..487614ecfd --- /dev/null +++ b/test/files/run/t6488.scala @@ -0,0 +1,11 @@ +import sys.process._ +object Test { + // Program that prints "Success" if the command was successfully run then destroyed + // It will silently pass if the command "/bin/ls" does not exist + // It will fail due to the uncatchable exception in t6488 race condition + def main(args: Array[String]) { + try Process("/bin/ls").run(ProcessLogger { _ => () }).destroy + catch { case _ => () } + println("Success") + } +} diff --git a/test/files/run/t6559.scala b/test/files/run/t6559.scala new file mode 100644 index 0000000000..5c671f7275 --- /dev/null +++ b/test/files/run/t6559.scala @@ -0,0 +1,17 @@ + +object Test { + + def main(args: Array[String]) = { + val one = "1" + val two = "2" + + val raw = raw"\n$one\n$two\n" + val escaped = s"\n$one\n$two\n" + val buggy = "\\n1\n2\n" + val correct = "\\n1\\n2\\n" + + assert(raw != escaped, "Raw strings should not be escaped.") + assert(raw != buggy, "Raw strings after variables should not be escaped.") + assert(raw == correct, "Raw strings should stay raw.") + } +} diff --git a/test/scaladoc/run/SI-191-deprecated.check b/test/scaladoc/run/SI-191-deprecated.check new file mode 100755 index 0000000000..3925a0d464 --- /dev/null +++ b/test/scaladoc/run/SI-191-deprecated.check @@ -0,0 +1 @@ +Done.
\ No newline at end of file diff --git a/test/scaladoc/run/SI-191-deprecated.scala b/test/scaladoc/run/SI-191-deprecated.scala new file mode 100755 index 0000000000..746aa9c598 --- /dev/null +++ b/test/scaladoc/run/SI-191-deprecated.scala @@ -0,0 +1,71 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.comment._ +import scala.tools.partest.ScaladocModelTest +import java.net.{URI, URL} +import java.io.File + +object Test extends ScaladocModelTest { + + override def code = + """ + /** See: + * - [[scala.collection.Map]] Simple linking + * - [[scala.collection.immutable.::]] Linking with symbolic name + * - [[scala.Int]].toLong Linking to a class + * - [[scala.Predef]] Linking to an object + * - [[scala.Int.toLong]] Linking to a method + * - [[scala]] Linking to a package + * - [[scala.AbstractMethodError]] Linking to a member in the package object + * - [[scala.Predef.String]] Linking to a member in an object + * + * Don't look at: + * - [[scala.NoLink]] Not linking :) + */ + object Test { + def foo(param: Any) {} + def barr(l: scala.collection.immutable.List[Any]) {} + def bar(l: List[String]) {} // TODO: Should be able to link to type aliases + def baz(d: java.util.Date) {} // Should not be resolved + } + """ + + def scalaURL = "http://bog.us" + + override def scaladocSettings = "-no-link-warnings -external-urls scala=" + scalaURL + + def testModel(rootPackage: Package) { + import access._ + val test = rootPackage._object("Test") + + def check(memberDef: Def, expected: Int) { + val externals = memberDef.valueParams(0)(0).resultType.refEntity collect { + case (_, (LinkToExternal(name, url), _)) => assert(url.contains(scalaURL)); name + } + assert(externals.size == expected) + } + + check(test._method("foo"), 1) + check(test._method("bar"), 0) + check(test._method("barr"), 2) + check(test._method("baz"), 0) + + val expectedUrls = collection.mutable.Set[String]( + "scala.collection.Map", + "scala.collection.immutable.::", + "scala.Int", + "scala.Predef$", + "scala.Int@toLong:Long", + "scala.package", + "scala.package@AbstractMethodError=AbstractMethodError", + "scala.Predef$@String=String" + ).map(scalaURL + "/index.html#" + _) + + def isExpectedExternalLink(l: EntityLink) = l.link match { + case LinkToExternal(name, url) => assert(expectedUrls contains url, url); true + case _ => false + } + + assert(countLinks(test.comment.get, isExpectedExternalLink) == 8, + countLinks(test.comment.get, isExpectedExternalLink) + " == 8") + } +} diff --git a/test/scaladoc/run/SI-191.check b/test/scaladoc/run/SI-191.check new file mode 100755 index 0000000000..3925a0d464 --- /dev/null +++ b/test/scaladoc/run/SI-191.check @@ -0,0 +1 @@ +Done.
\ No newline at end of file diff --git a/test/scaladoc/run/SI-191.scala b/test/scaladoc/run/SI-191.scala new file mode 100755 index 0000000000..0fb28145c3 --- /dev/null +++ b/test/scaladoc/run/SI-191.scala @@ -0,0 +1,76 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.comment._ +import scala.tools.partest.ScaladocModelTest +import java.net.{URI, URL} +import java.io.File + +object Test extends ScaladocModelTest { + + override def code = + """ + /** See: + * - [[scala.collection.Map]] Simple linking + * - [[scala.collection.immutable.::]] Linking with symbolic name + * - [[scala.Int]].toLong Linking to a class + * - [[scala.Predef]] Linking to an object + * - [[scala.Int.toLong]] Linking to a method + * - [[scala]] Linking to a package + * - [[scala.AbstractMethodError]] Linking to a member in the package object + * - [[scala.Predef.String]] Linking to a member in an object + * + * Don't look at: + * - [[scala.NoLink]] Not linking :) + */ + object Test { + def foo(param: Any) {} + def barr(l: scala.collection.immutable.List[Any]) {} + def bar(l: List[String]) {} // TODO: Should be able to link to type aliases + def baz(d: java.util.Date) {} // Should not be resolved + } + """ + + def scalaURL = "http://bog.us" + + override def scaladocSettings = { + val scalaLibUri = getClass.getClassLoader.getResource("scala/Function1.class").toURI.getSchemeSpecificPart.split("!")(0) + val scalaLib = new File(new URL(scalaLibUri).getPath).getPath + val extArg = new URI("file", scalaLib, scalaURL).toString + "-no-link-warnings -doc-external-uris " + extArg + } + + def testModel(rootPackage: Package) { + import access._ + val test = rootPackage._object("Test") + + def check(memberDef: Def, expected: Int) { + val externals = memberDef.valueParams(0)(0).resultType.refEntity collect { + case (_, (LinkToExternal(name, url), _)) => assert(url.contains(scalaURL)); name + } + assert(externals.size == expected) + } + + check(test._method("foo"), 1) + check(test._method("bar"), 0) + check(test._method("barr"), 2) + check(test._method("baz"), 0) + + val expectedUrls = collection.mutable.Set[String]( + "scala.collection.Map", + "scala.collection.immutable.::", + "scala.Int", + "scala.Predef$", + "scala.Int@toLong:Long", + "scala.package", + "scala.package@AbstractMethodError=AbstractMethodError", + "scala.Predef$@String=String" + ).map(scalaURL + "/index.html#" + _) + + def isExpectedExternalLink(l: EntityLink) = l.link match { + case LinkToExternal(name, url) => assert(expectedUrls contains url, url); true + case _ => false + } + + assert(countLinks(test.comment.get, isExpectedExternalLink) == 8, + countLinks(test.comment.get, isExpectedExternalLink) + " == 8") + } +} |