2017-06-08 16 views
6

मैं जावा प्रोग्राम कोड का विश्लेषण करने के लिए इंटेलिजे-प्लगइन लिख रहा हूं। इस प्रकार मैं स्थिर विश्लेषण लिखने के लिए Soot का उपयोग करता हूं। हर बार जब कोई उपयोगकर्ता मेरी प्लगइन का विश्लेषण कार्रवाई से चलाता है, मैं इस तरह वर्तमान संदर्भ की वर्तमान VirtualFile ले:सूट: स्रोत फ़ाइल के बाद कक्षा को दोबारा लोड करें

FileEditorManager manager = FileEditorManager.getInstance(e.getProject()); 
VirtualFile files[] = manager.getSelectedFiles(); 
toAnalyse = files[0]; [...] 

जब मैं इस फ़ाइल को सभी परिवर्तन लागू किए जाने की सामग्री की जाँच करें। इसके बाद मैं उस वर्ग को लोड कर रहा हूं जिसे मैं सूट में विश्लेषण करना चाहता हूं।

String dir = toAnalyse.getParent().getPath() ; 
Options.v().setPhaseOption("jb", "use-original-names"); 
Options.v().set_soot_classpath(System.getProperty("java.home")+";"+ dir); 
c = Scene.v().loadClassAndSupport(name); 
/*no analyse c*/ 

यह मेरे लिए पूरी तरह से काम करता है। लेकिन अब मेरे मुद्दे पर: यदि मैं sth बदलता हूं। मेरी प्लगइन के परीक्षण उदाहरण में और फिर एक ही विश्लेषण को ट्रिगर करें, कुछ भी नहीं बदलेगा।

मैंने अब तक क्या प्रयास किया है?

मैं विकल्पों निम्नलिखित सेट:

Options.v().set_dump_body(Arrays.asList("jb")); 
Options.v().set_dump_cfg(Arrays.asList("jb")); 
Options.v().set_allow_phantom_refs(true); 
Options.v().set_whole_program(true); 

मैं भी इस तरह हाथ

द्वारा सभी वर्गों हटाया:

Chain<SootClass> classes = Scene.v().getClasses(); 
Stack<SootClass> stack = new Stack<>(); 
for(SootClass s : classes) 
    stack.push(s); 
while(!stack.empty()) 
    Scene.v().removeClass(stack.pop()); 

और कार्यक्रम फिर से शुरू कर दिया।

उत्तर

5

मैंने इस मुद्दे को हल किया।

SootClass c = Scene.v().loadClassAndSupport(name); 
// ... 
c.setResolvingLevel(0); 
G.reset(); 

G.reset() फिर सेट करता है सब सिंगलटन उदाहरणों। इसलिए इस कैश को फिर से कॉल करके सभी कैश किए गए परिणाम ओवरराइट किए जाएंगे।

public static Scene v() { 
    return G.v().soot_Scene(); 
} 

this.instance_soot_SceneG.reset() बुला के बाद null है।

इसलिए निम्नलिखित कोड:

public Scene soot_Scene() { 
    if(this.instance_soot_Scene == null) { 
     synchronized(this) { 
      if(this.instance_soot_Scene == null) { 
       this.instance_soot_Scene = new Scene(this.g); 
      } 
     } 
    } 

    return this.instance_soot_Scene; 
} 

एक खाली परिणाम कैश के साथ एक नया उदाहरण देता है।

संबंधित मुद्दे