2013-08-06 7 views
17

में रिकर्सिव कॉल का पता लगाएं मैं अपने कोड में सभी रिकर्सिव कॉल ढूंढना चाहता हूं।सी # कोड

यदि मैं विजुअल स्टूडियो में फ़ाइल खोलता हूं, तो मुझे संपादक के बाईं तरफ "रिकर्सिव कॉल" आइकन मिलता है। enter image description here

मैं ऐसी कॉल के लिए पूरे समाधान का निरीक्षण करना चाहता हूं।

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

संपादित करें कि नीले-ish के लिए जाँच करने के लिए नहीं करना चाहते हैं -

वहाँ किसी भी तरह से है कि मैं पूरे समाधान का निरीक्षण कर सकता है -लेवल रिकर्सन

+0

आप जानते हैं कि यह आइकन बहु-स्तर रिकर्सन के लिए प्रकट नहीं होता है? अर्थात। विधि ए कॉल बी जो बदले में ए, आदि कॉल करता है? –

+0

हाँ मुझे पता है, मैं सिर्फ एकल स्तर की रिकर्सन चाहता हूं। –

उत्तर

16

आप Mono.Cecil के साथ कर सकते हैं।

const string AssemblyFilePath = @"path\to\assembly.dll"; 

void Main() 
{ 
    var assembly = ModuleDefinition.ReadModule(AssemblyFilePath); 
    var calls = 
     (from type in assembly.Types 
     from caller in type.Methods 
     where caller != null && caller.Body != null 
     from instruction in caller.Body.Instructions 
     where instruction.OpCode == OpCodes.Call 
     let callee = instruction.Operand as MethodReference 
     select new { type, caller, callee }).Distinct(); 

    var directRecursiveCalls = 
     from call in calls 
     where call.callee == call.caller 
     select call.caller; 

    foreach (var method in directRecursiveCalls) 
     Debug.WriteLine(method.DeclaringType.Namespace + "." + method.DeclaringType.Name + "." + method.Name + " calls itself"); 
} 

हो जाएगा ताकि उत्पादन के तरीकों सीधे खुद को कॉल:

यहाँ एक सरल LINQPad प्रोग्राम है जो यह दर्शाता है है। ध्यान दें कि मैंने केवल Call निर्देश को संसाधित किया है, मुझे यकीन नहीं है कि अन्य कॉल निर्देशों को सही तरीके से यहां कैसे संभाला जाए, या यदि भी संभव है।

कैविट: ध्यान दें कि ऐसा होगा, क्योंकि मैंने केवल उसी निर्देश को संभाला है, केवल स्थिर रूप से संकलित कॉल के साथ काम करता है।

वर्चुअल कॉल, इंटरफेस के माध्यम से कॉल करता है, जो कि उसी विधि पर वापस जाने के लिए होता है, इसके द्वारा पता नहीं लगाया जाएगा, इसके लिए बहुत अधिक उन्नत कोड आवश्यक है।

+2

एक आकर्षण की तरह काम करता है, धन्यवाद –

+1

बस स्पष्ट करने के लिए, अगर कोई सुनिश्चित नहीं है; ऐसा करने के लिए आपको मोनो की आवश्यकता नहीं है। लिंककैड प्रो में आप क्वेरी गुण विंडो में NuGet पैकेज 'Install-Package Mono.Cecil' जोड़ सकते हैं। यदि आप एक सस्ते स्केट हैं और मुफ्त संस्करण हैं तो आपको nuget पैकेज को किसी अन्य अस्थायी प्रोजेक्ट में डाउनलोड करने की आवश्यकता होगी, फिर क्वेरी गुणों का उपयोग करके अपनी क्वेरी में अतिरिक्त असेंबली जोड़ें। अन्यथा मॉड्यूलडिफिनिशन। रीड मॉड्यूल में काम के सही संदर्भ नहीं होंगे। – Junto

+0

मैंने https://github.com/jbevain/cecil/releases को उपरोक्त कोड के साथ निर्मित और चलाया है और मुझे सभी रिकर्सिव कॉल सूचीबद्ध करें। धन्यवाद! – Zyo