Scalameta parser problem

I am trying to use scalameta’s parser. However, there is an “import” problem that I cannot resolve.
The collect method is mentioned in this link: Tree Guide · Scalameta

Please see that last line in the following code snippet:

object ApiExtractor {

  implicit val parameterWrites: Writes[Parameter] = Json.writes[Parameter]
  implicit val apiFunctionWrites: Writes[ApiFunction] = Json.writes[ApiFunction]
  implicit val apiSchemaWrites: Writes[ApiSchema] = Json.writes[ApiSchema]

  def extractApi(sourceFiles: Seq[File]): ApiSchema = {
    val apiFunctions = sourceFiles.flatMap { file =>
      try {

        val bytes = Files.readAllBytes(file.toPath)
        val text = new String(bytes, "UTF-8")
        val input =
          Input.VirtualFile(file.getAbsolutePath, text)
        val tree: scala.meta.Source =
          input
            .parse[Source]
            .get // Or use .parse[Source].toEither.right.get for error handling

        tree.collect { case Defn.Def(mods, name, _, paramss, decltpe, _) =>

Thank you.

Are you getting a compile-time error, unexpected behavior at runtime, or what?

1 Like

Thank you for asking. Yes, I am getting compile-time error. It says that
“value collect is not a member of scala.meta.Source”

I have the following import statements where XtenstionSyntax helps me with some compile-time errors. I have delved into the source code of scalameta, but cannot find either a “collect” method or an extension that provides such a "collect method:

import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import scala.meta.Source
import scala.meta.Tree
import scala.meta.Position
import scala.meta.inputs.Input
import scala.util.control.NonFatal
import scala.meta.parsers.*
import scala.meta.XtensionSyntax
import scala.meta.contrib.TreeOps

Hmm. I don’t have any hands-on experience with Scalameta (so I’m just guessing), but I notice that you’re spelling out all of your dependencies explicitly. The Scalameta docs are pretty specific that you should import the whole kit and kaboodle as import scala.meta._, and stuff like implicit conversions can often lurk in the cracks there – have you tried that yet?

Yes, indeed, I started with

import scala.meta._

Then I switched to explicit imports in an attempt to resolve the error.

@nader
tree.collect is brought by import scala.meta._. It’s actually scala.meta.XtensionCollectionLikeUI(tree).collect. You can always investigate how your implicits are resolved (e.g. extension methods) with scalacOptions += "-Xprint:typer": https://stackoverflow.com/questions/59348301/in-scala-2-or-3-is-it-possible-to-debug-implicit-resolution-process-in-runtime
You can check that the code compiles: Scastie - An interactive playground for Scala.
You can try sbt clean compile.
If you need precise imports you can try

import java.io.File
import java.nio.file.Files
import scala.meta.{Defn, Input, Source}
import scala.meta.XtensionCollectionLikeUI

Oh, maybe you use Scala 3. In scalameta_3 there is no XtensionCollectionLikeUI. Try to use

libraryDependencies += "org.scalameta" %% "scalameta" % "4.13.8" cross CrossVersion.for3Use2_13

instead of

libraryDependencies += "org.scalameta" %% "scalameta" % "4.13.8"
2 Likes