Skip to content

Commit

Permalink
fix scalacenter#1104 Can't get symbol from TextDocument for arg of Ap…
Browse files Browse the repository at this point in the history
…plyInfix which have parens around

ref scalameta/scalameta#1083
  • Loading branch information
giabao committed Apr 24, 2020
1 parent c9e42a0 commit 9ece0a5
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 56 deletions.
Expand Up @@ -5,6 +5,7 @@ import scala.meta._
import scala.meta.internal.symtab._
import scala.meta.internal.{semanticdb => s}
import scalafix.internal.v0._
import scalafix.internal.v1.TreePos
import scalafix.util.SemanticdbIndex
import scalafix.v0
import scalafix.v0._
Expand Down Expand Up @@ -50,16 +51,7 @@ case class EagerInMemorySemanticdbIndex(
def symbol(position: Position): Option[Symbol] =
_names.get(position).map(_.symbol)
def symbol(tree: Tree): Option[Symbol] = tree match {
case name @ Name(_) =>
val syntax = name.syntax
// workaround for https://github.com/scalameta/scalameta/issues/1083
val pos =
if (syntax.startsWith("(") &&
syntax.endsWith(")") &&
syntax != name.value)
Position.Range(name.pos.input, name.pos.start + 1, name.pos.end - 1)
else name.pos
symbol(pos)
case name: Name => TreePos.symbol[Option[Symbol]](name, symbol, _.isEmpty)
case Importee.Rename(name, _) => symbol(name)
case Importee.Name(name) => symbol(name)
case Term.Select(_, name @ Name(_)) => symbol(name)
Expand Down
Expand Up @@ -71,7 +71,7 @@ final class LegacySemanticdbIndex(val doc: v1.SemanticDocument)
case multi => Some(v0.Symbol.Multi(multi))
}
override def symbol(tree: Tree): Option[v0.Symbol] =
symbol(TreePos.symbol(tree))
TreePos.symbolImpl[Option[v0.Symbol]](tree)(symbol, _.isEmpty)

override def denotation(symbol: v0.Symbol): Option[v0.Denotation] = {
doc.internal.info(v1.Symbol(symbol.syntax)).map { info =>
Expand Down
Expand Up @@ -50,7 +50,7 @@ final class InternalSemanticDoc(

def symbol(tree: Tree): Symbol = {
def fromTextDocument() = {
val result = symbols(TreePos.symbol(tree))
val result = TreePos.symbolImpl[Iterator[Symbol]](tree)(symbols, _.isEmpty)
if (result.hasNext) result.next() // Discard multi symbols
else Symbol.None
}
Expand Down
96 changes: 53 additions & 43 deletions scalafix-core/src/main/scala/scalafix/internal/v1/TreePos.scala
Expand Up @@ -4,49 +4,59 @@ import scala.annotation.tailrec
import scala.meta._

object TreePos {
@tailrec def symbol(tree: Tree): Position = tree match {
case name @ Name(_) =>
val syntax = name.syntax
// workaround for https://github.com/scalameta/scalameta/issues/1083
if (syntax.startsWith("(") &&
syntax.endsWith(")") &&
syntax != name.value) {
Position.Range(name.pos.input, name.pos.start + 1, name.pos.end - 1)
} else {
name.pos
}
case m: Member => symbol(m.name)
case t: Term.Select => symbol(t.name)
case t: Term.Interpolate => symbol(t.prefix)
case t: Term.Apply => symbol(t.fun)
case t: Term.ApplyInfix => symbol(t.op)
case t: Term.ApplyUnary => symbol(t.op)
case t: Term.ApplyType => symbol(t.fun)
case t: Term.Assign => symbol(t.lhs)
case t: Term.Ascribe => symbol(t.expr)
case t: Term.Annotate => symbol(t.expr)
case t: Term.New => symbol(t.init)
case t: Type.Select => symbol(t.name)
case t: Type.Project => symbol(t.name)
case t: Type.Singleton => symbol(t.ref)
case t: Type.Apply => symbol(t.tpe)
case t: Type.ApplyInfix => symbol(t.op)
case t: Type.Annotate => symbol(t.tpe)
case t: Type.ByName => symbol(t.tpe)
case t: Type.Repeated => symbol(t.tpe)
case t: Pat.Bind => symbol(t.lhs)
case t: Pat.Extract => symbol(t.fun)
case t: Pat.ExtractInfix => symbol(t.op)
case t: Pat.Interpolate => symbol(t.prefix)
case Defn.Val(_, p :: Nil, _, _) => symbol(p)
case Decl.Val(_, p :: Nil, _) => symbol(p)
case Defn.Var(_, p :: Nil, _, _) => symbol(p)
case Decl.Var(_, p :: Nil, _) => symbol(p)
case t: Importee.Rename => symbol(t.name)
case t: Importee.Name => symbol(t.name)
case Importer(_, i :: Nil) => symbol(i)
case t: Init => symbol(t.tpe)
case t: Mod.Annot => symbol(t.init)
private[scalafix] def symbol[T](name: Name, f: Position => T, isEmpty: T => Boolean): T = {
val syntax = name.syntax
// workaround for https://github.com/scalameta/scalameta/issues/1083
if (syntax.startsWith("(") &&
syntax.endsWith(")") &&
syntax != name.value) {
val pos = Position.Range(name.pos.input, name.pos.start + 1, name.pos.end - 1)
val t = f(pos)
if (isEmpty(t)) f(name.pos)
else t
} else {
f(name.pos)
}
}

def symbol(tree: Tree): Position = symbolImpl[Position](tree)(identity[Position], _ => false)

// The implicit function must named `$conforms` to shadow `Predef.$conforms`
@tailrec
private[scalafix] def symbolImpl[T](tree: Tree)(implicit $conforms: Position => T, isEmpty: T => Boolean): T = tree match {
case name: Name => symbol(name, $conforms, isEmpty)
case m: Member => symbolImpl(m.name)
case t: Term.Select => symbolImpl(t.name)
case t: Term.Interpolate => symbolImpl(t.prefix)
case t: Term.Apply => symbolImpl(t.fun)
case t: Term.ApplyInfix => symbolImpl(t.op)
case t: Term.ApplyUnary => symbolImpl(t.op)
case t: Term.ApplyType => symbolImpl(t.fun)
case t: Term.Assign => symbolImpl(t.lhs)
case t: Term.Ascribe => symbolImpl(t.expr)
case t: Term.Annotate => symbolImpl(t.expr)
case t: Term.New => symbolImpl(t.init)
case t: Type.Select => symbolImpl(t.name)
case t: Type.Project => symbolImpl(t.name)
case t: Type.Singleton => symbolImpl(t.ref)
case t: Type.Apply => symbolImpl(t.tpe)
case t: Type.ApplyInfix => symbolImpl(t.op)
case t: Type.Annotate => symbolImpl(t.tpe)
case t: Type.ByName => symbolImpl(t.tpe)
case t: Type.Repeated => symbolImpl(t.tpe)
case t: Pat.Bind => symbolImpl(t.lhs)
case t: Pat.Extract => symbolImpl(t.fun)
case t: Pat.ExtractInfix => symbolImpl(t.op)
case t: Pat.Interpolate => symbolImpl(t.prefix)
case Defn.Val(_, p :: Nil, _, _) => symbolImpl(p)
case Decl.Val(_, p :: Nil, _) => symbolImpl(p)
case Defn.Var(_, p :: Nil, _, _) => symbolImpl(p)
case Decl.Var(_, p :: Nil, _) => symbolImpl(p)
case t: Importee.Rename => symbolImpl(t.name)
case t: Importee.Name => symbolImpl(t.name)
case Importer(_, i :: Nil) => symbolImpl(i)
case t: Init => symbolImpl(t.tpe)
case t: Mod.Annot => symbolImpl(t.init)
case _ => tree.pos
}
}
Expand Up @@ -41,7 +41,7 @@ case class LegacyInMemorySemanticdbIndex(
}
}
override def symbol(tree: Tree): Option[v0.Symbol] =
symbol(TreePos.symbol(tree))
TreePos.symbolImpl[Option[v0.Symbol]](tree)(symbol, _.isEmpty)
override def denotation(symbol: v0.Symbol): Option[Denotation] =
symbol match {
case v0.Symbol.Local(id) =>
Expand Down

0 comments on commit 9ece0a5

Please sign in to comment.