I'm trying to restore a project named Scala-IDE.
One of the scala files is JavaSig.scala:
package org.scalaide.core.internal.compiler
import org.scalaide.core.compiler.IScalaPresentationCompiler.Implicits._
trait JavaSig { pc: ScalaPresentationCompiler =>
/** Returns the symbol's `JavaSignature`*/
def javaSigOf(sym: Symbol): JavaSignature = new JavaSignature(sym)
/*
* An utility class that allows to extract information from the `symbol`'s java signature.
* If the passed `symbol` does not need a Java signature, empty values are returned.
*
* @example Given the following method declaration:
* {{{ def foo[T <: Foo, U <: ArrayList[_ >: Class[T]]](u: U, t: T):T = t }}}
*
* The following are the values computed by JavaSignatureConverter:
* {{{
* sig <- <T:LFoo;U:Ljava.util.ArrayList<-Ljava.lang.Class<TT;>;>;>(TU;TT;)TT;
* paramsCount <- 2
* paramsType <- [[U], [T]]
* paramsTypeSig <- [TU;, TT;]
* typeVars <- [T, U]
* typeParamsSig <- [T:LFoo;, U:Ljava.util.ArrayList<-Ljava.lang.Class<TT;>;>;]
* typeParamsBounds <- [[LFoo;], [Ljava.util.ArrayList<-Ljava.lang.Class<TT;>;>;]]
* typeParamsBoundsReadable <- [[Foo], [java.util.ArrayList<? super java.lang.Class<T>>]]
* returnTypeSig <- TT;
* returnType <- T
* exceptionTypes <- []
* }}}
*
* @example Given the following method declaration:
* {{{ def foo[U <: List[Array[String]]](u: U, s: Int):U = u }}}
*
* The following are the values computed by JavaSignatureConverter:
* {{{
* sig <- <U:Lscala.collection.immutable.List<[Ljava.lang.String;>;>(TU;I)TU;
* paramsCount <- 2
* paramsType <- [[U], [i, n, t]]
* paramsTypeSig <- [TU;, I]
* typeVars <- [U]
* typeParamsSig <- [U:Lscala.collection.immutable.List<[Ljava.lang.String;>;]
* typeParamsBounds <- [[Lscala.collection.immutable.List<[Ljava.lang.String;>;]]
* typeParamsBoundsReadable <- [[scala.collection.immutable.List<java.lang.String[]>]]
* returnTypeSig <- TU;
* returnType <- U
* expceptionTypes <- []
* }}}
*/
class JavaSignature(symbol: Symbol) {
import org.eclipse.jdt.core.Signature
// see scala/scala commit e5ea3ab
private val markClassUsed: Symbol => Unit = _ => ()
private lazy val sig: Option[String] = {
// make sure to execute this call in the presentation compiler's thread
pc.asyncExec {
def needsJavaSig: Boolean = {
// there is no need to generate the generic type information for local symbols
val throwsArgs = symbol.annotations flatMap ThrownException.unapply
!symbol.isLocalToBlock && erasure.needsJavaSig(symbol, symbol.info, throwsArgs)
}
if (needsJavaSig) {
// it's *really* important we ran pc.atPhase so that symbol's type is updated! (atPhase does side-effects on the type!)
for (signature <- erasure.javaSig(symbol, pc.enteringPhase(pc.currentRun.erasurePhase)(symbol.info), markClassUsed))
yield signature.replace("/", ".")
} else None
}.getOrElse(None)()
}
def isDefined: Boolean = sig.isDefined
def paramsCount: Int =
sig.map(Signature.getParameterCount).getOrElse(0)
def paramsType: Array[Array[Char]] =
paramsTypeSig.map(p => Signature.toCharArray(p.toArray))
def paramsTypeSig: Array[String] =
sig.map(Signature.getParameterTypes).getOrElse(Array.empty)
def typeVars: Array[String] =
typeParamsSig.map(Signature.getTypeVariable)
def typeParamsSig: Array[String] =
sig.map(Signature.getTypeParameters).getOrElse(Array.empty)
def typeParamsBounds: Array[Array[String]] =
typeParamsSig.map(Signature.getTypeParameterBounds)
def typeParamsBoundsReadable: Array[Array[Array[Char]]] =
typeParamsBounds.map(_.map(s => Signature.toCharArray(s.toArray)))
def returnTypeSig: Option[String] =
sig.map(Signature.getReturnType)
def returnType: Option[String] =
returnTypeSig.map(r => Signature.toCharArray(r.toArray).mkString)
def exceptionTypes: Array[Array[Char]] =
sig.map(Signature.getThrownExceptionTypes).getOrElse(Array.empty[String]).map(_.toCharArray)
}
}
It uses an object of type scala.tools.nsc.transform.Erasure named erasure
which appears to be defined in scala.tools.nsc.Global. These are both from scala-compiler-2.12.19.jar.
When I try to compile JavaSig.scala
, I have the following error:
[ERROR] [Error] C:/Users/nicol/git/scala-ide/org.scala-ide.sdt.core/src/org/scalaide/core/internal/compiler/JavaSig.scala:61: value needsJavaSig is not a member of object JavaSig.this.erasure
When I try to use a fully qualified name on erasure like scala.tools.nsc.Global.erasure
instead of just erasure
, I have the following error:
[ERROR] [Error] C:/Users/nicol/git/scala-ide/org.scala-ide.sdt.core/src/org/scalaide/core/internal/compiler/JavaSig.scala:61: value erasure is not a member of object scala.tools.nsc.Global
What is actually missing so that I can use this object erasure
?
Please note I've just slightly adapted the code of JavaSig
. Now this method from Erasure
takes 3 parameters instead of 2, the Type
being added:
private def needsJavaSig(sym: Symbol, tp: Type, throwsArgs: List[Type]) = !settings.Ynogenericsig && {
def needs(tp: Type) = NeedsSigCollector(sym.isClassConstructor).collect(tp)
needs(tp) || throwsArgs.exists(needs)
}
So I adapted based on the existing code from Erasure
:
val throwsArgs = symbol.annotations flatMap ThrownException.unapply
!symbol.isLocalToBlock && erasure.needsJavaSig(symbol, symbol.info, throwsArgs)
EDIT:
ScalaPresentationCompiler
which extends scala.tools.nsc.Global
erasure
is defined in scala.tools.nsc.Global
=> erasure
should be available inside pc.asyncExec { ... }
without prefix/import
The error message was misleading. The real reason was that the method needsJavaSig
from Erasure
was private.
A temporary reflection hack is still possible to wait for a better solution such as a proper API replacement:
val method: Method = classOf[Erasure].getDeclaredMethod("needsJavaSig", classOf[Symbol], classOf[Type], classOf[List[Annotation]])
method.setAccessible(true)
val javaSigNeeded: Boolean = method.invoke(erasure, symbol, symbol.info, throwsArgs).asInstanceOf[Boolean]