You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scalameta获取引用全限定名及方法引用解析问题排查

Hey there! Let's work through this method reference parsing issue you're hitting with Scalameta and SemanticDB. It's super common to get stuck when moving from tracking explicit method calls to handling method references (whether explicit like foo _ or implicit when passing a method as a higher-order function argument), so let's break this down.

First, Why the Difference?

The key thing here is that method calls and method references are represented differently in both the AST and SemanticDB:

  • Explicit method calls (like someRecognizeableName()) show up as Apply nodes in the Scalameta AST, and their semantic references are straightforwardly linked to the method's symbol.
  • Method references (either explicit someRecognizeableName _ or implicit when used as a function argument) get handled via eta expansion by the compiler. In the AST, this might be a Term.Eta node (for explicit _ syntax) or even just a Term.Ident/Term.Select node (for implicit expansion), and their semantic linking isn't as obvious in the raw db.names list.

Fixes to Track Method References

Here are actionable steps to adjust your code to catch these references:

1. Expand Your AST Node Handling

Don't just target Apply nodes—add cases for nodes that represent method references:

import scala.meta._
import scala.meta.semanticdb._

def traverseCode(term: Term)(implicit ctx: SemanticContext): Unit = term match {
  // Handle explicit method calls
  case Apply(_, _) =>
    term.symbol.foreach { sym =>
      println(s"Found method call: ${sym.displayName}")
    }
  // Handle explicit method references (e.g., someRecognizeableName _)
  case Term.Eta(underlyingTerm) =>
    underlyingTerm.symbol.foreach { sym =>
      println(s"Found explicit method reference: ${sym.displayName}")
    }
  // Handle implicit method references (passed as higher-order function args)
  case ref @ (Term.ident(_) | Term.Select(_, _)) if ref.symbol.exists(_.isMethod) =>
    ref.symbol.foreach { sym =>
      println(s"Found implicit method reference: ${sym.displayName}")
    }
  // Recursively check all child nodes
  case other =>
    other.children.foreach {
      case t: Term => traverseCode(t)
      case _ => // Skip non-term nodes
    }
}

2. Use SemanticDB References Instead of Just db.names

The db.names list only captures raw identifier text, which doesn't carry the semantic context needed to link method references to their original method symbols. Instead, use the db.references collection, which maps positions directly to their associated symbols.

For example, to find all references to your someRecognizeableName method:

// Get the fully qualified symbol for your method (adjust the signature as needed)
val targetMethodSymbol = Symbol("codelab/FindMe#someRecognizeableName().")

// Filter all references that point to this symbol
val methodReferences = db.references.filter(_.symbol == targetMethodSymbol)

methodReferences.foreach { ref =>
  println(s"Found reference at position: ${ref.position.startLine}:${ref.position.startColumn}")
}

3. Double-Check Your SemanticDB Setup

Make sure your semanticdb-scalac plugin is configured correctly to capture all necessary semantic info:

  • Ensure you've set the sourceroot correctly in your build (matches the root of your project)
  • Verify that the plugin is enabled for all modules you're analyzing
  • Check that you're loading the correct .semanticdb files (they should be in target/scala-<version>/semanticdb if using sbt)

Quick Troubleshooting Tip

If you're still seeing odd entries, print out the symbol's full display name and kind for each reference:

ref.symbol.foreach { sym =>
  println(s"Symbol: ${sym.displayName}, Kind: ${sym.kind}, Owner: ${sym.owner}")
}

This will help you confirm if a reference is actually pointing to your target method, even if it's wrapped in an eta-expanded function.


内容的提问来源于stack exchange,提问作者Gabor Juhasz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:01:24