यदि आपकी पसंदीदा भाषा के लिए कोई स्थैतिक विश्लेषक नहीं है तो क्या होगा?

ठीक है, अगर आपकी पसंदीदा भाषा का मतलब रूसी, अंग्रेजी, आदि है, तो यह दूसरे हब में है । और अगर प्रोग्रामिंग या मार्कअप भाषा है, तो बेशक खुद को विश्लेषक लिखें! पहली नज़र में, यह बहुत मुश्किल है, लेकिन, सौभाग्य से, तैयार बहुभाषी उपकरण हैं, जो एक नई भाषा के लिए समर्थन जोड़ना अपेक्षाकृत आसान है। आज मैं दिखाऊंगा कि पीएमडी विश्लेषक को मॉडलिका भाषा समर्थन को समय की एक छोटी राशि के साथ कैसे जोड़ा जाए


वैसे, क्या आप जानते हैं कि आदर्श पुल अनुरोधों के अनुक्रम से प्राप्त कोड आधार की गुणवत्ता को नीचा दिखा सकते हैं? तथ्य यह है कि तीसरे पक्ष के प्रोग्रामर ने एक सक्षम अमूर्तता के बजाय मौजूदा परियोजना कोड के टुकड़ों को अपने पैच में कॉपी किया। आपको यह स्वीकार करना चाहिए कि, कुछ हद तक, खराब गुणवत्ता वाले कोड की तुलना में इस तरह की प्रतिबंध को पकड़ना और भी मुश्किल है - यह उच्च गुणवत्ता वाला है और यहां तक ​​कि पहले से ही सावधानी से डिबग किया हुआ है, इसलिए यहां स्थानीय सत्यापन पर्याप्त नहीं है, आपको पूरे कोड आधार को ध्यान में रखना होगा, लेकिन यह किसी व्यक्ति के लिए आसान नहीं है ... इसलिए: यदि राज्य के लिए मॉडलिका का पूर्ण समर्थन (विशिष्ट नियम बनाए बिना) जोड़ना "आदिम जांच चला सकता है" मुझे लगभग एक सप्ताह लग गया, फिर केवल कॉपी-पेस्ट डिटेक्टर समर्थन अक्सर एक दिन में जोड़ा जा सकता है!


और क्या है मॉडलिका?


मॉडलिका, जैसा कि नाम से पता चलता है, भौतिक प्रणालियों के मॉडल लिखने के लिए एक भाषा है। वास्तव में, न केवल भौतिक: रासायनिक प्रक्रियाओं, जानवरों की आबादी के मात्रात्मक व्यवहार आदि का वर्णन करना संभव है - इसका वर्णन फार्म der(X) = f(X) के अंतर समीकरणों की प्रणालियों द्वारा किया गया है, जहां X अज्ञात का वेक्टर है। कोड के इम्पीरियल टुकड़े भी समर्थित हैं। आंशिक अंतर समीकरणों का स्पष्ट रूप से समर्थन नहीं किया जाता है, लेकिन अध्ययन क्षेत्र को टुकड़ों में विभाजित करना संभव है (जैसा कि हमने शायद कुछ सामान्य-प्रयोजन भाषा में किया होगा), और फिर प्रत्येक तत्व के समीकरणों को लिखकर समस्या को पिछले एक तक कम कर दिया। Modelka की चाल यह है कि इस der(X) = f(X) का समाधान कंपाइलर के साथ है: आप बस सॉल्वर को सेटिंग्स में बदल सकते हैं , समीकरण को रैखिक होने की जरूरत नहीं है, आदि संक्षेप में, कुछ प्लस हैं (मैंने लिखा है) पाठ्यपुस्तक से सूत्र - और यह काम किया), और विपक्ष (अधिक अमूर्त के साथ, हमें कम नियंत्रण मिलता है)। मॉडलिका से परिचय एक अलग लेख का विषय है (जो पहले ही कई बार हैबे पर दिखाई दे चुका है), और यहां तक ​​कि एक पूरा चक्र, आज यह मुझे एक खुले और कई कार्यान्वयन के रूप में दिलचस्पी लेता है, लेकिन, अफसोस, अभी भी एक नम मानक है।


इसके अलावा, दूसरी ओर, मॉडलिका में स्थैतिक टंकण है (जो हमें कुछ सार्थक विश्लेषण तेजी से लिखने में मदद करेगा), दूसरी ओर, जब किसी मॉडल को त्वरित किया जाता है, तो कंपाइलर को पूरी लाइब्रेरी की पूरी तरह से जांच करने की आवश्यकता नहीं होती है (इसलिए, "स्लीपिंग" पकड़ने के लिए एक स्टैटिक विश्लेषक बहुत उपयोगी है) कीड़े)। अंत में, कुछ सी ++ के विपरीत, जिसके लिए सुंदर के साथ स्थिर विश्लेषक और संकलक का एक बादल है, और सबसे महत्वपूर्ण बात यह है कि C ++ टेम्प्लेट देखें त्रुटि निदान, संकलक मॉडल अभी भी समय-समय पर आंतरिक संकलक त्रुटि उत्पन्न करते हैं, जिसका अर्थ है कि उपयोगकर्ता को काफी सरल विश्लेषक के साथ भी मदद करने के लिए जगह है।


पीएमडी क्या है?


मैं जवाब दूंगा गीत बाइक से। एक बार जब मैं OpenModelica के लिए विकास के माहौल में कुछ छोटे खींचने का अनुरोध करना चाहता था। यह देखकर कि कोड के दूसरे भाग में मॉडल की बचत कैसे की जाती है, मैंने कोड की चार पंक्तियों के टुकड़े के अंदर एक छोटा और बहुत स्पष्ट नहीं देखा जो किसी प्रकार के अपरिवर्तनीय का समर्थन करता था। समझ में नहीं आ रहा है कि वह किस तरह के संपादक के साथ बातचीत करता है, लेकिन यह महसूस करते हुए कि इस कोड ऑफ़ कोड के दृष्टिकोण से, मेरा कार्य पूरी तरह से समान है, मैंने इसे केवल एक फ़ंक्शन में रखा ताकि मैं इसे पुन: उपयोग कर सकूं और इसे तोड़ न सकूं। Menteiner ने कहा, यह अद्भुत है, तभी इस कोड को शेष बीस स्थानों में एक फ़ंक्शन कॉल के साथ बदल दें ... मैंने अभी तक शामिल नहीं होने का फैसला किया, और बस एक और प्रतिलिपि बनाई, यह देखते हुए कि फिर किसी तरह मुझे मिश्रण किए बिना एक बार में सब कुछ कंघी करने की आवश्यकता होगी। वर्तमान पैच के साथ। Googling, मुझे कॉपी-पेस्ट डिटेक्टर (CPD) - पीएमडी स्टेटिक एनालाइज़र का हिस्सा मिला - जो विश्लेषक की तुलना में और भी अधिक भाषाओं का समर्थन करता है। इसे OMEdit कोड बेस पर सेट करने के बाद, मुझे चार लाइनों के उन दो दर्जन टुकड़ों को देखने की उम्मीद थी। मैंने अभी उन्हें नहीं देखा (उनमें से प्रत्येक ने टोकन की संख्या में सीमा से अधिक नहीं थी), लेकिन मैंने देखा, उदाहरण के लिए, सी ++ कोड की लगभग पचास पंक्तियों की पुनरावृत्ति। जैसा कि मैंने पहले ही कहा था, यह संभावना नहीं है कि दाढ़ ने बस एक अन्य फ़ाइल से एक विशाल टुकड़े की नकल की। लेकिन वह पीआर में यह आसानी से याद कर सकता है - क्योंकि कोड, परिभाषा के अनुसार, पहले से ही परियोजना के सभी मानकों को पूरा करता है! जब मैंने प्रस्तावक के साथ अवलोकन साझा किया, तो उन्होंने सहमति व्यक्त की कि एक अलग कार्य के हिस्से के रूप में सफाई करना आवश्यक होगा।


तदनुसार, प्रोग्राम मिस्टेक डिटेक्टर (पीएमडी) एक आसानी से एक्स्टेंसिबल स्टेटिक विश्लेषक है। हो सकता है कि वह उन मानों के सेट की गणना नहीं करता है जो एक चर ले सकते हैं (हालांकि कौन जानता है ...), लेकिन इसमें नियमों को जोड़ने के लिए, आपको जावा को जानने की जरूरत नहीं है और किसी तरह इसके कोड को बदलना होगा! तथ्य यह है कि पहली चीज वह, और आश्चर्यजनक रूप से नहीं, स्रोत कोड के साथ एएसटी फाइलों का निर्माण कर रही है। और स्रोत परसिंग ट्री कैसा दिखता है? XML पार्सिंग ट्री के लिए! तो, आप नियमों का वर्णन केवल XPath अनुरोधों के रूप में कर सकते हैं - जिसके लिए यह मेल खाता है, फिर हम एक चेतावनी जारी करते हैं। वे भी नियमों के लिए एक ग्राफिकल डिबगर है! निश्चित रूप से अधिक जटिल नियम, जावा में सीधे एएसटी के लिए आगंतुकों के रूप में लिखे जा सकते हैं।


परिणाम : पीएमडी का उपयोग न केवल कठोर और सार्वभौमिक नियमों के लिए किया जा सकता है, जो कठोर जावा प्रोग्रामर ने विश्लेषक कोड के लिए प्रतिबद्ध किया है, बल्कि स्थानीय कोडिंग शैली के लिए भी किया है - भले ही आप प्रत्येक रिपॉजिटरी में अपने स्वयं के स्थानीय ruleset.xml को धक्का दें!


स्तर 1: कॉपी-पेस्ट स्वचालित रूप से ढूंढें


सिद्धांत रूप में, सीपीडी में एक नई भाषा के लिए समर्थन जोड़ना अक्सर बहुत सरल होता है। मुझे "कैसे करना है" प्रलेखन को फिर से देखने में कोई भी समझदारी नहीं है - यह बहुत स्पष्ट, संरचित और चरण-दर-चरण है। ऐसी चीज को फिर से बेचना - केवल एक क्षतिग्रस्त फोन में खेलते हैं। मैं बेहतर बताता हूं कि आपको क्या इंतजार है (TLDR: यह ठीक है) :


  • विश्लेषक (PMD और CPD दोनों) को pmd / pmd रिपॉजिटरी में github पर विकसित किया गया है
  • दृश्य नियम डीबगर को एक अलग pmd / pmd-डिजाइनर रिपॉजिटरी में स्थानांतरित कर दिया गया है। कृपया ध्यान दें कि समाप्त जार-उपनाम स्वचालित रूप से पीएमडी बाइनरी वितरण में एम्बेडेड है, जो ग्रैडल आपके लिए पिछले रिपॉजिटरी में इकट्ठा करेगा, आपको इसके लिए विशेष रूप से pmd-designer क्लोन करने की आवश्यकता नहीं है।
  • परियोजना में एक डेवलपर प्रलेखन है । मैंने जो पढ़ा वह बहुत विस्तृत था। सच है, थोड़ा पुराना है, लेकिन यह दूसरा पुल अनुरोध द्वारा इलाज किया जाता है :)

मैं आपको चेतावनी दूंगा कि मैं उबंटू में विकास कर रहा हूं। विंडोज पर, यह भी पूरी तरह से काम करना चाहिए - दोनों गुणवत्ता के संदर्भ में और लॉन्चिंग टूल के थोड़ा अलग तरीके से।


इसलिए, CPD में एक नई भाषा जोड़ने के लिए, आपको बस ...


  • ध्यान दें: यदि आप पीएमडी 7 की रिलीज़ से पहले पीएमडी के लिए पूर्ण समर्थन चाहते हैं, तो सीधे स्तर 2 पर जाना बेहतर है, क्योंकि समाप्त एंट्रेल व्याकरण के माध्यम से आसान तरीके के लिए सामान्य समर्थन अफवाहों के अनुसार, बहुत ही संस्करण 7 में दिखाई देगा, लेकिन अभी के लिए आप सिर्फ समय बिताएंगे (हालांकि और थोड़ा सा ...)
  • पीएमडी / पीएमडी रिपॉजिटरी को कांटा।
  • Antlr / grammars-v4 में अपनी भाषा के लिए एक तैयार व्याकरण का पता लगाएं - बेशक, अगर भाषा आंतरिक है, तो आपको इसे खुद लिखना होगा, लेकिन उदाहरण के लिए, Modelika के लिए, यह पाया गया था। यहां, निश्चित रूप से, आपको लाइसेंस के साथ औपचारिकताओं का पालन करने की आवश्यकता है - मैं एक वकील नहीं हूं, लेकिन कम से कम मुझे उस स्रोत को निर्दिष्ट करने की आवश्यकता है जहां से मैंने कॉपी किया था।
  • उसके बाद, आपको pmd-<your language name> मॉड्यूल बनाना होगा, इसे pmd-<your language name> जोड़ें और वहां व्याकरण फ़ाइल डालें। इसके अलावा, गैर-तनावपूर्ण प्रलेखन के दो पृष्ठों को पढ़ने के बाद, गो के लिए मॉड्यूल से असेंबली की स्क्रिप्ट को फिर से करें, प्रतिबिंब के माध्यम से मॉड्यूल को लोड करने के लिए कक्षाओं की एक जोड़ी, अच्छी तरह से, वहाँ एक छोटी सी बात है ...
  • परीक्षणों में से एक में संदर्भ आउटपुट को ठीक करें, क्योंकि अब सीपीडी एक और भाषा का समर्थन करता है! आप इस परीक्षा को कैसे देखते हैं? बहुत आसान: वह बिल्ड को तोड़ना चाहता है
  • लाभ! यह वास्तव में सरल है बशर्ते कि एक तैयार व्याकरण हो

अब, ./mvnw clean verify रिपॉजिटरी की जड़ में होने के कारण, आप टाइप कर सकते हैं। / ./mvnw clean verify , जबकि pmd-dist/target आपको अन्य चीजों के अलावा, जिप आर्काइव के रूप में बाइनरी डिस्ट्रीब्यूशन जो आपको ./bin/run.sh cpd --minimum-tokens 100 --files /path/to/source/dir --language <your language name> और रन करने की जरूरत है ./bin/run.sh cpd --minimum-tokens 100 --files /path/to/source/dir --language <your language name> डायरेक्टरी से। सिद्धांत रूप में, आप कर सकते हैं ../mvnw clean verify अपने नए मॉड्यूल से ../mvnw clean verify , जो बहुत तेजी से विधानसभा को गति देगा, लेकिन फिर आपको इकट्ठे जार उपनाम को सही ढंग से अनपैक्ड बाइनरी वितरण में डालना होगा (उदाहरण के लिए, एक नया मॉड्यूल पंजीकृत करने के बाद एक बार इकट्ठा)।


स्तर 2: शैली मार्गदर्शिका की त्रुटियों और उल्लंघनों का पता लगाना


जैसा कि मैंने कहा, पीएमडी 7 में एंट्र के लिए पूर्ण समर्थन का वादा किया गया है । यदि आप, मेरी तरह, समुद्र की रिहाई के लिए इंतजार नहीं करना चाहते हैं, तो आपको कहीं से JJTree प्रारूप में भाषा के व्याकरण का विवरण प्राप्त करना होगा। हो सकता है कि आप स्वयं एक मनमाने ढंग से पार्सर के समर्थन को सख्त कर सकते हैं - प्रलेखन का कहना है कि यह संभव है, लेकिन वे यह नहीं बताएंगे कि कैसे ... मैंने बस आधार के रूप में एनलर के लिए व्याकरण के साथ समान रिपॉजिटरी से modelica.g4 लिया और मैन्युअल रूप से इसे JJTree में रीमेक किया। स्वाभाविक रूप से, यदि व्याकरण मौजूदा एक का प्रसंस्करण निकला, फिर से, स्रोत को इंगित करें, लाइसेंस के साथ अनुपालन को सत्यापित करें और। टी। डी।


वैसे, एक ऐसे व्यक्ति के लिए जो सभी प्रकार के पार्सर जनरेटर में अच्छी तरह से वाकिफ है, यह एक आश्चर्य के रूप में आने की संभावना नहीं है। इससे पहले, मैंने इसे गंभीरता से इस्तेमाल किया जब तक कि मैंने खुद स्कैला पर नियमित और पार्सर कॉम्बीनेटर नहीं लिखा। इसलिए, स्पष्ट, वास्तव में, मुझे पहली बार में दुखद बात हुई: एएसटी, निश्चित रूप से, मैं modelica.g4 से प्राप्त modelica.g4 , लेकिन यह बहुत स्पष्ट नहीं दिखता है और "उपयोग करने योग्य": इसमें अतिरिक्त नोड्स के बादल होंगे, और यदि आप टोकन को नहीं देखेंगे, लेकिन केवल नोड्स, यह हमेशा स्पष्ट नहीं होता है कि कहां, उदाहरण के लिए, then शाखा समाप्त होती है, और else शुरू होती है।


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


  • सबसे पहले, JavaCC पार्सर विवरण कोड जावा आवेषण को मानता है जो उत्पन्न पार्सर में अंकित किया जाएगा
  • एक एएसटी का निर्माण करते समय भ्रमित न हों, [ Expression() ] जैसे वाक्यविन्यास का अर्थ वैकल्पिक है, और टोकन का वर्णन करने के संदर्भ में - एक चरित्र चुनना, जैसा कि एक नियमित अभिव्यक्ति में है। जहां तक ​​मैं पीएमडी डेवलपर्स के स्पष्टीकरण को समझता हूं, ये समान निर्माण हैं जिनका इतना अलग अर्थ है - विरासत, सर ...
  • रूट नोड (मेरे मामले में, StoredDefinition ) के लिए, आपको इसके प्रकार को void (यानी ASTStoredDefiniton ) के बजाय निर्दिष्ट करना होगा
  • नोड नाम के बाद #void सिंटैक्स का उपयोग करते हुए, आप इसे पार्स किए गए पेड़ से छिपा सकते हैं (अर्थात, यह केवल प्रभावित करेगा कि सही स्रोत क्या है और क्या नहीं है, और अन्य नोड्स कैसे नेस्टेड होंगे)
  • फॉर्म के निर्माण का उपयोग करते हुए void SimpleExpression() #SimpleExpression(>1) हम कह सकते हैं कि नोड को परिणामी एएसटी में दिखाया जाना चाहिए, अगर इसमें एक से अधिक वंशज हों। विभिन्न प्राथमिकताओं के साथ कई ऑपरेटरों के साथ अभिव्यक्तियों का वर्णन करते समय यह बहुत सुविधाजनक है: अर्थात, पार्सर के दृष्टिकोण से, अकेला निरंतर 1 LogicExpression(AdditiveExpression(MultiplicativeExperssion(Constant(1)))) तरह कुछ होगा - ऑपरेशन प्राथमिकताओं के सभी n स्तरों को दर्ज करें - लेकिन विश्लेषक कोड सिर्फ Constant(1) मिलेगा
  • नोड में एक मानक चर image (देखें getImage , setImage ), जो आमतौर पर इस नोड के "सार" को setImage : उदाहरण के लिए, स्थानीय चर के नाम के अनुरूप नोड के लिए, image में पहचानकर्ता के मिलान टोकन की प्रतिलिपि बनाना तर्कसंगत है (डिफ़ॉल्ट रूप से, सभी टोकन से पेड़ों को फेंक दिया जाएगा, इसलिए यह उन में निहित अर्थ की नकल करने के लायक है, किसी भी मामले में, अगर यह कुछ चर है, और केवल कीवर्ड नहीं है)
  • LOOKAHEAD - ठीक है, यह एक अलग गीत है, यहां तक ​​कि प्रलेखन में एक अलग अध्याय भी इसके लिए समर्पित है
    • मोटे तौर पर, जावासीसी में, यदि आप एक नोड पर जाते हैं, तो आप इसे वापस नहीं फेंक सकते हैं और अलग तरीके से पार्स करने की कोशिश कर सकते हैं, लेकिन आप पहले से देख सकते हैं और तय कर सकते हैं कि जाना है या नहीं
    • सबसे सरल मामले में, JavaCC चेतावनी को देखने पर, आप सिर्फ हेडर LOOKAHEAD = n में कहेंगे और आपको रहस्यमयी पार्सिंग त्रुटियां प्राप्त होती हैं, क्योंकि सामान्य स्थिति में, ऐसा लगता है, यह सभी समस्याओं को हल नहीं कर सकता है (ठीक है, सिवाय इसके कि कुछ बिलियन टोकन सेट करके, आपको वास्तव में हर चीज का पूर्वावलोकन मिलता है, लेकिन इस तथ्य से नहीं कि यह काम करता है .. )।
    • एम्बेडेड नोड के नाम के सामने, आप स्पष्ट रूप से इस आधार पर संकेत कर सकते हैं कि यहाँ कितने टोकन हैं जो आप निश्चित रूप से अंतिम निर्णय ले सकते हैं
    • अगर सामान्य स्थिति में टोकनों की ऐसी कोई निश्चित संख्या नहीं है, तो आप कह सकते हैं कि "यहां जाएं, यदि पहले, इस बिंदु से शुरू करते हुए, हम इस तरह के उपसर्ग का मिलान करने में कामयाब रहे - और फिर सबट्री का सामान्य विवरण"
    • सावधान रहें: सामान्य मामले में, JavaCC LOOKAHEAD निर्देशों की शुद्धता को सत्यापित नहीं कर सकता है - यह आप पर भरोसा करता है, इसलिए कम से कम गणितीय प्रमाण का पता लगाएं कि ऐसा लुकहेड पर्याप्त क्यों है ...

अब जब आपके पास JJTree प्रारूप में भाषा के व्याकरण का विवरण है, तो ये सरल 14 चरण आपको भाषा समर्थन जोड़ने में मदद करेंगे। उनमें से अधिकांश के पास फॉर्म है "जावा या वीएम के लिए कार्यान्वयन के समान एक वर्ग बनाएं, लेकिन अनुकूलित।" मैं केवल विशिष्ट विशेषताएं नोट करूंगा, उनमें से कुछ मुख्य दस्तावेज में दिखाई देंगे यदि वे प्रलेखन के लिए मेरे अनुरोध को स्वीकार करते हैं:


  • असेंबली स्क्रिप्ट alljavacc.xml (जो आपके नए मॉड्यूल में है) में सभी जेनरेट की गई फ़ाइलों को हटाने की टिप्पणी करते हुए, आप उन्हें target/generated-sources से सोर्स ट्री में ट्रांसफर कर सकते target/generated-sources । लेकिन बेहतर नहीं। संभवतः, केवल एक छोटा सा हिस्सा बदला जाएगा, इसलिए केवल कुछ को हटाने का ध्यान रखना बेहतर है: उन्होंने डिफ़ॉल्ट कार्यान्वयन को बदलने की आवश्यकता देखी, स्रोत पेड़ पर कॉपी की गई, हटाए गए फ़ाइलों की सूची में जोड़ा गया, फिर से बनाया गया - और अब आप फ़ाइल का प्रबंधन करते हैं - विशेष रूप से यह फ़ाइल । अन्यथा, यह पता लगाना मुश्किल होगा कि वास्तव में क्या बदल दिया गया है, और समर्थन को शायद ही सुखद कहा जा सकता है।
  • अब जब आपके पास "मुख्य" पीएमडी मोड का कार्यान्वयन है, तो आप आसानी से अपने JJTree पार्सर पर सीपीडी के लिए बाध्यकारी के रूप में अच्छी तरह से जावा या कुछ अन्य उपलब्ध कार्यान्वयन के समान लटका सकते हैं।
  • XPath क्वेरीज़ के लिए होस्ट नाम वापस करने वाली पद्धति को लागू करना याद रखें। डिफ़ॉल्ट कार्यान्वयन में, या तो अनंत पुनरावर्ती प्राप्त की जाती है (नोड का नाम toString और इसके विपरीत होता है), या कुछ और, सामान्य तौर पर, इस वजह से, पीएमडी डिजाइनर में पेड़ को देखना संभव नहीं है, और इसके बिना व्याकरण को डीबग करना संभव नहीं है।
  • घटक पंजीकरण का एक हिस्सा पूरी तरह से योग्य वर्ग नाम प्रविष्टि बिंदु से META-INF/services लिए पाठ फ़ाइलों को जोड़कर किया जाता है
  • नियमों में घोषित रूप से वर्णित किया जा सकता है (उदाहरण के लिए, चेक का एक विस्तृत विवरण और त्रुटियों के उदाहरण) का वर्णन कोड में नहीं है, लेकिन category/<language name>/<ruleset>.xml - किसी भी मामले में, आपको अपने नियमों को वहां दर्ज करना होगा।
  • ... लेकिन परीक्षणों को लागू करते समय, जाहिरा तौर पर, कुछ, शायद घर में रहने वाले, ऑटो डिस्कवरी तंत्र सक्रिय रूप से उपयोग किया जाता है, इसलिए
    • यदि आपसे कहा जाए, "भाषा के प्रत्येक संस्करण के लिए एक तुच्छ परीक्षा जोड़ें" - बेहतर तर्क नहीं, वे कहते हैं "मुझे इसकी आवश्यकता नहीं है, यह इस तरह काम करता है" - शायद यह ऑटो खोज तंत्र है
    • यदि आप केवल एक टिप्पणी के साथ वर्ग निकाय के साथ एक विशिष्ट नियम के लिए एक परीक्षण देखते हैं। // no additional unit tests , तो ये परीक्षण नहीं हैं, वे सिर्फ इनपुट डेटा के एक्सएमएल-विवरण और अपेक्षित विश्लेषण प्रतिक्रियाओं के रूप में संसाधनों में निहित हैं, कुछ सही: और कुछ गलत उदाहरण हैं।

एक छोटी लेकिन महत्वपूर्ण खोज: पीएमडी डिजाइनर को समाप्त कर दिया


शायद आप एक विज़ुअलाइज़र के बिना सब कुछ डिबग कर सकते हैं। लेकिन क्यों? सबसे पहले, इसे खत्म करने के लिए बहुत सरल है। दूसरे, यह आपके उपयोगकर्ताओं को बहुत मदद करेगा जो जावा से परिचित नहीं हैं: वे आसान और सरल हैं (यदि यह एक्सपीथ पर लागू होता है), अच्छी तरह से, या कम से कम पीएमडी को पुन: स्थापित किए बिना, वे सरल पैटर्न का वर्णन करने में सक्षम होंगे जो उन्हें पसंद नहीं है (सबसे सरल मामले में) - एक स्टाइल गाइड जैसे "एक मॉडल पैकेज का नाम हमेशा लोअरकेस पी के साथ शुरू होता है")।


तुरंत दिखाई देने वाली अन्य त्रुटियों के विपरीत, पीएमडी डिजाइनर के साथ समस्याएं काफी कपटी हैं: ऐसा लगता है कि आप पहले से ही समझ गए थे कि मेनू के दाईं ओर जावा शिलालेख एक बटन नहीं है, लेकिन ओ_ओ भाषा चयन की एक ड्रॉप-डाउन सूची है, जिसमें यह पहले से ही दिखाई दिया था मॉडलिका, क्योंकि प्रवेश बिंदुओं के पंजीकरण के साथ एक नया मॉड्यूल क्लासपाथ में दिखाई दिया है। लेकिन यहां आप अपनी भाषा चुनते हैं, एक परीक्षण फ़ाइल डाउनलोड करते हैं, और एएसटी देखते हैं। और यह एक जीत प्रतीत होती है, लेकिन यह किसी भी तरह से काला और सफेद है, और हाइलाइट किए गए उपशीर्षक को पाठ में हाइलाइट किया जा सकता है - हालांकि नहीं, एक हाइलाइट है, लेकिन यह टेढ़ा-मेढ़ा अपडेट किया गया है - और फिर भी, उन्होंने XPath के साथ पाए गए मैचों को हाइलाइट करने का अनुमान कैसे लगाया ... पहले से ही काम की मात्रा का अनुमान लगाते हुए, आप अगले पुल अनुरोध के बारे में सोचते हैं, लेकिन फिर आप गलती से भाषा को जावा पर स्विच करने और खुद पीएमडी के कुछ स्रोत कोड डाउनलोड करने का निर्णय लेते हैं ... ओह! यह रंगीन है! .. और उपशीर्षक हाइलाइट काम करता है! उह ... और यह पता चला है कि यह आम तौर पर पाए गए मैचों को हाइलाइट करता है और अनुरोध के दाईं ओर बॉक्स में पाठ के टुकड़े लिखता है ... ऐसा लगता है जैसे इंटरफ़ेस को प्रस्तुत करते समय JavaFX कोड में कोई अपवाद होता है, यह रेंडरिंग को बाधित करता है, लेकिन कंसोल को प्रिंट नहीं करता है ...


सामान्य तौर पर, आपको नियमित अभिव्यक्तियों के आधार पर वाक्य रचना को हाइलाइट करने के लिए बस एक मा-ए-स्कारलेट क्लास जोड़ने की आवश्यकता होती है। मेरे मामले में, यह net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.ModelicaSyntaxHighlighter , जो कि AvailableSyntaxHighlighters net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.ModelicaSyntaxHighlighter वर्ग में पंजीकृत होना चाहिए। कृपया ध्यान दें कि ये दोनों परिवर्तन pmd-designer रिपॉजिटरी में होते हैं, जिसकी असेंबली आर्टिफिशियल को आपके बाइनरी डिस्ट्रीब्यूशन में डालने की आवश्यकता है।


अंत में, यह कुछ इस तरह दिखता है (PMD डिजाइनर रिपॉजिटरी में README से लिया गया GIF))


काम पर पीएमडीआई डिजाइनर


उप-योग


यदि आपने इन सभी स्तरों को पूरा कर लिया है, तो अब आपके पास है:


  • कॉपी पेस्ट डिटेक्टर
  • नियम इंजन
  • एएसटी डिबगिंग के लिए विज़ुअलाइज़र और विश्लेषण के लिए इसे एक सुविधाजनक रूप में लाना (जैसा कि हमने पहले ही देखा है, एक ही भाषा के सभी व्याकरण समान रूप से उपयोगी नहीं हैं!)
  • XPath नियमों को डीबग करने के लिए वही विज़ुअलाइज़र जो आपके उपयोगकर्ता पीएमडी को फिर से लिखने के बिना लिख ​​सकते हैं और आम तौर पर जावा (XPath का ज्ञान, निश्चित रूप से, यह भी BASIC नहीं है, लेकिन यह कम से कम एक मानक और एक स्थानीय क्वेरी भाषा नहीं है)

मुझे आशा है कि आपको इस तथ्य की भी समझ होगी कि व्याकरण अब भाषा समर्थन के आपके कार्यान्वयन के लिए एक स्थिर एपीआई है - इसे तब तक न बदलें (या इसके द्वारा वर्णित स्रोत को एएसटी में परिवर्तित करने का कार्य) जब तक कि बिल्कुल आवश्यक न हो, और यदि आप बदल गए हैं, तो ब्रेकिंग परिवर्तन के रूप में सूचित करें। और फिर उपयोगकर्ता परेशान होंगे: सबसे अधिक संभावना है, हर कोई अपने नियमों के लिए परीक्षण नहीं लिखेगा, लेकिन यह बहुत दुख की बात है जब नियमों ने कोड की जांच की, और फिर चेतावनी के बिना बंद कर दिया - लगभग एक बैकअप की तरह, जो अचानक टूट गया, और एक साल पहले ...


कहानी यहीं समाप्त नहीं होती है: कम से कम कुछ उपयोगी नियमों को लिखना होगा।


लेकिन यह सब नहीं है: पीएमडी मूल रूप से स्कोप और घोषणाओं का समर्थन करता है। प्रत्येक एएसटी नोड में इसके साथ गुंजाइश है: वर्ग, फ़ंक्शन, लूप का शरीर ... पूरी फ़ाइल, सबसे खराब! और हर दायरे में परिभाषाओं (घोषणाओं) की एक सूची है जो सीधे इसमें शामिल है। अन्य मामलों में, इसे अन्य भाषाओं के साथ सादृश्य द्वारा लागू करने का प्रस्ताव है, उदाहरण के लिए, मॉडलिका (लेकिन लेखन के समय, मेरे पुल अनुरोध में तर्क काफी स्पष्ट है, कच्चा है)। scopes declarations visitor, - ScopeAndDeclarationFinder , — , , , - , read-only AST. , .


 public class ModelicaHandler extends AbstractLanguageVersionHandler { // ... @Override public VisitorStarter getSymbolFacade() { return new VisitorStarter() { @Override public void start(Node rootNode) { new SymbolFacade().initializeWith((ASTStoredDefinition) rootNode); } }; } } 

निष्कर्ष


PMD . , «» Clang Static Analyzer , . , CPD ( ), .

Source: https://habr.com/ru/post/hi474920/


All Articles