كتابة أول SymbolProcessor لك
نفّذ معالج KSP يبحث عن الأصناف المعلّمة بتعليقات توضيحية ويسجّلها.
كتابة أول SymbolProcessor لك درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
بنية المشروع
يعيش معالج KSP في وحدة Gradle منفصلة (مثل :processor). وتطبّق الوحدة المستهلكة إضافة KSP وتعلن عن تبعية ksp على وحدة المعالج. أما وحدة المعالج نفسها، فلديها تبعية implementation عادية على واجهة برمجة تطبيقات KSP.
إضافة تبعيات KSP
في ملف build.gradle.kts الخاص بوحدة المعالج:
plugins { kotlin("jvm") }
dependencies {
implementation("com.google.devtools.ksp:symbol-processing-api:2.0.0-1.0.21")
}واجهة SymbolProcessor
طبّق SymbolProcessor. ونقطة الدخول الرئيسية هي process(resolver: Resolver): List. أعد الرموز التي لم تتمكن من معالجتها، مثل الرموز التي لم تُحل تبعياتها بعد، كي تُعالَج في جولة ثانية.
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*
class MyProcessor(private val logger: KSPLogger,
private val codeGenerator: CodeGenerator) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation("com.example.MyAnnotation")
// process symbols here
return emptyList()
}
}SymbolProcessorProvider
يكتشف KSP معالجكم عبر SymbolProcessorProvider. سجّلوه في resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider:
class MyProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
MyProcessor(
logger = environment.logger,
codeGenerator = environment.codeGenerator
)
}ملف تسجيل الخدمة
أنشئوا الملف في المسار المحدد تمامًا داخل موارد وحدة المعالج:
- المسار:
src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider - المحتوى: الاسم المؤهل بالكامل لفئة
SymbolProcessorProviderالخاصة بكم
حل الرموز حسب التعليق التوضيحي
استخدم resolver.getSymbolsWithAnnotation(fqn) للحصول على جميع الإعلانات التي تحمل تعليقكم التوضيحي. صَفِّها وفق نوع الإعلان المتوقع، مثل إعلانات الفئات:
val classes = resolver
.getSymbolsWithAnnotation("com.example.MyAnnotation")
.filterIsInstance<KSClassDeclaration>()التحقق من الرموز
قبل المعالجة، تحقّق من إمكانية حل كل رمز بالكامل. فالرمز الذي تشير أنواعُه إلى مراجع لم تُترجم بعد لا يُعد صالحًا. أعد هذه الرموز من process() لإعادة محاولة معالجتها في الجولة التالية:
val (valid, deferred) = classes.partition { it.validate() }
// process valid; return deferredزيارة إعلان فئة
استخدم نمط الزائر KSVisitorVoid لاجتياز بنية الفئة. وتجاوز visitClassDeclaration للوصول إلى الخصائص والدوال والفئات المتداخلة:
class MyVisitor : KSVisitorVoid() {
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
val name = classDeclaration.simpleName.asString()
val props = classDeclaration.getAllProperties().toList()
println("Class: $name, props: ${props.size}")
}
}تسجيل الرسائل من معالج
استخدم KSPLogger لإصدار رسائل بمستويات مختلفة. يؤدي logger.error() إلى فشل البناء؛ ويطبع logger.warn() تحذيرًا؛ ويطبع logger.info() رسالة إعلامية تظهر عند استخدام --info.
logger.info("Processing class: ${classDeclaration.simpleName.asString()}")
logger.error("Missing required annotation", classDeclaration)الوصول إلى التعليقات التوضيحية على رمز
يحتوي كل KSDeclaration على تسلسل annotations. استخدم filter وarguments لقراءة قيم التعليق التوضيحي:
val ann = classDeclaration.annotations
.first { it.shortName.asString() == "MyAnnotation" }
val value = ann.arguments.first { it.name?.asString() == "value" }.value as Stringإرشادات المعالجة التزايدية
أخبر KSP بالملفات الناتجة التي تعتمد على رموز الإدخال، وذلك بربطها عبر CodeGenerator.createNewFile(dependencies = ...). ويتيح هذا لـ KSP تخطي معالجكم عندما لا يتغير أي من مدخلاته.
تحقق سريع
كيف يكتشف KSP تطبيق SymbolProcessorProvider الخاص بكم؟
مراجعة: كتابة أول SymbolProcessor
أهم النقاط:
- تطبيق
SymbolProcessorوSymbolProcessorProviderفي وحدة منفصلة - تسجيل الموفر عبر
META-INF/services/ - استخدام
resolver.getSymbolsWithAnnotation()للعثور على الرموز التي تحمل تعليقات توضيحية - التحقق من الرموز قبل معالجتها، وإعادة الرموز التي لم تُحل لإعادة المحاولة
- استخدام
KSPLoggerلرسائل وقت البناء وCodeGeneratorلكتابة الملفات
الأسئلة الشائعة
هل درس «كتابة أول SymbolProcessor لك» مجاني؟
نعم — نص درس «كتابة أول SymbolProcessor لك» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
ماذا ستتعلم في «كتابة أول SymbolProcessor لك»؟
نفّذ معالج KSP يبحث عن الأصناف المعلّمة بتعليقات توضيحية ويسجّلها. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟
لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «كتابة أول SymbolProcessor لك»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟
نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- KSP مقابل KAPT: لماذا KSP أسرع
- كتابة أول SymbolProcessor لك
- إنشاء ملفات مصدر Kotlin باستخدام KotlinPoet
- دمج معالجات KSP في عملية بناء Gradle