في الجزء الأول ، اكتشفنا سبب الحاجة إلى إنشاء الشفرة وسردنا الأدوات اللازمة لإنشاء الشفرة في Dart. في الجزء الثاني ، سنتعلم كيفية إنشاء التعليقات التوضيحية واستخدامها في Dart ، وكذلك كيفية استخدام source_gen و build_runner لبدء إنشاء الكود.

دارت الشروح
التعليقات التوضيحية هي بيانات وصفية نحوية يمكن إضافتها إلى الكود. بمعنى آخر ، إنها فرصة لإضافة معلومات إضافية إلى أي مكون من عناصر التعليمات البرمجية ، على سبيل المثال ، إلى فئة أو طريقة. تُستخدم التعليقات التوضيحية على نطاق واسع في رمز Dart: نستخدم @required
للإشارة إلى أن المعلمة المسماة مطلوبة ، ولن يتم تجميع الكود الخاص بنا إذا لم يتم تحديد المعلمة المشروحة. نستخدم أيضًا @override
للإشارة إلى أنه يتم تنفيذ واجهة برمجة تطبيقات (API) محددة في فئة رئيسية في فصل تابع. تبدأ التعليقات التوضيحية دائمًا بالرمز @
.
كيفية إنشاء الشرح الخاص بك؟
على الرغم من أن فكرة إضافة البيانات الوصفية إلى الكود تبدو غريبة ومعقدة بعض الشيء ، إلا أن التعليقات التوضيحية هي واحدة من أبسط الأشياء في لغة Dart. قيل سابقًا أن التعليقات التوضيحية تحمل ببساطة معلومات إضافية . وهي تشبه PODO (كائنات دارت عادي قديم). وأي صف يمكن أن يكون بمثابة تعليق توضيحي إذا تم تعريف مُنشئ const
فيه :
class { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); } @Todo('hello first annotation', todoUrl: 'https://www.google.com') class HelloAnnotations {}
كما ترون ، التعليقات التوضيحية بسيطة للغاية. وما يهم هو ما سنفعله مع هذه الشروح. هذا سوف يساعدنا source_gen
و build_runner
.
كيفية استخدام build_runner؟
build_runner
هي حزمة Dart التي ستساعدنا على إنشاء ملفات باستخدام كود Dart. سنقوم بتكوين ملفات Builder
باستخدام build.yaml
. عندما يتم تكوينه ، سيتم استدعاء Builder
في كل أمر build
أو عندما يتم تغيير الملف. لدينا أيضًا فرصة لتحليل الكود الذي تم تعديله أو استيفائه لمعايير معينة.
source_gen لفهم رمز دارت
بمعنى ما ، build_runner
هي آلية تجيب على السؤال " متى أحتاج إلى إنشاء رمز؟" في الوقت نفسه ، يجيب source_gen
عن السؤال " ما هي الشفرة التي ينبغي إنشاؤها؟". يوفر source_gen
إطار عمل لإنشاء Builders for build_runner
للعمل. كما يوفر source_gen
واجهة برمجة تطبيقات ملائمة لتحليل وإنشاء التعليمات البرمجية.
وضع كل ذلك معا: تقرير TODO
في الجزء المتبقي من هذه المقالة ، سنفصل مشروع todo_reporter.dart ، والذي يمكن العثور عليه هنا .
هناك قاعدة غير مكتوبة تتبعها جميع المشروعات التي تستخدم إنشاء التعليمات البرمجية: تحتاج إلى إنشاء حزمة تحتوي على تعليقات توضيحية ، وحزمة منفصلة للمولد الذي يستخدم هذه التعليقات التوضيحية. يمكن العثور على معلومات حول كيفية إنشاء مكتبة حزم في Dart / Flutter هنا .
تحتاج أولاً إلى إنشاء دليل todo_reporter.dart
. داخل هذا الدليل ، تحتاج إلى إنشاء دليل todo_reporter
، والذي سيحتوي على التعليق التوضيحي ، todo_reporter_generator
لمعالجة التعليق التوضيحي ، وأخيراً ، دليل example
يحتوي على عرض توضيحي لقدرات المكتبة التي يتم إنشاؤها.
.dart
إضافة لاحقة .dart
إلى اسم الدليل الجذر للتوضيح. بالطبع ، هذا ليس ضروريًا ، لكني أرغب في اتباع هذه القاعدة للإشارة بدقة إلى حقيقة أن هذه الحزمة يمكن استخدامها في أي مشروع Dart. على العكس من ذلك ، إذا أردت الإشارة إلى أن هذه الحزمة مخصصة فقط لـ Flutter (مثل ozzie.flutter ) ، فسأستخدم لاحقة مختلفة. هذا ليس ضروريًا ، إنه مجرد اصطلاح تسمية أحاول الالتزام به.
إنشاء todo_reporter ، حزمة التعليقات التوضيحية البسيطة
سنقوم بإنشاء todo_reporter
داخل todo_reporter.dart
. للقيام بذلك ، قم بإنشاء ملف pubspec.yaml
lib
.
pubspec.yaml
بسيط جدًا:
name: todo_reporter description: Keep track of all your TODOs. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: dev_dependencies: test: 1.3.4
لا توجد تبعيات باستثناء حزمة test
المستخدمة في عملية التطوير.
في دليل lib
، قم بما يلي:
- تحتاج إلى إنشاء ملف
todo_reporter.dart
، حيث ، باستخدام export
، سيتم تحديد جميع الفئات التي لها واجهة برمجة تطبيقات عامة. هذه ممارسة جيدة ، حيث يمكن استيراد أي فئة في الحزمة الخاصة بنا باستخدام import 'package:todo_reporter/todo_reporter.dart';
. يمكنك أن ترى هذه الفئة هنا . - داخل دليل
lib
، سنقوم بإنشاء دليل src
يحتوي على جميع الشفرات - العامة وغير العامة.
في حالتنا ، كل ما نحتاج إلى إضافته هو تعليق توضيحي. لنقم بإنشاء ملف todo.dart
مع todo.dart
التوضيحي:
class Todo { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); }
هذا كل ما يتطلبه الأمر للتعليق. قلت أنها ستكون بسيطة. لكن هذا ليس كل شيء. دعنا نضيف اختبارات الوحدة إلى دليل test
:
todo_test.dart import 'package:test/test.dart'; import 'package:todo_reporter/todo_reporter.dart'; void main() { group('Todo annotation', () { test('must have a non-null name', () { expect(() => Todo(null), throwsA(TypeMatcher<AssertionError>())); }); test('does not need to have a todoUrl', () { final todo = Todo('name'); expect(todo.todoUrl, null); }); test('if it is a given a todoUrl, it will be part of the model', () { final givenUrl = 'http://url.com'; final todo = Todo('name', todoUrl: givenUrl); expect(todo.todoUrl, givenUrl); }); }); }
هذا هو كل ما نحتاجه لإنشاء التعليق التوضيحي. يمكنك العثور على الكود هنا . الآن يمكننا أن نذهب إلى المولد.
القيام بعمل رائع: todo_reporter_generator
الآن وقد عرفنا كيفية إنشاء حزم ، فلنقم بإنشاء حزمة todo_reporter_generator
. يجب أن تكون داخل هذه الحزمة build.yaml
و build.yaml
lib
. يجب أن يكون دليل lib
دليل src
وملف builder.dart
. يُعد todo_reporter_generator
الخاص todo_reporter_generator
حزمة منفصلة ستتم إضافتها باعتبارها dev_dependency
لمشاريع أخرى. هذا لأن إنشاء الكود مطلوب فقط في مرحلة التطوير ، ولا يحتاج إلى إضافته إلى التطبيق النهائي.
pubspec.yaml
كما يلي:
name: todo_reporter_generator description: An annotation processor for @Todo annotations. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: build: '>=0.12.0 <2.0.0' source_gen: ^0.9.0 todo_reporter: path: ../todo_reporter/ dev_dependencies: build_test: ^0.10.0 build_runner: '>=0.9.0 <0.11.0' test: ^1.0.0
الآن لنقم بإنشاء build.yaml
. يحتوي هذا الملف على التكوين الضروري لبناةنا . مزيد من التفاصيل يمكن العثور عليها هنا . build.yaml
النحو التالي:
targets: $default: builders: todo_reporter_generator|todo_reporter: enabled: true builders: todo_reporter: target: ":todo_reporter_generator" import: "package:todo_reporter_generator/builder.dart" builder_factories: ["todoReporter"] build_extensions: {".dart": [".todo_reporter.g.part"]} auto_apply: dependents build_to: cache applies_builders: ["source_gen|combining_builder"]
تشير خاصية import
إلى الملف الذي يحتوي على Builder
، وتشير خاصية builder_factories
إلى الأساليب التي ستنشئ الكود.
الآن يمكننا إنشاء ملف builder.dart
في دليل lib
:
import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter_generator/src/todo_reporter_generator.dart'; Builder todoReporter(BuilderOptions options) => SharedPartBuilder([TodoReporterGenerator()], 'todo_reporter');
وملف todo_reporter_generator.dart
في دليل src
:
import 'dart:async'; import 'package:analyzer/dart/element/element.dart'; import 'package:build/src/builder/build_step.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter/todo_reporter.dart'; class TodoReporterGenerator extends GeneratorForAnnotation<Todo> { @override FutureOr<String> generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) { return "// Hey! Annotation found!"; } }
كما ترون ، في ملف builder.dart
قمنا بتعريف طريقة todoReporter
التي ينشئها Builder
. يتم إنشاء Builder
باستخدام SharedPartBuilder
، والذي يستخدم TodoReporterGenerator
. لذلك build_runner
و source_gen
العمل معا.
TodoReporterGenerator
الخاص TodoReporterGenerator
هو فئة فرعية من GeneratorForAnnotation
، لذلك لن يتم تنفيذ طريقة @Todo
إلا عند العثور على هذا التعليق التوضيحي ( @Todo
في حالتنا) في الكود.
تقوم generateForAnnotatedElement
generForAnnotatedElement بإرجاع سلسلة تحتوي على الكود الذي تم إنشاؤه. إذا لم يتم تجميع التعليمات البرمجية المنشأة ، فسوف تفشل مرحلة الإنشاء بأكملها . هذا مفيد للغاية لأنه يتجنب الأخطاء في المستقبل.
وبالتالي ، مع كل جيل من الشفرات ، todo_repoter_generator
ملف part
، مع تعليق // Hey! Annotation found!
// Hey! Annotation found!
في المقالة التالية ، سنتعلم كيفية معالجة التعليقات التوضيحية.
ضعها جميعًا معًا: باستخدام todo_reporter
يمكنك الآن شرح كيفية todo_reporter.dart
. من الممارسات الجيدة إضافة مشروع example
عند العمل مع الحزم. لذلك سيتمكن المطورون الآخرون من معرفة كيفية استخدام واجهة برمجة التطبيقات في مشروع حقيقي.
لنقم بإنشاء مشروع وإضافة التبعيات المطلوبة إلى pubspec.yaml
. في حالتنا ، سننشئ مشروع رفرفة داخل دليل example
ونضيف التبعيات:
dependencies: flutter: sdk: flutter todo_reporter: path: ../todo_reporter/ dev_dependencies: build_runner: 1.0.0 flutter_test: sdk: flutter todo_reporter_generator: path: ../todo_reporter_generator/
بعد تلقي الحزم ( flutter packages get
) ، يمكننا استخدام التعليق التوضيحي الخاص بنا:
import 'package:todo_reporter/todo_reporter.dart'; @Todo('Complete implementation of TestClass') class TestClass {}
الآن بعد أن أصبح كل شيء في مكانه ، قم بتشغيل مولدنا:
$ flutter packages pub run build_runner build
بعد اكتمال الأمر ، ستلاحظ وجود ملف جديد في مشروعنا: todo.g.dart
. وسوف تحتوي على ما يلي:
لقد حققنا ما أردنا! الآن يمكننا إنشاء ملف Dart الصحيح لكل تعليق توضيحي على @Todo
في التعليمات البرمجية الخاصة بنا. حاول وإنشاء ما تحتاج إليه.
في المقال التالي
الآن لدينا الإعدادات الصحيحة لإنشاء الملفات. في المقالة التالية ، سوف نتعلم كيفية استخدام التعليقات التوضيحية حتى تتمكن الشفرة التي تم إنشاؤها من فعل أشياء رائعة حقًا. بعد كل شيء ، الكود الذي يتم إنشاؤه الآن لا معنى له.