Skip to content
Permalink
Browse files

Removed BackquotedIdent.

In favor of a marker attachment using Attachment, as suggested in
comments. (The Attachment interface needs work.) I did this bit trying
to fix SI-5715, but it's still a bit elusive because the Ident node is
thrown away as soon as there's a member definition.

Also, as far as I can see this will if anything propagate the
backquotedness of an identifier less effectively than before, because
TreeCopiers don't copy attachments. Maybe that's on the "todo" list? The
whole idea seems to depend on their being propagated to copies.
  • Loading branch information
paulp committed May 3, 2012
1 parent ca74659 commit 0cb886ae44505334dd5e8408b9355a53bc00e578
@@ -389,12 +389,8 @@ trait Importers { self: SymbolTable =>
new This(importName(qual).toTypeName)
case from.Select(qual, name) =>
new Select(importTree(qual), importName(name))
case from.Ident(name) => tree match {
case _: from.BackQuotedIdent =>
new BackQuotedIdent(importName(name))
case _ =>
new Ident(importName(name))
}
case from.Ident(name) =>
new Ident(importName(name))
case from.ReferenceToBoxed(ident) =>
new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident })
case from.Literal(constant @ from.Constant(_)) =>
@@ -332,6 +332,11 @@ trait StdNames {
def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME

def isDeprecatedIdentifierName(name: Name) = name.toTermName match {
case nme.`then` | nme.`macro` => true
case _ => false
}

def isOpAssignmentName(name: Name) = name match {
case raw.NE | raw.LE | raw.GE | EMPTY => false
case _ =>
@@ -634,6 +639,7 @@ trait StdNames {
val lang: NameType = "lang"
val length: NameType = "length"
val lengthCompare: NameType = "lengthCompare"
val `macro` : NameType = "macro"
val macroThis : NameType = "_this"
val macroContext : NameType = "c"
val main: NameType = "main"
@@ -690,6 +696,7 @@ trait StdNames {
val staticModule : NameType = "staticModule"
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val `then` : NameType = "then"
val thisModuleType: NameType = "thisModuleType"
val this_ : NameType = "this"
val throw_ : NameType = "throw"
@@ -227,8 +227,11 @@ abstract class TreeInfo {

/** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
case _: BackQuotedIdent => false
case x: Ident => isVariableName(x.name)
case x: Ident => !x.isBackquoted && isVariableName(x.name)
case _ => false
}
def isDeprecatedIdentifier(tree: Tree): Boolean = tree match {
case x: Ident => !x.isBackquoted && nme.isDeprecatedIdentifierName(x.name)
case _ => false
}

@@ -373,11 +373,9 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
case Select(qualifier, name) =>
print(backquotedPath(qualifier), ".", symName(tree, name))

case bqid: BackQuotedIdent =>
print("`%s`" format symName(tree, bqid.name))

case Ident(name) =>
print(symName(tree, name))
case id @ Ident(name) =>
val str = symName(tree, name)
print( if (id.isBackquoted) "`" + str + "`" else str )

case Literal(x) =>
print(x.escapedStringValue)
@@ -1027,7 +1027,7 @@ self =>
val tok = in.token
val name = ident()
t = atPos(start) {
if (tok == BACKQUOTED_IDENT) new BackQuotedIdent(name)
if (tok == BACKQUOTED_IDENT) Ident(name) withAttachment BackquotedIdentifier
else Ident(name)
}
if (in.token == DOT) {
@@ -2506,7 +2506,6 @@ self =>
}
else {
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
funDefRest(start, nameOffset, mods, name)
}
@@ -2601,7 +2600,6 @@ self =>
newLinesOpt()
atPos(start, in.offset) {
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
// @M! a type alias as well as an abstract type may declare type parameters
val tparams = typeParamClauseOpt(name, null)
@@ -2660,7 +2658,6 @@ self =>
def classDef(start: Int, mods: Modifiers): ClassDef = {
in.nextToken
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
atPos(start, if (name == tpnme.ERROR) start else nameOffset) {
savingClassContextBounds {
@@ -2701,7 +2698,6 @@ self =>
def objectDef(start: Int, mods: Modifiers): ModuleDef = {
in.nextToken
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
val tstart = in.offset
atPos(start, if (name == nme.ERROR) start else nameOffset) {
@@ -1458,6 +1458,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
analyzer.ImplicitNotFoundMsg.check(sym) foreach { warn =>
unit.warning(tree.pos, "Invalid implicitNotFound message for %s%s:\n%s".format(sym, sym.locationString, warn))
}

case tpt@TypeTree() =>
if(tpt.original != null) {
tpt.original foreach {
@@ -16,6 +16,9 @@ trait Trees { self: Universe =>
type Modifiers >: Null <: AbsModifiers
val NoMods: Modifiers

// TODO - Where do I put this?
object BackquotedIdentifier

This comment has been minimized.

Copy link
@burmako

burmako May 17, 2012

There is the StdAtachments file, which, I think, should be a good place to put attachment payload classes.

abstract class AbsModifiers {
def modifiers: Set[Modifier]
def hasModifier(mod: Modifier): Boolean
@@ -96,6 +99,20 @@ trait Trees { self: Universe =>
case _ =>
rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att))
}

// a) why didn't this method already exist
// b) what is all this "Any" business?
// c) am I reverse-engineering this correctly? It shouldn't be hard
// to figure out what is attached.
def attachments: List[Any] = rawatt match {
case NoPosition => Nil
case NontrivialAttachment(pos, atts) => pos :: atts.toList
case x => List(x)
}
// Writing "Any" repeatedly to work within this structure
// is making my skin crawl.
def hasAttachment(x: Any) = attachments contains x

This comment has been minimized.

Copy link
@xeno-by

xeno-by May 3, 2012

Member

Martin has done a major refactoring to attachments, now they look much better.

This comment has been minimized.

Copy link
@paulp

paulp May 3, 2012

Author Contributor

Excellent, thanks.


def withAttachment(att: Any): this.type = { attach(att); this }
def detach(att: Any): Unit =
detach(att.getClass)
@@ -702,16 +719,13 @@ trait Trees { self: Universe =>
/** Identifier <name> */
case class Ident(name: Name) extends RefTree {
def qualifier: Tree = EmptyTree
def isBackquoted = this hasAttachment BackquotedIdentifier
}

def Ident(name: String): Ident

def Ident(sym: Symbol): Ident

// TODO remove this class, add a tree attachment to Ident to track whether it was backquoted
// copying trees will all too easily forget to distinguish subclasses
class BackQuotedIdent(name: Name) extends Ident(name)

/** Marks underlying reference to id as boxed.
* @pre: id must refer to a captured variable
* A reference such marked will refer to the boxed entity, no dereferencing
@@ -1163,11 +1177,11 @@ trait Trees { self: Universe =>
new This(qual.toTypeName).copyAttrs(tree)
def Select(tree: Tree, qualifier: Tree, selector: Name) =
new Select(qualifier, selector).copyAttrs(tree)
def Ident(tree: Tree, name: Name) =
(tree match { // TODO: use a tree attachment to track whether this identifier was backquoted
case _ : BackQuotedIdent => new BackQuotedIdent(name)
case _ => new Ident(name)
}).copyAttrs(tree)
def Ident(tree: Tree, name: Name) = {
val t = new Ident(name) copyAttrs tree
if (tree hasAttachment BackquotedIdentifier) t withAttachment BackquotedIdentifier
else t
}
def ReferenceToBoxed(tree: Tree, idt: Ident) =
new ReferenceToBoxed(idt).copyAttrs(tree)
def Literal(tree: Tree, value: Constant) =

3 comments on commit 0cb886a

@retronym

This comment has been minimized.

Copy link
Member

@retronym retronym replied May 17, 2012

Looks like attachments are propagated by copyAttrs, called by TreeCopiers.

https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Trees.scala#L293

@burmako

This comment has been minimized.

Copy link

@burmako burmako replied May 17, 2012

Yes, they are, and that's by design. Does this cause any problems?

@retronym

This comment has been minimized.

Copy link
Member

@retronym retronym replied May 17, 2012

I was responding to Paul's question in the commit comment.

Please sign in to comment.
You can’t perform that action at this time.