J'essaie d'implémenter une analyse (étend DefaultOneStepAnalysis) pour construire un graphe d'appel dans les algorithmes CHA. Il y a trois parties de mon code:"findMethods" ne retourne pas les résultats attendus
1) method "doAnalyze" to return the "BasicReport"
2) method "analyze" to find call edges for each method in the given project
3) class "AnalysisContext" to store the context and methods using in the analysis.
En 3), j'utilise la méthode « callBySignature » pour découvrir cbsMethods d'une même méthode que dans « CHACallGraphExtractor » mais il ne retourne pas résultat attendu. Alors que j'utilise la méthode d'origine d'OPAL pour obtenir cbsMethods dans Extractor, le résultat est un ensemble de méthodes.
Pourriez-vous m'aider s'il vous plaît à confirmer où le problème est et comment le résoudre? Merci beaucoup.
Cordialement, Jiang
---- partie principale de mon code ----------------------------- --------------------
object CHACGAnalysis extends DefaultOneStepAnalysis {
... ...
override def doAnalyze(
project: Project[URL],
parameters: Seq[String] = List.empty,
isInterrupted:() ⇒ Boolean
): BasicReport = {
... ...
for {
classFile <- project.allProjectClassFiles
method <- classFile.methods
} {
analyze(project, methodToCellCompleter, classFile, method))
}
... ...
}
def analyze(
project: Project[URL],
methodToCellCompleter: Map[(String,Method), CellCompleter[K, Set[Method]]],
classFile: ClassFile,
method: Method
): Unit = {
… …
val context = new AnalysisContext(project, classFile, method)
method.body.get.foreach((pc, instruction) ⇒
instruction.opcode match {
... ...
case INVOKEINTERFACE.opcode ⇒
val INVOKEINTERFACE(declaringClass, name, descriptor) = instruction
context.addCallEdge_VirtualCall(pc, declaringClass, name, descriptor, true,cell1)
... ...
}
… …
}
protected[this] class AnalysisContext(
val project: SomeProject,
val classFile: ClassFile,
val method: Method
) {
val classHierarchy = project.classHierarchy
val cbsIndex = project.get(CallBySignatureResolutionKey)
val statistics = project.get(IntStatisticsKey)
val instantiableClasses = project.get(InstantiableClassesKey)
val cache = new CallGraphCache[MethodSignature, scala.collection.Set[Method]](project)
private[AnalysisContext] def callBySignature(
declaringClassType: ObjectType,
name: String,
descriptor: MethodDescriptor
): Set[Method] = {
val cbsMethods = cbsIndex.findMethods(
name,
descriptor,
declaringClassType
)
cbsMethods
}
def addCallEdge_VirtualCall(
pc: PC,
declaringClassType: ObjectType,
name: String,
descriptor: MethodDescriptor,
isInterfaceInvocation: Boolean = false,
cell1: CellCompleter[K, Set[Method]]
): Unit = {
val cbsCalls =
if (isInterfaceInvocation) {
callBySignature(declaringClassType, name, descriptor)
}
else
Set.empty[Method]
… …
}
… …
}
Pouvez-vous ajouter votre code à la question? Cela aiderait à clarifier votre question. –
Le code d'origine est trop compliqué pendant que je télécharge la partie principale du code. J'ai également débogué dans OPAL pour trouver pourquoi "cbsIndex.findMethods" n'a pas pu trouver les méthodes comme prévu. J'ai trouvé qu'il vient de "propertyStore (méthode, CallBySignature.Key)" dans CallBySignatureResolution.scala. En ce qui concerne cette instruction, le résultat de mon code est "EP (XXXX, NoCBSTargets)" et le résultat du code d'origine est "EP (XXX, CBSTargets (XXX))". Pour aller plus loin –
Est-il possible que votre mode d'analyse soit une application de bureau? Vous pouvez utiliser 'project.analysisMode'pour le vérifier –