2011-10-17 13 views
35

एक स्कैला कंपाइलर प्लगइन में, मैं एक नई कक्षा बनाने की कोशिश कर रहा हूं जो पूर्व-मौजूदा विशेषता को कार्यान्वित करे। अब तक मेरा कोड इस तरह दिखता है:स्कैला कंपाइलर प्लगइन में एक नई कक्षा कैसे जोड़ें?

def trait2Impl(original: ClassDef, newName: String): ClassDef = { 
    val impl = original.impl 
    // Seems OK to have same self, but does not make sense to me ... 
    val self = impl.self 
    // TODO: implement methods ... 
    val body = impl.body 
    // We implement original 
    val parents = original :: impl.parents 
    val newImpl = treeCopy.Template(impl, parents, self, body) 
    val name = newTypeName(newName) 
    // We are a syntheic class, not a user-defined trait 
    val mods = (original.mods | SYNTHETIC) &~ TRAIT 
    val tp = original.tparams 
    val result = treeCopy.ClassDef(original, mods, name, tp, newImpl) 
    // Same Package? 
    val owner = original.symbol.owner 
    // New symbol. What's a Position good for? 
    val symbol = new TypeSymbol(owner, NoPosition, name) 
    result.setSymbol(symbol) 
    symbol.setFlag(SYNTHETIC) 
    symbol.setFlag(ABSTRACT) 
    symbol.resetFlag(INTERFACE) 
    symbol.resetFlag(TRAIT) 
    owner.info.decls.enter(symbol) 
    result 
} 

लेकिन ऐसा लगता है कि यह पैकेज में जोड़ा नहीं जा रहा है। मुझे संदेह है कि वास्तव में यह पैकेज पीढ़ी के कारण होने वाली विशेषता से पहले "घुमावदार" हो गया है, और/या क्योंकि "ओवरराइड डीफ़ ट्रांसफॉर्म (पेड़: वृक्ष): ट्रीपिंग ट्रांसफॉर्मर की विधि" पेड़ "विधि केवल एक पेड़ लौटा सकती है, के लिए हर पेड़ जो इसे प्राप्त करता है, इसलिए यह वास्तव में एक नया पेड़ नहीं बना सकता है, लेकिन केवल एक को संशोधित कर सकता है।

तो, आप मौजूदा पैकेज में एक नई कक्षा कैसे जोड़ते हैं? शायद यह काम करेगा अगर मैंने पैकेज को बदल दिया, जब "ट्रांसफॉर्म (ट्री)" इसे प्राप्त करता है, लेकिन मुझे लगता है कि मुझे अभी तक पैकेज की सामग्री नहीं पता है, इसलिए मैं इस कक्षा में नई कक्षा उत्पन्न नहीं कर सकता (या मैं कर सकता हूं?) । या शायद यह प्रतीक के "स्थिति" पैरामीटर से संबंधित है?

अब तक मुझे कई उदाहरण मिले हैं जहां पेड़ संशोधित किए गए हैं, लेकिन कंपाइलर प्लगइन में कोई भी पूरी तरह से नई कक्षा नहीं बनाई गई है।

+0

में बदल देती है तो आप समस्या का समाधान हो गया है? मेरे पास एक समान है, इसलिए मैं सोच रहा था ... मुझे लगता है कि दुर्भाग्यवश, आपको ट्रांसफॉर्म विधि में अपने गुण के माता-पिता के लिए मिलान करने की आवश्यकता है। यही है, पैकेजडिफ और टेम्पलेट के लिए देखो, और अपने शरीर में अपने गुणों की सभी घटनाओं को ढूंढें। फिर आप एक रूपांतरित पैकेजडिफ और टेम्पलेट –

+0

वापस कर सकते हैं हां, मुझे स्कैला मेलिंग सूची से सहायता मिली है। लेकिन मैं अभी तक नहीं हूं, क्योंकि मैं केवल उसी पैकेज में कक्षा बना सकता हूं *। जब मैं चीजों को हल करता हूं तो मैं अपने प्रश्न का उत्तर पोस्ट करने का प्रयास करूंगा। –

+0

कृपया अभी अपने प्रश्न का उत्तर दें! क्योंकि मेरे पास वही है [प्रश्न] (https://github.com/iron9light/autoguice) – iron9light

उत्तर

2

पूर्ण स्रोत कोड यहाँ है: https://gist.github.com/1794246

चाल नव निर्मित ClassDef रों की दुकान और जब एक नया PackageDef बनाने के लिए उन्हें का उपयोग करने के लिए है। ध्यान दें कि आपको दोनों प्रतीकों और पेड़ों से निपटने की ज़रूरत है: एक पैकेज प्रतीक सिर्फ एक हैंडल है। कोड उत्पन्न करने के लिए, आपको एक एएसटी उत्पन्न करना होगा (बस एक वर्ग के लिए, जहां प्रतीक वर्ग का नाम और प्रकार रखता है, लेकिन कोड ClassDef पेड़ों में है)।

जैसा कि आपने देखा है, कक्षाओं की तुलना में पैकेज परिभाषाएं पेड़ से अधिक हैं, इसलिए आपको पहले रिकर्स करना होगा (माना जाता है कि आप मौजूदा कक्षा से नई कक्षा उत्पन्न करेंगे)। फिर, एक बार subtrees ट्रैवर्स हो जाने के बाद, आप एक नई पैकेजडिफ तैयार कर सकते हैं (प्रत्येक संकलन इकाई में एक पैकेज परिभाषा है, जो डिफ़ॉल्ट रूप से खाली पैकेज है) नई कक्षाओं के साथ।

उदाहरण में, स्रोत कोड संभालने

class Foo { 
    def foo { 
    "spring" 
    } 
} 

संकलक

package <empty> { 
    class Foo { 
    def foo { 
     "spring" 
    } 
    } 
} 

में लपेटता है और प्लगइन

package <empty> { 
    class Foo { 
    def foo { 
     "spring" 
    } 
    } 
    package mypackage { 
    class MyClass extends AnyRef 
    } 
} 
+0

धन्यवाद! मैंने इसे 'कोशिश की', लेकिन चूंकि आप "गुरु" में से एक हैं, तो आपको यह सही होना चाहिए। मैं इसे जोड़ना चाहूंगा, और इसका विशेष रूप से आपके साथ कुछ लेना देना नहीं है, मैंने महीनों में स्कैला का उपयोग नहीं किया है और मैं लोगों से यह शिकायत कर सकता हूं कि स्कैला समुदाय असभ्य/अनुपयोगी/अनन्य है जब ऐसे मूल प्रश्न (यह है जावा कंपाइलर प्लगइन में नो-ब्रेनर) केवल * महीने * के बाद उत्तर दिया जाता है * जब कोई व्यक्ति उन पर बक्षीस डालता है "*। मैंने स्कैला भाषा मेलिंग सूची पर पूछा और यहां तक ​​कि उपयोगी मदद भी नहीं मिली ... कृपया डॉन इसे व्यक्तिगत रूप से नहीं लेते; मैं आपके उत्तर के लिए आभारी हूं! –

+2

मैं आपका विचार समझता हूं, लेकिन कृपया इस प्रश्न के आधार पर स्कैला समुदाय का न्याय न करें। अधिकांश स्कैला प्रश्नों को गुणवत्ता, तेज़ उत्तर मिलते हैं, लेकिन यह निश्चित रूप से ' कोई ब्रेनर नहीं है। इसके लिए किसी को संकलक पर उत्तर देने के लिए काम करने की आवश्यकता होती है (स्कैला टीम में ज्यादातर लोग अक्सर एसओवी नहीं पढ़ते हैं), और ऐसा कुछ है जो 'स्केलैक' कभी नहीं करता है, इसलिए एक उदाहरण ढूंढना असंभव है। हालांकि समाधान छोटा है, मुझे सब कुछ पाने के लिए लगभग एक घंटे लग गए सही ढंग से चल रहा है। –

+0

फिर से धन्यवाद! इसे शीघ्रता से रखने के लिए, जब किसी के पास "जावा प्रश्न" होता है, तो वे यहां या दर्जनों अन्य स्थानों पर पूछ सकते हैं, और एक उत्तर (यदि कोई है) प्राप्त करना सुनिश्चित है, लेकिन जब एक स्कैला प्रश्न का उत्तर न दिया गया है और न ही स्कैला मेलिंग सूचियां, फिर यह है, आप अपने आप हैं, और यह वास्तव में निराशाजनक है। मैं चाहता हूं कि कोई "कट्टर स्कैला" किताब लिखे; "गहराई में स्केल" अभी भी समाप्त नहीं हुआ है, और यदि यह लगभग 200 पृष्ठों तक लंबा होगा, तो यह केवल "हार्ड सामान" की सतह को खरोंच करेगा। लेकिन हार्ड सामान जावा की तुलना में बहुत कठिन है, और पर्याप्त संभावित खरीदारों नहीं हैं। –

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