Hi,(I'm just reporting, I don't intend to act on this before 2.10.1.)
I can't even bear to consider how many of my "lost 1000 hours" in the
pattern matcher swirled around them. There's nothing quite like
trying to fix something which doesn't work right, where you have to
examine usages which are known to work correctly to know how these are
supposed to work, except there aren't any.
(I'm just reporting, I don't intend to act on this before 2.10.1.)That's the only thing I don't agree with in this e-mail. Ship it in 2.10 please, please
A meta observation: if you were to leave that change to 2.11, you'd be
left in the awkward position of breaking the public API of Trees [1].
Perhaps you need to reserve the right to break this part of the API at
each major revision of the compiler, rather than going through a
deprecation cycle.
-jason
[1] https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Trees.scala#L438
This occurred to me as well. Macros that do anything more than reify
code are bound to break much more often than normal code is. It's
unreasonable to expect _generated code_ (well, generated ASTs) to
remain stable even at the bug fix level.
Perhaps the expectations that macro writers can -- and cannot -- have
should be clearly enunciated.
--
Daniel C. Sobral
I travel to the future all the time.
I'm reasonably happy with Trees, happy for me anyway. But I always have a list.
// Weird "tree-like" not-Trees which always demand special handling
// and could be better integrated
case class ImportSelector(name: Name, namePos: Int, rename: Name,
renamePos: Int)
case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree])
sealed abstract class AnnotationInfo // and its buddies, *AnnotArg etc.
// Trees which encode too many disparate things
ValDef: parameters, vals, vars, fields, self-types, ...
// Trees which are clunky
// it being divorced from constructor arguments and desugared so early
// is a constant source of pain and confusion
case class New(tpt: Tree) extends TermTree
// Given that there's a whole dedicated node called "UnApply", why do
// I have to use this ungodly structure to "UnApply" things.
case class UnApply(fun: Tree, args: List[Tree]) extends TermTree
object UnapplyPattern {
private object UnapplySeq {
def unapply(x: UnApply) = x match {
case UnApply(
Apply(TypeApply(Select(qual, nme.unapplySeq), List(tpt)), _),
List(ArrayValue(_, elems))) =>
Some((qual.symbol, tpt, elems))
case _ =>
None
}
}
def apply(x: UnApply): Pattern = x match {
case UnapplySeq(ListModule, tpt, elems) =>
ListExtractorPattern(x, tpt, elems)
case _ =>
ExtractorPattern(x)
}
}
// trees which feel hacky or which I think should be justified
case class Star(elem: Tree)
case class AssignOrNamedArg(lhs: Tree, rhs: Tree) extends TermTree
case class ReferenceToBoxed(ident: Ident) extends TermTree
// trees which could have clearer names
// How about "TypeRepresentation" or something, so we don't
// have to say "Not to be confused with 'TypeTree'..."
trait TypTree extends Tree
// It would be nice to have names for TypeApply and AppliedTypeTree
// which gave one a better chance to intuit the distinction.
case class AppliedTypeTree(tpt: Tree, args: List[Tree])
case class TypeApply(fun: Tree, args: List[Tree])
// This tree sounds less like what it is with each passing day
case class ApplyDynamic(qual: Tree, args: List[Tree])
// On the compiler side, but... I hope "TypeTreeWithDeferredRefCheck"
// is with us always, so when the right day arrives I can roll out
// "HackTreeContainingMysteryClosure" in good conscience.
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree)
extends TypTree
Yes, please! In scala-refactoring, I internally have an
ImportSelectorTree and ModifierTree. I also have a NameTree, and
there's a SuperConstructorCall and SelfTypeTree but these are less
problematic, they just make a few things easier for me, but the
ImportSelectorTree would be great to have.
Cheers,
Mirko
--
Mirko Stocker | m...@misto.ch
Work: http://ifs.hsr.ch | http://infoq.com
Personal: http://misto.ch | http://twitter.com/m_st
I keep meaning to add that. I did recently put qualifier on RefTree
so you can handle Ident and Select uniformly (on Ident, qualifier is
always EmptyTree.)
For me, the biggest pain with names is finding their position in the
source code. If you're courageous, here's the code:
> I did recently put qualifier on RefTree
> so you can handle Ident and Select uniformly (on Ident, qualifier is
> always EmptyTree.)
Cool, that could be useful.
Ha ha, don't you know I've already done about the same thing. At least twice.
In current master, grotesque code starts around here:
https://github.com/scala/scala/blob/master/src/compiler/scala/tools/nsc/interpreter/IMain.scala#L500
When I tried to fix the xml positions I broke the IDE and had to revert it:
commit 07fab88cee
Author: Paul Phillips <pa...@improving.org>
Date: 10 months ago
Reverts r25036, "Altered the positioning of XML...
Reverts r25036, "Altered the positioning of XML literal trees" because
the IDE did not like it. No review.
commit 92a2fd5397
Author: Paul Phillips <pa...@improving.org>
Date: 11 months ago
More adjustments to repl parsing to accomodate ...
More adjustments to repl parsing to accomodate inaccurately positioned
parse trees. No review.
commit 94e1965b64
Author: Paul Phillips <pa...@improving.org>
Date: 11 months ago
Altered the positioning of XML literal trees.
with the earliest position later than the earliest character in the
source code, which was breaking some repl logic. No review.
And then there is the substantial rewrite here:
https://github.com/paulp/scala/tree/topic/positions
Which takes the rather more appealing position (no pun intended) of
adding a "sourceCode" method to Position, so you can get the source
defined by the range without having a PhD in special casing.
https://github.com/paulp/scala/blob/topic/positions/src/compiler/scala/tools/nsc/util/Position.scala#L319