首页 > 编程知识 正文

vscode自定义代码颜色(自定义标签怎么设置)

时间:2023-05-05 03:02:20 阅读:64958 作者:3057

使用TSLint定制你的代码Rule TSLint可以规范你的代码,可以与vs代码的TSLint插件合作,治疗你的代码洁癖。

为了统一公司内部的代码样式,最近公司也开发了一些Rule,与Prettier合作还不是很美吗? 我负责这个Rule的开发。 TSlint国内资料很少,而且TSlint自己的文档对自定义Rule的开发也很模糊,不可避免地要查找资料和查看源代码。 当dqdppx可以编写第一个Rule时,后续的开发会变得更加顺利。 现在还在开发中,腾出时间写博客,定制Rule也帮助想写的同志们,不要绕道而行吧。 如果你感兴趣,你也可以转到我们正在开发的MagicSpace。 虽然还在开发中,但是试着做一下Star吧。 )

从官方的例子进入正题。

公式的例子也很清楚,先看看公式的例子吧

import * as ts from 'typescript '; 导入* as lint from ' tsl int '; exportclassruleextendslint.rules.abstract rule { public static failure _ string=' importstatementforbidden '; 公共应用(source file : ts.source file ) : lint.rule failure [ ] { return this.applywithwalker } newnoimportswalker thewalkertakescareofallthework.classnoimportswalkerextendslint.rule walker { publicvisitimportdeclaration (node 3360 ts.iiiion ) createafailureatthecurrentpositionthis.add failure (this.create failure (node.getstart ),node.getWidth ),//caltth 假设您要写名为noImportRule.ts的Rule。 在此文件中,需要一个名为Rule的类,显示当前应用的sourceFile参数继承Rules.AbstractRule,并实现它的apply方法。返回值为RuleFailure。 在TSLint中,与Rule不匹配的被视为故障。 此返回值是Failure数组。 当然,不是直接返回,而是返回Walker。

Walker是Rule的中心部分,是判断哪里不符合规定、应该在哪里放入failure等工作。 声明NoImportsWalker。 这里写着要继承RuleWalker。 RuleWalker相当于访问者,通过它可以访问所需的语句。 例如,visitImportDeclaration是访问其源文件的所有import声明语句。 参数node得到的是import表达式,node表示AST的节点。 (在TSLint中,在检查规则之前,首先将源代码转换为AST,然后通过多种方法提取AST的节点。 TSLint使用一种叫做TSUtil的工具。 在TSLint如此燃烧的同时,似乎只有几十个TSUtil,没有点燃TSLint呢。 大家可能对如何提取AST中的节点不感兴趣。 感兴趣的还是TSLint吧)。 然后,一旦得到此节点,就可以执行此节点上的方法。 例如,使用getText (获取它,或者使用getChildren,getParent获取它。

代码中的this.add failure (this.create failure (node.getstart (,node.getWidth ),Rule.FAILURE_STRING ) ); 就是调用addFailure添加错误。

此rule的功能是禁止和执行import语句以查看效果吗?

例如,我在这里随便引入模块

import * asfoofrom './foo '~~~~~~~~~~此语句已在tslidden中可见

沃克和Function写了简单的Rule

。这样看是不是很简单?

其实一般在做自定义 Rule 的时候,我们一般不会直接继承 RuleWalker, 而是会继承 AbstractWalker,然后实现它的 walk 方法,比如下面是我MagicSpace里的一个代码片段

class ExplicitReturnTypeWalker extends AbstractWalker<undefined> { /** 装载 */ walk(sourceFile: TypeScript.SourceFile): void { let cb = (node: TypeScript.Node): void => { if ( (TypeScript.isFunctionDeclaration(node) || TypeScript.isArrowFunction(node) || TypeScript.isFunctionExpression(node) || TypeScript.isMethodDeclaration(node)) && node.type ) { } TypeScript.forEachChild(node, cb); }; TypeScript.forEachChild(sourceFile, cb); }}

这个 walker是用来获取到一些我想要的函数节点,比如函数表达式,箭头函数,函数声明语句,方法声明。TSLint 作规则检查的时候就会调用walk,因此,你可以kqdl写一些判断逻辑,以达成你的规则判定要求。

除此之外,如果你的 rule 比较简单, 你大可不必去创建一个walker类,而是可以直接用applyWithFunction,功能上和walker差不多,只是用一个函数来替代walker。

protected applyWithFunction(sourceFile: ts.SourceFile, walkFn: (ctx: WalkContext<void>) => void): RuleFailure[]; protected applyWithFunction<T>(sourceFile: ts.SourceFile, walkFn: (ctx: WalkContext<T>) => void, options: NoInfer<T>): RuleFailure[]; protected applyWithFunction<T, U>(sourceFile: ts.SourceFile, walkFn: (ctx: WalkContext<T>, programOrChecker: U) => void, options: NoInfer<T>, checker: NoInfer<U>): RuleFailure[];

比如

applyWithFunction(souceFile, ctx => { // some logic})

这个函数就相当于 Walker 里面的walk方法,在检查规则的时候也会去调用这个函数,ctx参数就相当于是Walker的上下文。如果要调用 addFailure 的话,不是通过this.addFailure去调用,而是通过ctx.addFailure去进行调用。

基本可以实现和walker一样的功能。

相对逻辑比较简单的 Rule, 用applyWithFunction 可能更加轻便。

Metadata

除此之外,我们还可以在Rule的类中写元数据,用于来描述这个 Rule。看一个我写的一个 Metadata

static metadata: IRuleMetadata = { ruleName: 'import-groups', description: 'Validate that module imports are grouped as expected.', optionsDescription: '', options: { properties: { groups: { items: { properties: { name: { type: 'string', }, test: { type: 'string', }, }, type: 'object', }, type: 'array', }, ordered: { type: 'boolean', }, }, type: 'object', }, optionExamples: [ [ true, { groups: [ {name: 'node-core', test: '$node-core'}, {name: 'node-modules', test: '$node-modules'}, ], ordered: true, }, ], ], type: 'maintainability', hasFix: true, typescriptOnly: false, };

这里的字段的意思还是大家下来看看文档,这里就不再赘述了,有很多字段是可选的,看自己的情况需要来选。具体的可以看rule.d.ts中的IMetadata接口

查找对应的表达式

有的时候,我们需要查找对应的表达式,比如我们想收集整个文件里的 import 声明语句,可以用 kind 来作判断。kind 是什么?

Node.kind 是一个表示这个节点语义类型的整数,枚举类 ts.SyntaxKind 有完整的对应关系。

Oh,我们来看一个实际的例子。

import * as TypeScript form 'typescript'for (let statement of sourceFile.statements) { if (statement.kind === Typescript.SyntaxKind.ImportDeclaration) { //... }

这里可以通过对比每个 statement 的 kind 来获取所有的 import 的声明语句,不过在 tsutil 里封装了一些可以直接调用的方法,比如isImportDeclaration

那么上面的代码就可以改成

import * as TypeScript form 'typescript'for (let statement of sourceFile.statements) { if (isImportDeclaration(statement)) { //... }

还有 findImports方法可以帮助我们快速的找到所有的 import 语句

for (const expression of findImports( sourceFile, ImportKind.AllStaticImports, )) { //... }

是不是方便很多,当然,不止 import

总结

TSLint 当然是 TS 必备的一个风格检查的工具, 但是 TSLint 自带的一些规则肯定不能满足我们的有些奇怪的要求,那么可能就需要自己写一个 TSLint Rule,帮助我们在风格层面来规范代码。暂时只想到要写这些,国内的 TSLint 资料太少了,这个博文只是帮助大家找到一点思路, 当然,还是得结合文档和源码来构建自己的 TSLint 规则。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。