diff --git a/semanticdb/integration/src/main/scala/example/InstrumentTyper.scala b/semanticdb/integration/src/main/scala/example/InstrumentTyper.scala index 74119cf71e..887bfe974e 100644 --- a/semanticdb/integration/src/main/scala/example/InstrumentTyper.scala +++ b/semanticdb/integration/src/main/scala/example/InstrumentTyper.scala @@ -17,7 +17,8 @@ class InstrumentTyper { self: AnyRef => Literal.bool, Literal.unit, Literal.javaEnum, - Literal.clazzOf, + Literal.clazzOfInt, + Literal.clazzOfOption, List() ) def existential: U[Int] forSome { type U[T <: Int] } = ??? diff --git a/semanticdb/integration/src/main/scala/example/Types.scala b/semanticdb/integration/src/main/scala/example/Types.scala index 223555b005..be28268738 100644 --- a/semanticdb/integration/src/main/scala/example/Types.scala +++ b/semanticdb/integration/src/main/scala/example/Types.scala @@ -111,6 +111,8 @@ object Test { final val bool = true final val unit = () final val javaEnum = java.nio.file.LinkOption.NOFOLLOW_LINKS - final val clazzOf = classOf[Option[Int]] + final val clazzOfInt = classOf[Int] + final val clazzOfOption = classOf[Option[Int]] + } } diff --git a/semanticdb/scalac/library/src/main/scala/scala/meta/internal/semanticdb/scalac/TextDocumentOps.scala b/semanticdb/scalac/library/src/main/scala/scala/meta/internal/semanticdb/scalac/TextDocumentOps.scala index 11f568abd5..4e73b5f647 100644 --- a/semanticdb/scalac/library/src/main/scala/scala/meta/internal/semanticdb/scalac/TextDocumentOps.scala +++ b/semanticdb/scalac/library/src/main/scala/scala/meta/internal/semanticdb/scalac/TextDocumentOps.scala @@ -604,6 +604,14 @@ trait TextDocumentOps { self: SemanticdbOps => case _ => } + def isClassOf(pos: m.Position): Boolean = { + val chars = pos.input.chars + val classOfChars = "classOf".toCharArray + + chars.length >= (classOfChars.length + pos.start) && + (0 until classOfChars.length).forall(i => chars(i + pos.start) == classOfChars(i)) + } + gtree match { case OriginalTreeOf(original) => traverse(original) @@ -635,6 +643,17 @@ trait TextDocumentOps { self: SemanticdbOps => case gtree: g.TypeTreeWithDeferredRefCheck => traverse(gtree.check()) + case gtree: g.Literal + if isClassOf(gtree.pos.toMeta) && + gtree.tpe != null && + gtree.tpe.typeSymbol == g.definitions.ClassClass && + gtree.pos.isRange => + val coLen = "classOf".length + val mpos = gtree.pos.toMeta + val mposFix = new m.Position.Range(mpos.input, mpos.start, mpos.start + coLen) + + occurrences(mposFix) = "scala/Predef.classOf()." + case gtree: g.MemberDef => gtree.symbol.annotations.foreach(ann => traverse(ann.original)) tryFindMtree(gtree) diff --git a/tests/jvm/src/test/resources/example/InstrumentTyper.scala b/tests/jvm/src/test/resources/example/InstrumentTyper.scala index a8e7efded8..5a5ab59248 100644 --- a/tests/jvm/src/test/resources/example/InstrumentTyper.scala +++ b/tests/jvm/src/test/resources/example/InstrumentTyper.scala @@ -17,11 +17,12 @@ class InstrumentTyper/*<=example.InstrumentTyper#*/ { self/*<=local0*/: AnyRef = Literal/*=>types.Test.Literal.*/.bool/*=>types.Test.Literal.bool.*/, Literal/*=>types.Test.Literal.*/.unit/*=>types.Test.Literal.unit.*/, Literal/*=>types.Test.Literal.*/.javaEnum/*=>types.Test.Literal.javaEnum.*/, - Literal/*=>types.Test.Literal.*/.clazzOf/*=>types.Test.Literal.clazzOf.*/, + Literal/*=>types.Test.Literal.*/.clazzOfInt/*=>types.Test.Literal.clazzOfInt.*/, + Literal/*=>types.Test.Literal.*/.clazzOfOption/*=>types.Test.Literal.clazzOfOption.*/, List/*=>scala.collection.immutable.Nil.*/() ) def existential/*<=example.InstrumentTyper#existential().*/: U/*=>local1*/[Int/*=>scala.Int#*/] forSome { type U/*<=local1*/[T/*<=local2*/ <: Int] } = ???/*=>scala.Predef.`???`().*/ type AnnotatedType/*<=example.InstrumentTyper#AnnotatedType#*/ = Int/*=>scala.Int#*/ @param def singletonType/*<=example.InstrumentTyper#singletonType().*/(x/*<=example.InstrumentTyper#singletonType().(x)*/: Predef.type) = ???/*=>scala.Predef.`???`().*/ - final val clazzOf/*<=example.InstrumentTyper#clazzOf.*/ = classOf[Option[Int]] + final val clazzOf/*<=example.InstrumentTyper#clazzOf.*/ = classOf/*=>scala.Predef.classOf().*/[Option[Int]] } diff --git a/tests/jvm/src/test/resources/example/Types.scala b/tests/jvm/src/test/resources/example/Types.scala index abdc3a0de1..728777a33f 100644 --- a/tests/jvm/src/test/resources/example/Types.scala +++ b/tests/jvm/src/test/resources/example/Types.scala @@ -111,6 +111,8 @@ object Test/*<=types.Test.*/ { final val bool/*<=types.Test.Literal.bool.*/ = true final val unit/*<=types.Test.Literal.unit.*/ = () final val javaEnum/*<=types.Test.Literal.javaEnum.*/ = java.nio.file.LinkOption/*=>java.nio.file.LinkOption#*/.NOFOLLOW_LINKS/*=>java.nio.file.LinkOption#NOFOLLOW_LINKS.*/ - final val clazzOf/*<=types.Test.Literal.clazzOf.*/ = classOf[Option[Int]] + final val clazzOfInt/*<=types.Test.Literal.clazzOfInt.*/ = classOf/*=>scala.Predef.classOf().*/[Int] + final val clazzOfOption/*<=types.Test.Literal.clazzOfOption.*/ = classOf/*=>scala.Predef.classOf().*/[Option[Int]] + } } diff --git a/tests/jvm/src/test/resources/metac.expect b/tests/jvm/src/test/resources/metac.expect index ed9440648d..9f8643e029 100644 --- a/tests/jvm/src/test/resources/metac.expect +++ b/tests/jvm/src/test/resources/metac.expect @@ -1712,7 +1712,7 @@ Uri => semanticdb/integration/src/main/scala/example/InstrumentTyper.scala Text => non-empty Language => Scala Symbols => 11 entries -Occurrences => 53 entries +Occurrences => 56 entries Synthetics => 1 entries Symbols: @@ -1787,20 +1787,23 @@ Occurrences: [18:4..18:11): Literal => types/Test.Literal. [18:12..18:20): javaEnum => types/Test.Literal.javaEnum. [19:4..19:11): Literal => types/Test.Literal. -[19:12..19:19): clazzOf => types/Test.Literal.clazzOf. -[20:4..20:8): List => scala/collection/immutable/Nil. -[22:6..22:17): existential <= example/InstrumentTyper#existential(). -[22:19..22:20): U => local1 -[22:21..22:24): Int => scala/Int# -[22:41..22:42): U <= local1 -[22:43..22:44): T <= local2 -[22:57..22:60): ??? => scala/Predef.`???`(). -[23:7..23:20): AnnotatedType <= example/InstrumentTyper#AnnotatedType# -[23:23..23:26): Int => scala/Int# -[24:6..24:19): singletonType <= example/InstrumentTyper#singletonType(). -[24:20..24:21): x <= example/InstrumentTyper#singletonType().(x) -[24:38..24:41): ??? => scala/Predef.`???`(). -[25:12..25:19): clazzOf <= example/InstrumentTyper#clazzOf. +[19:12..19:22): clazzOfInt => types/Test.Literal.clazzOfInt. +[20:4..20:11): Literal => types/Test.Literal. +[20:12..20:25): clazzOfOption => types/Test.Literal.clazzOfOption. +[21:4..21:8): List => scala/collection/immutable/Nil. +[23:6..23:17): existential <= example/InstrumentTyper#existential(). +[23:19..23:20): U => local1 +[23:21..23:24): Int => scala/Int# +[23:41..23:42): U <= local1 +[23:43..23:44): T <= local2 +[23:57..23:60): ??? => scala/Predef.`???`(). +[24:7..24:20): AnnotatedType <= example/InstrumentTyper#AnnotatedType# +[24:23..24:26): Int => scala/Int# +[25:6..25:19): singletonType <= example/InstrumentTyper#singletonType(). +[25:20..25:21): x <= example/InstrumentTyper#singletonType().(x) +[25:38..25:41): ??? => scala/Predef.`???`(). +[26:12..26:19): clazzOf <= example/InstrumentTyper#clazzOf. +[26:22..26:29): classOf => scala/Predef.classOf(). Synthetics: [8:12..8:16): List => *.apply[Any] @@ -3677,8 +3680,8 @@ Schema => SemanticDB v4 Uri => semanticdb/integration/src/main/scala/example/Types.scala Text => non-empty Language => Scala -Symbols => 139 entries -Occurrences => 246 entries +Symbols => 140 entries +Occurrences => 249 entries Symbols: local0 => abstract method k: Int @@ -3946,11 +3949,14 @@ types/Test.C#typeRef4. => val method typeRef4: List[Int] types/Test.C#x. => val method x: p.X p => types/Test.C#p. X => types/P#X# -types/Test.Literal. => final object Literal extends AnyRef { +11 decls } +types/Test.Literal. => final object Literal extends AnyRef { +12 decls } AnyRef => scala/AnyRef# types/Test.Literal.bool. => final val method bool: true types/Test.Literal.char. => final val method char: 'a' -types/Test.Literal.clazzOf. => final val method clazzOf: Class[Option[Int]] +types/Test.Literal.clazzOfInt. => final val method clazzOfInt: Class[Int] + Class => java/lang/Class# + Int => scala/Int# +types/Test.Literal.clazzOfOption. => final val method clazzOfOption: Class[Option[Int]] Class => java/lang/Class# Option => scala/Option# Int => scala/Int# @@ -4240,7 +4246,10 @@ Occurrences: [112:34..112:38): file => java/nio/file/ [112:39..112:49): LinkOption => java/nio/file/LinkOption# [112:50..112:64): NOFOLLOW_LINKS => java/nio/file/LinkOption#NOFOLLOW_LINKS. -[113:14..113:21): clazzOf <= types/Test.Literal.clazzOf. +[113:14..113:24): clazzOfInt <= types/Test.Literal.clazzOfInt. +[113:27..113:34): classOf => scala/Predef.classOf(). +[114:14..114:27): clazzOfOption <= types/Test.Literal.clazzOfOption. +[114:30..114:37): classOf => scala/Predef.classOf(). semanticdb/integration/src/main/scala/example/ValPattern.scala -------------------------------------------------------------- diff --git a/tests/jvm/src/test/resources/metacp.expect b/tests/jvm/src/test/resources/metacp.expect index 100032d12a..05643f45ee 100644 --- a/tests/jvm/src/test/resources/metacp.expect +++ b/tests/jvm/src/test/resources/metacp.expect @@ -3303,7 +3303,7 @@ Schema => SemanticDB v4 Uri => types/Test.class Text => empty Language => Scala -Symbols => 101 entries +Symbols => 102 entries Symbols: types/Test. => final object Test extends AnyRef { +4 decls } @@ -3516,11 +3516,14 @@ types/Test.C#typeRef4. => val method typeRef4: List[Int] types/Test.C#x. => val method x: p.X p => types/Test.C#p. X => types/P#X# -types/Test.Literal. => final object Literal extends AnyRef { +11 decls } +types/Test.Literal. => final object Literal extends AnyRef { +12 decls } AnyRef => scala/AnyRef# types/Test.Literal.bool. => final val method bool: true types/Test.Literal.char. => final val method char: 'a' -types/Test.Literal.clazzOf. => final val method clazzOf: Class[Option[Int]] +types/Test.Literal.clazzOfInt. => final val method clazzOfInt: Class[Int] + Class => java/lang/Class# + Int => scala/Int# +types/Test.Literal.clazzOfOption. => final val method clazzOfOption: Class[Option[Int]] Class => java/lang/Class# Option => scala/Option# Int => scala/Int#