การเขียนไวยากรณ์ใหม่

ฉันต้องแปลงคุณสมบัติทั้งหมดของคลาสหนึ่งโดยใช้ Roslyn

วิธีที่แนะนำในการใช้การแปลงมากกว่าหนึ่งรายการกับแผนผังไวยากรณ์โดยไม่ทำให้การอ้างอิงนั้นไม่ถูกต้องคืออะไร


นี่คือสิ่งที่ฉันได้ลองและติดขัดอยู่:

  • ในการผ่านครั้งแรก ผู้สืบทอดของ CSharpSyntaxWalker กำลังเยี่ยมชมโหนด PropertyDeclarationSyntax ทั้งหมด และจัดเก็บไว้ในรายการ

  • ในการผ่านครั้งที่สอง CSharpSyntaxRewriter กำลังเปลี่ยนโหนดในขณะที่ตรวจสอบว่าแต่ละโหนดที่เยี่ยมชมมีค่าเท่ากับหนึ่งในรายการก่อนทำการแปลง

ปัญหาในความพยายามของฉันคือ: เมื่อฉันแปลงคุณสมบัติ ฉันจะเพิ่มฟิลด์ใหม่ให้กับคลาสซึ่งทำให้คลาสกลายพันธุ์ การอ้างอิงทั้งหมดในรายการไปยังคุณสมบัติอื่น ๆ จะไม่ถูกต้องในแผนผังใหม่สำหรับชั้นเรียน

ดูเหมือนว่าจะไม่มีประสิทธิภาพในการกลับมาทบทวนทั้งชั้นเรียนอีกครั้ง และไม่ว่าจะด้วยวิธีใดก็ตาม ฉันก็ตรวจไม่พบโหนดคุณสมบัติที่ได้รับการจัดการแล้วเนื่องจากความแตกต่างในการอ้างอิง


person Liviu    schedule 29.05.2014    source แหล่งที่มา
comment
คุณช่วยอธิบายรายละเอียดเพิ่มเติมหน่อยได้ไหมว่าคุณกำลังทำอะไรอยู่? บางทีอาจแสดงรหัสบางส่วน?   -  person Dan Puzey    schedule 29.05.2014
comment
ฉันได้เพิ่มข้อมูลเพิ่มเติมในโพสต์ต้นฉบับ   -  person Liviu    schedule 29.05.2014
comment
ฉันคิดว่าคุณต้องโพสต์รหัสที่เกี่ยวข้อง ฉันไม่ชัดเจนว่าคุณกำลังทำอะไรอยู่   -  person Dan Puzey    schedule 29.05.2014
comment
@DanPuzey ฉันได้แก้ไขคำถามแล้ว โปรดแจ้งให้เราทราบว่าสิ่งที่ OP ถามนั้นชัดเจนกว่านี้ในความคิดเห็นของคุณหรือไม่   -  person Benjamin Gruenbaum    schedule 01.06.2014


คำตอบ (1)


ฉันไม่แนะนำให้อ้างอิงโหนดจาก SyntaxTree ที่คุณต้องการแก้ไข ในกรณีของคุณ การใช้ CSharpSyntaxRewriter ในการผ่านครั้งเดียว (โดยไม่ เก็บการอ้างอิงจากบัตรผ่านการประมวลผลล่วงหน้า) ก็เพียงพอแล้ว เนื่องจากเมธอด VisitPropertyDeclaration ของมันจะถูกเรียกใช้เพียงครั้งเดียวต่อคุณสมบัติ ดังนั้นจึงไม่จำเป็นต้อง เพื่อติดตามโหนดที่คุณได้แก้ไขแล้ว

CSharpSyntaxRewriter ยังไปที่โหนดจากล่างขึ้นบน ดังนั้นการแทนที่ควรถูกเรียกด้วยโหนดจากแผนผังดั้งเดิมเสมอ เป็นไปได้มากว่าคุณได้แก้ไข node ผ่านการเรียกเป็น base.VisitPropertyDeclaration() ก่อนที่จะเปรียบเทียบการอ้างอิงกับข้อมูลที่เก็บไว้ ดังนั้นคุณจึงยังสามารถเก็บและเปรียบเทียบข้อมูลอ้างอิงได้หากต้องการ

public class PropertyRewriter : CSharpSyntaxRewriter
{
    public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
    {
        // 'node' should be still from the original syntax tree here

        node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node);

        // 'node' might be replaced here

        return node;
    }
}

แทนที่จะเก็บการอ้างอิงไปยังโหนดที่คุณต้องการแก้ไข คุณสามารถใส่คำอธิบายประกอบได้ คำอธิบายประกอบไปยังโหนดจะคงอยู่ต่อไปจากการแก้ไขที่มี SyntraxTree ตราบใดที่โหนดนั้นไม่ได้ถูกแทนที่ คุณสามารถเพิ่มได้ดังนี้:

node = node.WithAdditionalAnnotations(
        new SyntaxAnnotation("propertyToChange", "todo"));

หากต้องการดึงคำอธิบายประกอบอีกครั้ง ให้ใช้ node.GetAnnotations("propertyToChange") หรือใช้ GetAnnotatedNodesOrTokens("propertyToChange") เพื่อดึงโหนดหรือโทเค็นทั้งหมดที่มีคำอธิบายประกอบตามประเภทที่กำหนด ("propertyToChange")

person andyp    schedule 03.06.2014