Skip to content

Commit

Permalink
Refactor symbol search after review
Browse files Browse the repository at this point in the history
  • Loading branch information
kpbochenek committed Mar 19, 2020
1 parent 602161a commit 99ef3cd
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,32 @@ final class ImplementationProvider(
}
}

def defaultSymbolSearch(
textDocumentWithPath: TextDocumentWithPath
): String => Option[SymbolInformation] =
defaultSymbolSearch(
textDocumentWithPath.filePath,
textDocumentWithPath.textDocument
)

def defaultSymbolSearch(
anyWorkspacePath: AbsolutePath,
textDocument: TextDocument
): String => Option[SymbolInformation] = {
lazy val global =
new GlobalClassTable(buildTargets).globalSymbolTableFor(anyWorkspacePath)
symbol => {
textDocument.symbols
.find(_.symbol == symbol)
.orElse(findSymbolInformation(symbol))
.orElse(global.flatMap(_.safeInfo(symbol)))
}
}

def implementations(
params: TextDocumentPositionParams
): List[Location] = {
val source = params.getTextDocument.getUri.toAbsolutePath
lazy val global = globalTable.globalSymbolTableFor(source)
val locations = for {
(symbolOccurrence, currentDocument) <- definitionProvider
.symbolOccurrence(
Expand All @@ -97,14 +118,10 @@ final class ImplementationProvider(
// 1. Search locally for symbol
// 2. Search inside workspace
// 3. Search classpath via GlobalSymbolTable
def symbolSearch(symbol: String): Option[SymbolInformation] = {
findSymbol(currentDocument, symbol)
.orElse(findSymbolInformation(symbol))
.orElse(global.flatMap(_.safeInfo(symbol)))
}
val symbolSearch = defaultSymbolSearch(source, currentDocument)
val sym = symbolOccurrence.symbol
val dealiased =
if (sym.desc.isType) dealiasClass(sym, symbolSearch _) else sym
if (sym.desc.isType) dealiasClass(sym, symbolSearch) else sym

val definitionDocument =
if (currentDocument.definesSymbol(dealiased)) {
Expand Down Expand Up @@ -266,18 +283,13 @@ final class ImplementationProvider(
if (isClassLike(parentSymbolInfo))
Some(implReal.symbol)
else {
lazy val global = globalTable.globalSymbolTableFor(source)
def localSearch(symbol: String): Option[SymbolInformation] = {
findSymbol(implDocument, symbol)
.orElse(findSymbolInformation(symbol))
.orElse(global.flatMap(_.safeInfo(symbol)))
}
val symbolSearch = defaultSymbolSearch(source, implDocument)
MethodImplementation.findInherited(
parentSymbolInfo,
symbolClass,
classContext,
implReal,
localSearch
symbolSearch
)
}
}
Expand Down Expand Up @@ -348,7 +360,9 @@ final class ImplementationProvider(
}
}

def findSymbolInformation(symbol: String): Option[SymbolInformation] = {
private def findSymbolInformation(
symbol: String
): Option[SymbolInformation] = {
findSemanticDbForSymbol(symbol).flatMap(findSymbol(_, symbol))
}

Expand Down Expand Up @@ -435,7 +449,7 @@ object ImplementationProvider {
}
}

def findSymbol(
private def findSymbol(
semanticDb: TextDocument,
symbol: String
): Option[SymbolInformation] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import scala.meta.internal.semanticdb.TextDocument
import scala.meta.internal.semanticdb.TypeRef
import scala.meta.internal.semanticdb.TypeSignature
import scala.collection.{mutable => m}
import scala.meta.internal.metals.codelenses.SuperMethodLensesProvider.LensGoSuperCache
import scala.meta.internal.metals.codelenses.SuperMethodCodeLens.LensGoSuperCache

object SuperMethodProvider {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,21 @@ import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.meta.internal.implementation.Supermethods.GoToSuperMethodParams
import scala.meta.internal.implementation.Supermethods.formatMethodSymbolForQuickPick
import scala.meta.internal.metals.BuildTargets
import scala.meta.internal.metals.ClientCommands
import scala.meta.internal.metals.DefinitionProvider
import scala.meta.internal.metals.JsonParser._
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.MetalsLanguageClient
import scala.meta.internal.metals.MetalsQuickPickItem
import scala.meta.internal.metals.MetalsQuickPickParams
import scala.meta.internal.metals.codelenses.SuperMethodLensesProvider.emptyLensGoSuperCache
import scala.meta.internal.metals.codelenses.SuperMethodCodeLens.emptyLensGoSuperCache
import scala.meta.internal.semanticdb.SymbolInformation
import scala.meta.internal.semanticdb.SymbolOccurrence
import scala.meta.internal.semanticdb.TextDocument
import scala.meta.io.AbsolutePath

class Supermethods(
client: MetalsLanguageClient,
definitionProvider: DefinitionProvider,
implementationProvider: ImplementationProvider,
buildTargets: BuildTargets
implementationProvider: ImplementationProvider
)(
implicit ec: ExecutionContext
) {
Expand Down Expand Up @@ -66,7 +62,10 @@ class Supermethods(
filePath,
params.position
)
findSymbol = makeFindSymbolMethod(textDocument, filePath)
findSymbol = implementationProvider.defaultSymbolSearch(
filePath,
textDocument
)
symbolInformation <- findSymbol(symbolOcc.symbol)
gotoSymbol <- {
if (symbolOcc.role.isDefinition) {
Expand Down Expand Up @@ -118,7 +117,10 @@ class Supermethods(
filePath,
params.position
)
findSymbol = makeFindSymbolMethod(textDocument, filePath)
findSymbol = implementationProvider.defaultSymbolSearch(
filePath,
textDocument
)
symbolInformation <- findSymbol(symbolOcc.symbol)
docText = TextDocumentWithPath(textDocument, filePath)
hierarchy <- SuperMethodProvider.getSuperMethodHierarchy(
Expand All @@ -130,25 +132,6 @@ class Supermethods(
} yield hierarchy.map(_.symbol)
}

private def makeFindSymbolMethod(
textDocument: TextDocument,
filePath: AbsolutePath
): String => Option[SymbolInformation] = {
val global = new GlobalClassTable(buildTargets)
.globalSymbolTableFor(filePath)
.get
si =>
ImplementationProvider
.findSymbol(textDocument, si)
.orElse(
implementationProvider
.findSymbolInformation(si)
)
.orElse(
global.info(si)
)
}

private def findSuperMethodSymbol(
symbolInformation: SymbolInformation,
role: SymbolOccurrence.Role,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package scala.meta.internal.metals

import org.eclipse.{lsp4j => l}
import scala.meta.internal.implementation.TextDocumentWithPath
import scala.meta.internal.metals.codelenses.CodeLenses
import scala.meta.internal.metals.codelenses.CodeLens
import scala.meta.internal.mtags.Semanticdbs
import scala.meta.io.AbsolutePath

final class CodeLensProvider(
codeLensProviders: List[CodeLenses],
codeLensProviders: List[CodeLens],
semanticdbs: Semanticdbs
) {
// code lenses will be refreshed after compilation or when workspace gets indexed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ import java.{util => ju}
import scala.meta.internal.metals.Messages.IncompatibleBloopVersion
import com.google.gson.JsonNull
import scala.meta.internal.implementation.Supermethods
import scala.meta.internal.metals.codelenses.CodeLenses
import scala.meta.internal.metals.codelenses.RunTestLensesProvider
import scala.meta.internal.metals.codelenses.SuperMethodLensesProvider
import scala.meta.internal.metals.codelenses.RunTestCodeLens
import scala.meta.internal.metals.codelenses.SuperMethodCodeLens

class MetalsLanguageServer(
ec: ExecutionContextExecutorService,
Expand Down Expand Up @@ -383,27 +382,25 @@ class MetalsLanguageServer(
supermethods = new Supermethods(
languageClient,
definitionProvider,
implementationProvider,
buildTargets
implementationProvider
)

val runTestLensesProvider: List[CodeLenses] =
if (clientExperimentalCapabilities.debuggingProvider) {
List(
new RunTestLensesProvider(buildTargetClasses, buffers, buildTargets)
)
} else {
List.empty
}
val goSuperLensesProvider = new SuperMethodLensesProvider(
val runTestLensProvider =
new RunTestCodeLens(
buildTargetClasses,
buffers,
buildTargets,
clientExperimentalCapabilities
)

val goSuperLensProvider = new SuperMethodCodeLens(
implementationProvider,
buffers,
buildTargets,
() => userConfig,
config
)
codeLensProvider = new CodeLensProvider(
runTestLensesProvider :+ goSuperLensesProvider,
List(runTestLensProvider, goSuperLensProvider),
semanticdbs
)
renameProvider = new RenameProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package scala.meta.internal.metals.codelenses
import org.eclipse.{lsp4j => l}
import scala.meta.internal.implementation.TextDocumentWithPath

trait CodeLenses {
trait CodeLens {
def isEnabled: Boolean
def codeLenses(textDocumentWithPath: TextDocumentWithPath): Seq[l.CodeLens]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package scala.meta.internal.metals.codelenses

import java.util.Collections.singletonList

import ch.epfl.scala.bsp4j.BuildTargetIdentifier
import ch.epfl.scala.{bsp4j => b}
import com.google.gson.JsonElement
Expand All @@ -15,16 +14,19 @@ import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.TokenEditDistance
import scala.meta.internal.metals.BuildTargets
import scala.meta.internal.metals.BuildTargetClasses
import scala.meta.internal.metals.ClientExperimentalCapabilities
import scala.meta.internal.semanticdb.TextDocument
import scala.meta.internal.metals.JsonParser._

final class RunTestLensesProvider(
final class RunTestCodeLens(
buildTargetClasses: BuildTargetClasses,
buffers: Buffers,
buildTargets: BuildTargets
) extends CodeLenses {
buildTargets: BuildTargets,
clientExperimentalCapabilities: ClientExperimentalCapabilities
) extends CodeLens {

override def isEnabled: Boolean = true
override def isEnabled: Boolean =
clientExperimentalCapabilities.debuggingProvider

override def codeLenses(
textDocumentWithPath: TextDocumentWithPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,27 @@ package scala.meta.internal.metals.codelenses
import java.util.Collections.singletonList
import org.eclipse.{lsp4j => l}
import scala.collection.{mutable => m}
import scala.meta.internal.implementation.GlobalClassTable
import scala.meta.internal.implementation.ImplementationProvider
import scala.meta.internal.implementation.SuperMethodProvider
import scala.meta.internal.implementation.ClassHierarchyItem
import scala.meta.internal.implementation.TextDocumentWithPath
import scala.meta.internal.metals.Buffers
import scala.meta.internal.metals.BuildTargets
import scala.meta.internal.metals.MetalsServerConfig
import scala.meta.internal.metals.ServerCommands
import scala.meta.internal.metals.TokenEditDistance
import scala.meta.internal.metals.UserConfiguration
import scala.meta.internal.semanticdb.SymbolInformation
import scala.meta.internal.semanticdb.SymbolOccurrence
import scala.meta.internal.semanticdb.TextDocument
import scala.meta.internal.symtab.GlobalSymbolTable
import scala.meta.io.AbsolutePath
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.codelenses.SuperMethodLensesProvider.LensGoSuperCache
import scala.meta.internal.metals.codelenses.SuperMethodLensesProvider.emptyLensGoSuperCache
import scala.meta.internal.metals.codelenses.SuperMethodCodeLens.LensGoSuperCache
import scala.meta.internal.metals.codelenses.SuperMethodCodeLens.emptyLensGoSuperCache

final class SuperMethodLensesProvider(
final class SuperMethodCodeLens(
implementationProvider: ImplementationProvider,
buffers: Buffers,
buildTargets: BuildTargets,
userConfig: () => UserConfiguration,
config: MetalsServerConfig
) extends CodeLenses {
) extends CodeLens {

override def isEnabled: Boolean = userConfig().superMethodLensesEnabled

Expand All @@ -39,11 +33,9 @@ final class SuperMethodLensesProvider(
val textDocument = textDocumentWithPath.textDocument
val path = textDocumentWithPath.filePath

lazy val search =
makeSymbolSearchMethod(
makeGlobalClassTable(textDocumentWithPath.filePath),
textDocumentWithPath.textDocument
)
val search = implementationProvider.defaultSymbolSearch(
textDocumentWithPath
)
val distance =
TokenEditDistance.fromBuffer(path, textDocument.text, buffers)

Expand Down Expand Up @@ -97,23 +89,9 @@ final class SuperMethodLensesProvider(
)
}

private def makeSymbolSearchMethod(
global: GlobalSymbolTable,
openedTextDocument: TextDocument
): String => Option[SymbolInformation] = { symbolInformation =>
implementationProvider
.findSymbolInformation(symbolInformation)
.orElse(global.info(symbolInformation))
.orElse(openedTextDocument.symbols.find(_.symbol == symbolInformation))
}

private def makeGlobalClassTable(path: AbsolutePath): GlobalSymbolTable = {
new GlobalClassTable(buildTargets).globalSymbolTableFor(path).get
}

}

object SuperMethodLensesProvider {
object SuperMethodCodeLens {
type LensGoSuperCache =
m.Map[String, List[ClassHierarchyItem]]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import scala.concurrent.Future
import munit.Location
import munit.TestOptions

class CodeLensesLspSuite extends BaseLspSuite("codeLenses") {
class CodeLensLspSuite extends BaseLspSuite("codeLenses") {
check("empty-package")(
"""|<<run>><<debug>>
|object Main {
Expand Down

0 comments on commit 99ef3cd

Please sign in to comment.