Dart-自定义Lint之路(一)-创建Analyzer Plugin

1,117 阅读2分钟

官方参考文档

官方的参考文档,看IntroductionPackage StructureGetting Started 三个章节即可。不过基本上看完也是蒙的。因此下面直接说明如何最简单地创建一个Analyzer Plugin。

创建Plugin项目

创建一个最简单的Dart项目,不需要创建Flutter项目。项目结构如下(根目录为analyzer_plugin文件夹):

image.png pubspec.yaml的内容如下:

name: my_plugin #这个是插件名,是最终被另外工程引用时的名称 
description: A plugin for Analyzer Server. 
version: 1.0.0 
publish_to: none 
environment:   
    sdk: ">=2.14.0 <3.0.0" #根据需要修改dart的版本  
dependencies:  
dev_dependencies:

创建Plugin目录

在根目录下,创建tools/analyzer_plugin/pubspec.yaml和tools/analyzer_plugin/bin/plugin.dart两个文件,文件夹名和文件名不能被修改,然后填写内容:

pubspec.yaml:

#这个是插件实现的项目 
name: pluginImpl 
version: 0.0.1 
publish_to: none  
environment:   
    sdk: ">=2.14.0 <3.0.0"  
dependencies:   
    analyzer: 4.0.0   
    analyzer_plugin: 0.10.0   
    my_plugin: #这里需要关联起外部的容器项目     
        path: ../../../analyzer_plugin/

plugin.dart:

import 'dart:isolate';  
void main(List<String> args, SendPort sendPort) {
}

这个plugin.dart中的main方法就是插件运行的入口函数。

实现一个的Plugin

有了入口函数后,就可以开始编写Plugin的具体内容了。一般会把具体实现的代码,放置在标准Dart项目的目录结构中,也就是lib/src文件夹下,所以创建对应目录:

image.png

接着直接从官网教程上copy一个plugin的实现代码,命名为my_plugin.dart:

import 'package:analyzer/file_system/file_system.dart'; 
import 'package:analyzer/src/dart/analysis/driver.dart'; 
import 'package:analyzer_plugin/plugin/plugin.dart'; 
import 'package:analyzer_plugin/protocol/protocol_generated.dart';  

class MyPlugin extends ServerPlugin {   
    MyPlugin(ResourceProvider provider) : super(provider);    
    @override   
    List<String> get fileGlobsToAnalyze => <String>['**/*.dart']; 
    
    @override   
    String get name => 'My analyzer plugin';    
    
    @override   
    String get version => '1.0.0';    
    
    @override   
    AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot) {     
        // TODO: implement createAnalysisDriver     
        return null;   
    }
}

然后就是从入口函数中启动这个MyPlugin插件:

import 'dart:isolate';   
import 'package:analyzer/file_system/physical_file_system.dart'; 
import 'package:analyzer_plugin/starter.dart'; 
import 'package:pluginImpl/src/my_plugin.dart';  

void main(List<String> args, SendPort sendPort) {   
    ServerPluginStarter(MyPlugin(PhysicalResourceProvider.INSTANCE)).start(sendPort); 
}

此时,会发现my_plugin.dart中报错,因为createAnalysisDriver方法需要一个返回值。这里先直接填充一下:

  @override   
  AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot) {        
      final rootPath = contextRoot.root;     
      final locator = ContextLocator(resourceProvider: resourceProvider).locateRoots(includedPaths: [rootPath],excludedPaths: contextRoot.exclude,optionsFile: contextRoot.optionsFile,);
      final builder = ContextBuilder(resourceProvider: resourceProvider);     
      final context = builder.createContext(contextRoot: locator.first) as DriverBasedAnalysisContext;     
      final dartDriver = context.driver;       
      return dartDriver;   
  }

注意导包问题,DriverBasedAnalysisContext可能需要手动导入

import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';

至此为止,一个基础的Analyzer Plugin项目就完成了,下面我们来实验一下这个Plugin的运行。

测试MyPlugin

要如何测试这个MyPlugin是否能够正常运行?这个只能新创建一个项目来引入这个Plugin进行测试,这里要注意,一定要新建一个独立的项目,而不是在原先Plugin项目外面包一个项目。

创建完项目后,在pubspec.yaml中引入这个插件:

name: plugin_test 
description: A Project for testing my_plugin 
version: 0.0.1 
publish_to: none 
environment:   
    sdk: ">=2.14.0 <3.0.0"   
dependencies:  
dev_dependencies:   
    my_plugin:     
        path: ../analyzer_plugin #因为是本地测试,所以使用本地路径

然后在根目录下创建analysis_options.yaml,在里面启用插件:

analyzer:   
    plugins:     
        - my_plugin

这样这个项目,就能够启用MyPlugin了。如何验证呢?只需要启动Analysis Server Diagnostics里面查看即可。

Android Studio如何启动Analysis Server Diagnostics: image.png

VsCode如何启动(命令面板中直接搜索即可): image.png

打开后,直奔Plugins界面,就能看到如下页面:

image.png 说明my_plugin启动成功。