2017-05-19 17 views
15

मैं रोज़लिन में एक वाक्यविन्यास पेड़ के भीतर नोड्स को प्रतिस्थापित करने की कोशिश कर रहा हूं, और यह सिर्फ काम करने के बारे में है, लेकिन एक परेशानी के साथ यह महसूस करता है कि कोई समस्या नहीं होनी चाहिए।SyntaxNode.ReplaceNode SyntaxTree विकल्पों को क्यों बदलता है?

सिंटैक्स पेड़ एक स्क्रिप्ट से उत्पन्न होता है, और मैं परिणाम को स्क्रिप्ट-आधारित सिंटैक्स पेड़ भी बनना चाहता हूं - लेकिन किसी कारण से, पेड़ में नोड को बदलकर बदलते विकल्पों के साथ एक नया वाक्यविन्यास पेड़ बनाता है: KindScript के बजाय Regular बन जाता है। यह SyntaxTree.WithRootAndOptions के साथ फिक्स करने योग्य है लेकिन ऐसा लगता है कि अगर मुझे कॉल करने की आवश्यकता है तो मैं कुछ गलत कर रहा हूं।

नमूना कार्यक्रम:

using Microsoft.CodeAnalysis; 
using Microsoft.CodeAnalysis.CSharp; 
using Microsoft.CodeAnalysis.CSharp.Scripting; 
using Microsoft.CodeAnalysis.CSharp.Syntax; 
using Microsoft.CodeAnalysis.Scripting; 
using System; 
using System.Linq; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Script script = CSharpScript.Create("Console.WriteLine(\"Before\")", 
      ScriptOptions.Default.AddImports("System")); 

     var compilation = script.GetCompilation(); 
     var tree = compilation.SyntaxTrees.Single(); 

     var after = SyntaxFactory.LiteralExpression(
      SyntaxKind.StringLiteralExpression, 
      SyntaxFactory.Literal("After")); 

     var root = tree.GetRoot(); 
     var before = root.DescendantNodes().OfType<LiteralExpressionSyntax>().Single(); 
     var newRoot = root.ReplaceNode(before, after); 
     var fixedTree = newRoot.SyntaxTree.WithRootAndOptions(newRoot, tree.Options); 

     Console.WriteLine(newRoot);       // Console.WriteLine("After") 
     Console.WriteLine(tree.Options.Kind);    // Script 
     Console.WriteLine(newRoot.SyntaxTree.Options.Kind); // Regular 
     Console.WriteLine(fixedTree.Options.Kind);   // Script 
    } 
} 

(। आउटपुट टिप्पणी में है)

इस समाधान वास्तव में सही है, या वहाँ कुछ अलग तरह से मैं एक वृक्ष के नोड की जगह किया जाना चाहिए?

+0

भाषा संस्करण भी बदलता है। यदि आप सी # 5 सिंटैक्स पेड़ चाहते हैं तो आपको स्पष्ट रूप से निर्दिष्ट करना होगा। मैंने 'विथ रूट एंड ऑप्शन()' का भी उपयोग किया और इसके साथ कभी भी समस्या नहीं थी। – Tamas

+0

मेरा आंत कह रहा है कि यह एक बग है ... –

+0

@ जेसनमालिनोस्की: मुझे खुशी है कि आप यह कहने वाले हैं - मैं निश्चित रूप से नहीं चाहता था :) (लेकिन हाँ, यह मुझे भी ऐसा लगता है।) –

उत्तर

0

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

कारण रोसलिन इस SyntaxTree बनाता है कि इतने सारे उप पेड़ तकनीकी तौर पर, एक SyntaxTree उदाहरण के भीतर समाहित कर रहे हैं ताकि रोसलिन इसके साथ निदान जुड़े कर सकते हैं। यह उपयोगी है यदि आप & को बाध्य करने के प्रयास के लिए सेमेन्टिक मॉडेल की खोजी एपीआई का उपयोग करते हैं, जो पेड़ों के टुकड़ों के लिए अर्थपूर्ण जानकारी प्राप्त करते हैं जो वर्तमान में संकलन का हिस्सा नहीं हैं। नैदानिक ​​त्रुटि और उसके स्थान की रिपोर्ट करता है, जो पेड़ के उदाहरण को इंगित करता है।

+1

"यहां तक ​​कि यदि यह संभव था, तो विकल्प बनाए रखना व्यर्थ होगा क्योंकि अब आपके पास पार्सर द्वारा उत्पादित पेड़ नहीं है।" हालांकि व्यावहारिक कारण से सैद्धांतिक की तरह यह बहुत अधिक लगता है।निश्चित रूप से यह कहना असामान्य परिदृश्य नहीं है कि "मैं चाहता हूं कि यह पेड़ दूसरे की तरह हो, क्योंकि यह एक नोड बदल गया।" जब मेरे पास अधिक समय होता है, तो मुझे आपके बाकी उत्तर को ध्यान से पढ़ने की ज़रूरत है, लेकिन मूल रूप से यह कम से कम एपीआई उपयोग के मामले में * अजीब * लगता है। यह उस तरह से हो सकता है, लेकिन यह दुर्भाग्यपूर्ण आईएमओ है :( –

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