العودة إلى التحديثات
New releaseJul 24, 2026

trailmark v0.5.0

بناء والاستعلام عن تمثيل قاعدة بيانات رسومية لشفرة المصدر

مشاركة

Trailmark

CI Mutation Testing

حلّل الشيفرة المصدرية إلى رسوم بيانية قابلة للاستعلام تتضمّن الدوال والأصناف والاستدعاءات والتعليقات الدلالية لأغراض تحليل الأمان.

يستخدم Trailmark مكتبة tree-sitter لتحليل شجرة التركيب النحوي (AST) بشكل مستقل عن اللغة، ومكتبة rustworkx لاجتياز الرسوم البيانية عالي الأداء. تتمثل الرؤية طويلة المدى في دمج هذا الرسم البياني مع اختبار الطفرات والاختبار التوجيهي القائم على التغطية (coverage-guided fuzzing) لتحديد الفجوات بين الافتراضات وتغطية الاختبارات التي يمكن الوصول إليها من مدخلات المستخدم.

كيف يعمل

يعمل Trailmark على ثلاث مراحل: التحليل، والفهرسة، والاستعلام.

flowchart TD
    A["Source Files"] --> B["tree-sitter Parser"]
    B --> C["CodeGraph (nodes + edges)"]
    C --> D["rustworkx GraphStore"]
    D --> E["QueryEngine"]
    E --> F["JSON / Summary / Hotspots"]

    classDef src fill:#007bff26,stroke:#007bff,color:#007bff
    classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
    classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1
    classDef query fill:#ffc10726,stroke:#e6a817,color:#e6a817

    class A src
    class B parse
    class C,D data
    class E,F query

1. التحليل

يقوم محلل خاص بكل لغة بالمرور على الدليل، وتحليل كل ملف إلى شجرة AST باستخدام tree-sitter، واستخراج:

  • العُقد — الدوال، والطرق، والأصناف، والبنى، والواجهات، والسمات، والتعدادات، والوحدات، والنطاقات
  • الحواف — الاستدعاءات، والوراثة، والتنفيذ، والاحتواء، والاستيرادات
  • البيانات الوصفية — تعليقات النوع، والتعقيد الحلقي، والفروع، وسلاسل التوثيق، وأنواع الاستثناءات

اللغات المدعومة

اللغةالامتداداتالبُنى الأساسية
Python.pyالدوال، والأصناف، والطرق
JavaScript.js، .jsx، .mjs، .cjsالدوال، والأصناف، ودوال السهم
TypeScript.ts، .tsxالدوال، والأصناف، والواجهات، والتعدادات
PHP.phpالدوال، والأصناف، والواجهات، والسمات
Ruby.rbالطرق، والأصناف، والوحدات
C.c، .hالدوال، والبنى، والتعدادات
C++.cpp، .hpp، .cc، .hh، .cxx، .hxxالدوال، والأصناف، والبنى، والنطاقات
C#.csالطرق، والأصناف، والواجهات، والبنى، والتعدادات، والنطاقات
Java.javaالطرق، والأصناف، والواجهات، والتعدادات
Go.goالدوال، والطرق، والبنى، والواجهات
Rust.rsالدوال، والبنى، والسمات، والتعدادات، وكتل impl، وكتل verus!
Solidity.solالعقود، والواجهات، والمكتبات، والدوال، والمعدِّلات، والبنى، والتعدادات
Cairo.cairoالدوال، والسمات، والبنى، والتعدادات، وكتل impl، وعقود StarkNet
Circom.circomالقوالب، والدوال، والإشارات، والمكوّنات
Haskell.hsالدوال، وأنواع البيانات، وأصناف الأنواع، والنسخ
Erlang.erlالدوال، والسجلات، والسلوكيات، والوحدات
Miden Assembly.masmالإجراءات، ونقاط الدخول، والثوابت، والاستدعاءات
Swift.swiftالدوال، والأصناف، والبنى، والتعدادات، والبروتوكولات، والامتدادات
Objective-C.m، .mm، .hدوال C، والأصناف، والطرق (تسمية قائمة على المحدِّد)
Kotlin.kt، .ktsالدوال، والأصناف، والواجهات، وأصناف البيانات، والكائنات، والطرق
Dart.dartالدوال، والأصناف، والأصناف المجردة، والطرق، والبنّاؤون
Move.moveالوحدات، والدوال، والاستيرادات، والاستدعاءات المباشرة
Tact.tactالعقود، والبنى، والمستقبِلات، والدوال
Func.fc، .funcالدوال، والتضمينات، والاستدعاءات المباشرة
Sway.swواجهات ABI، والبنى، وطرق impl، والدوال
Rego.regoالحزم، والاستيرادات، وقواعد السياسة، واستدعاءات القواعد
Proto.protoالخدمات، وRPCs، والرسائل، والحقول، والتعدادات
Thrift.thriftالخدمات، والدوال، والبنى، والحقول، والتعدادات
GraphQL.graphql، .gqlأنواع الكائنات، والعمليات الجذرية، والحقول، والتعدادات
SQL.sqlالمخططات، والجداول، وطرق العرض، والدوال، والإجراءات

محلل Rust يستخرج الدوال العادية وspec وproof مع أجسامها من كتل verus! { ... }. تدعم قواعد Verus حاليًا الكتل المحددة بأقواس معقوفة فقط؛ يتم تخطي verus!(...) وverus![...] مع تحذير. تحتفظ الوحدات المضمّنة بالمعرّفات المؤهلة (على سبيل المثال، file.inner:function)، وتحتفظ الطرق بمالك impl أو trait الخاص بها. يتم تحليل كل كتلة بشكل مستقل؛ تنتج أخطاء الصياغة تحذيرًا مع موقع الملف والكتلة. يتم دعم الاستدعاءات المؤهلة مثل vstd::prelude::verus! أيضًا. تحتفظ الدوال المساعدة المحلية بالدالة المحيطة بها في معرّفاتها (على سبيل المثال، file:outer.inner). تُحل الاستدعاءات لهذه الدوال المساعدة والاستيرادات النسبية مثل use super::* إلى التعريفات الموجودة في الملف. تتلقى الأسماء المحلية المتكررة في كتل مختلفة لاحقة إزاحة بايتية للحفاظ على تميز عقدها، وتحترم الاستدعاءات نطاق الكتلة. تحتفظ البنى المحلية والتعدادات والسمات والوحدات المضمّنة بالدالة المحيطة أيضًا: على سبيل المثال، file:outer.Guard.drop وfile:outer.local.helper. تحتوي أجسامها على استدعاءات وتعقيد منفصلين. تُحل الاستدعاءات الصريحة للأنواع والوحدات المحلية المعروفة داخل الملف. تبحث الاستدعاءات المجردة في نطاقات الدوال والوحدات؛ تستخدم العناصر المرتبطة مسارات مثل Type::method. تُحل الاستدعاءات المنقطة فقط عندما يسمي المستقبل بنية أو تعدادًا معروفًا. تبقى مستقبلات القيم الأخرى، بما في ذلك self.method()، غير محلولة. لا يتم نمذجة استدعاءات المدمر الضمنية واستنتاج نوع المستقبل. تنطبق هذه القواعد على Rust العادي بالإضافة إلى كتل Verus. يؤدي تحرير الكود قبل تعريف ذي لاحقة إزاحة إلى تغيير معرّفه، لذا يمكن لـ trailmark diff الإبلاغ عن ذلك التعريف كمحذوف ومضاف.

لا يوسّع Trailmark وحدات الماكرو العشوائية. يتم تخطي استدعاءات Verus الحرفية داخل وحدات الماكرو المعتمة أو أجسام الدوال مع تحذير. لا يتم توسيع تعريفات macro_rules! غير المستدعاة. لا يتم استخراج توقيعات الدوال بدون أجسام والاستدعاءات في جمل requires/ensures.

flowchart TD
    subgraph "Per-File Parsing"
        F["Source file"] --> TS["tree-sitter AST"]
        TS --> EX["Extract nodes"]
        TS --> EC["Extract call edges"]
        TS --> EB["Count branches"]
        TS --> ET["Resolve types"]
    end

    EX --> CG["CodeGraph"]
    EC --> CG
    EB --> CG
    ET --> CG

    classDef src fill:#007bff26,stroke:#007bff,color:#007bff
    classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
    classDef extract fill:#ffc10726,stroke:#e6a817,color:#e6a817
    classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1

    class F src
    class TS parse
    class EX,EC,EB,ET extract
    class CG data

تُتبع معرّفات العُقد المخطط module:function أو module:Class أو module:Class.method لضمان بحث لا لبس فيه. يحل تحليل الدلائل الاستدعاءات المباشرة بين الملفات عندما يوجد تعريف فريد؛ وتُترك الاستدعاءات الملتبسة بين الملفات عند هدفها الأصلي بأفضل جهد وتُوسم بـ uncertain. تُوسم ثقة الحافة بـ certain (الاستدعاءات المباشرة، self.method()) أو inferred (الوصول إلى السمات على كائنات غير ذاتية) أو uncertain (الإرسال الديناميكي أو الحل الملتبس).

2. الفهرس

يُحمّل GraphStore مخطط CodeGraph في PyDiGraph من rustworkx ويبني تعيينات ثنائية الاتجاه للمعرّفات/الفهارس لاجتياز سريع.

3. الاستعلام

يوفر QueryEngine واجهة برمجية عالية المستوى فوق المخطط المفهرس:

الفئات