Repository: scalacenter/tasty-query (scala)

Issue:
Crashes on some simple signature
Since `0.1.0` I have some crashes on some simple signatures:

Here is the test that fails:
```scala
package simple_trees

case class A(x: String)
```

```scala
  testWithContext("problem") {
    val A = resolve(name"simple_trees" / tname"A").asClass
    A.getDecl(name"copy").get.asTerm.signedName
  }
```

And the stack trace is:

```
==> X tastyquery.TypeSuite.problem  0.876s tastyquery.Exceptions$MemberNotFoundException: cannot find package member _root_ of symbol[package <root>]
    at tastyquery.Contexts$Context.$anonfun$1(Contexts.scala:124)
    at scala.Option.getOrElse(Option.scala:201)
    at tastyquery.Contexts$Context.rec$1(Contexts.scala:125)
    at tastyquery.Contexts$Context.findPackageFromRoot(Contexts.scala:129)
    at tastyquery.Types$PackageRef.symbol(Types.scala:819)
    at tastyquery.Types$NamedType$.possibleSelFromPackage(Types.scala:724)
    at tastyquery.TypeTrees$TermRefTypeTree.calculateType(TypeTrees.scala:90)
    at tastyquery.TypeTrees$TypeTree.toType(TypeTrees.scala:21)
    at tastyquery.TypeTrees$SelectTypeTree.calculateType(TypeTrees.scala:82)
    at tastyquery.TypeTrees$TypeTree.toType(TypeTrees.scala:21)
    at tastyquery.reader.tasties.TreeUnpickler.readTemplate$$anonfun$4$$anonfun$1(TreeUnpickler.scala:526)
    at scala.collection.immutable.List.map(List.scala:250)
    at tastyquery.reader.tasties.TreeUnpickler.readTemplate$$anonfun$3(TreeUnpickler.scala:527)
    at tastyquery.Symbols$ClassSymbol.parents(Symbols.scala:507)
    at tastyquery.Symbols$ClassSymbol.isDerivedValueClass(Symbols.scala:446)
    at tastyquery.Types$ErasedTypeRef$.finishErase(Types.scala:147)
    at tastyquery.Types$ErasedTypeRef$.erase(Types.scala:69)
    at tastyquery.Signatures$Signature$.rec$1(Signatures.scala:39)
    at tastyquery.Signatures$Signature$.fromMethodic(Signatures.scala:44)
    at tastyquery.Symbols$TermSymbol.signature(Symbols.scala:218)
    at tastyquery.Symbols$TermSymbol.signedName(Symbols.scala:225)
    at tastyquery.TypeSuite.$init$$$anonfun$1(TypeSuite.scala:783)
    at tastyquery.UnrestrictedUnpicklingSuite.testWithContext$$anonfun$1(UnrestrictedUnpicklingSuite.scala:9)
    at tastyquery.UnrestrictedUnpicklingSuite.testWithContext$$anonfun$3$$anonfun$1(UnrestrictedUnpicklingSuite.scala:15)
    at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:431)
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
```

I hope you can fix this soon and release `0.1.1` :pray:

Pull request:
in tasty, trees that point to the Root package are stored as `TERMREFpkg _root_`, so have a fully qualified name of `FullyQualifiedName(name"_root_" :: Nil)`. I adjust the method `findPackageFromRoot` to drop an initial `_root_`, so its optional to add it.

For context, the crash in #154 comes from reading the `_root_.scala.Product` parent of the case class, when determining if it is a value class in erasure

fixes #154

Patch:
diff --git a/tasty-query/shared/src/main/scala/tastyquery/Contexts.scala b/tasty-query/shared/src/main/scala/tastyquery/Contexts.scala
index 76fee395..ee2f0e9a 100644
--- a/tasty-query/shared/src/main/scala/tastyquery/Contexts.scala
+++ b/tasty-query/shared/src/main/scala/tastyquery/Contexts.scala
@@ -126,7 +126,11 @@ object Contexts {
             rec(next, pathRest)
           case name :: pathRest =>
             throw MemberNotFoundException(owner, name, s"cannot find package member $name of $owner")
-      rec(RootPackage, fullyQualifiedName.path)
+      // strip initial `_root_` if present, which is how user signals qualified from root names.
+      val path0 = fullyQualifiedName.path match
+        case nme.RootPackageName :: path => path
+        case path                        => path
+      rec(RootPackage, path0)
     end findPackageFromRoot
 
     def findSymbolFromRoot(path: List[Name]): Symbol =


Test patch:
diff --git a/tasty-query/shared/src/test/scala/tastyquery/SignatureSuite.scala b/tasty-query/shared/src/test/scala/tastyquery/SignatureSuite.scala
index 62f43be9..d4528d52 100644
--- a/tasty-query/shared/src/test/scala/tastyquery/SignatureSuite.scala
+++ b/tasty-query/shared/src/test/scala/tastyquery/SignatureSuite.scala
@@ -242,4 +242,10 @@ class SignatureSuite extends UnrestrictedUnpicklingSuite:
     assertIsSignedName(bar3.signedName, "bar3", "():scala.Int")
   }
 
+  testWithContext("case class copy method") {
+    val CaseClass = resolve(name"synthetics" / tname"CaseClass").asClass
+    val copy = CaseClass.getDecl(name"copy").get.asTerm
+    assertIsSignedName(copy.signedName, "copy", "(java.lang.String):synthetics.CaseClass")
+  }
+
 end SignatureSuite
diff --git a/test-sources/src/main/scala/synthetics/CaseClass.scala b/test-sources/src/main/scala/synthetics/CaseClass.scala
new file mode 100644
index 00000000..1eb6349a
--- /dev/null
+++ b/test-sources/src/main/scala/synthetics/CaseClass.scala
@@ -0,0 +1,3 @@
+package synthetics
+
+case class CaseClass(x: String)