Skip to content

Commit

Permalink
improvement: Color vals of module type as classes
Browse files Browse the repository at this point in the history
eg. in `val Foo = List`, syntax highlighting on Foo will be the same as on List
This was already true for vals defined in predef.scala
  • Loading branch information
jkciesluk committed Nov 24, 2023
1 parent 58b80be commit 3a27d23
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ final class PcSemanticTokensProvider(
if (sym.isAccessor)
getTypeId(SemanticTokenTypes.Variable)
else getTypeId(SemanticTokenTypes.Method) // "def"
else if (isPredefClass(sym)) getTypeId(SemanticTokenTypes.Class)
else if (isValObject(sym)) getTypeId(SemanticTokenTypes.Class)
else if (sym.isTerm && (!sym.isParameter || sym.isParamAccessor)) {
addPwrToMod(SemanticTokenModifiers.Readonly)
getTypeId(SemanticTokenTypes.Variable) // "val"
Expand All @@ -132,16 +132,18 @@ final class PcSemanticTokensProvider(
if (isDefinition) addPwrToMod(SemanticTokenModifiers.Definition)

TokenNode(pos.start, pos.end, typ, mod)

}

private def isPredefClass(sym: Collector.compiler.Symbol) =
// eg. val Foo = List
private def isValObject(sym: Collector.compiler.Symbol) = {
sym.info match {
case Collector.compiler.NullaryMethodType(
Collector.compiler.SingleType(_, value)
) if value.isModule =>
true
) =>
value.isModule
case Collector.compiler.SingleType(_, value) => value.isModule
case _ => false
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ final class PcSemanticTokensProvider(
if sym.isGetter | sym.isSetter then
getTypeId(SemanticTokenTypes.Variable)
else getTypeId(SemanticTokenTypes.Method) // "def"
else if isPredefClass(sym) then
else if sym.isTerm && sym.info.typeSymbol.is(Flags.Module) then
getTypeId(SemanticTokenTypes.Class) // "class"
else if sym.isTerm &&
(!sym.is(Flags.Param) || sym.is(Flags.ParamAccessor))
Expand All @@ -153,7 +153,4 @@ final class PcSemanticTokensProvider(
TokenNode(pos.start, pos.`end`, typ, mod)
end makeNode

def isPredefClass(sym: Symbol)(using Context) =
sym.is(Flags.Method) && sym.info.resultType.typeSymbol.is(Flags.Module)

end PcSemanticTokensProvider
23 changes: 23 additions & 0 deletions tests/cross/src/test/scala/tests/tokens/SemanticTokensSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,29 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite {
|""".stripMargin
)

check(
"predef",
"""
|object <<Main>>/*class*/ {
| val <<a>>/*variable,definition,readonly*/ = <<List>>/*class*/(1,2,3)
| val <<y>>/*class,definition*/ = <<List>>/*class*/
| val <<z>>/*class,definition*/ = <<scala>>/*namespace*/.<<collection>>/*namespace*/.<<immutable>>/*namespace*/.<<List>>/*class*/
|}
|""".stripMargin
)

check(
"val-object",
"""|case class <<X>>/*class*/(<<a>>/*variable,declaration,readonly*/: <<Int>>/*class,abstract*/)
|object <<X>>/*class*/
|
|object <<Main>>/*class*/ {
| val <<x>>/*class,definition*/ = <<X>>/*class*/
| val <<y>>/*variable,definition,readonly*/ = <<X>>/*class*/(1)
|}
|""".stripMargin
)

// When for-comprehension includes line with `=`, we get `scala.x$1`, `scala.x$2` symbols on `foo`.
// Both `scala` and `x$#` have position on `foo`, and we don't want to highlight it as a `scala` package,
// so we need `namespace` to have lower priority than `variable`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@
<<val>>/*keyword*/ <<f>>/*variable,definition,readonly*/ = <<given_Float>>/*variable,readonly*/
<<val>>/*keyword*/ <<g>>/*variable,definition,readonly*/ = <<`* *`>>/*variable,readonly*/
<<val>>/*keyword*/ <<i>>/*variable,definition,readonly*/ = <<X>>/*class*/.<<of>>/*method*/[<<Int>>/*class,abstract*/]
<<val>>/*keyword*/ <<x>>/*variable,definition,readonly*/ = <<given_Xg>>/*class*/
<<val>>/*keyword*/ <<x>>/*class,definition*/ = <<given_Xg>>/*class*/
<<val>>/*keyword*/ <<y>>/*variable,definition,readonly*/ = <<given_Yg>>/*method*/
<<val>>/*keyword*/ <<z>>/*variable,definition,readonly*/ = <<given_Zg_T>>/*method*/[<<String>>/*type*/]

0 comments on commit 3a27d23

Please sign in to comment.