mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
feat(unstable): support comments in lint plugin (#29189)
This PR adds support for comments in the AST for lint plugins. - The `Program` node has a `comments` field pointing to an array of all comments. - `SourceCode.getAllComments()`: Returns all comments (same as `program.comments`) - `SourceCode.getCommentsBefore(node)`: Get all comments before this Node - `SourceCode.getCommentsAfter(node)`: Get all comments after this Node - `SourceCode.getCommentsInside(node)`: Get all comments inside this Node ESLint docs: - https://eslint.org/docs/latest/extend/custom-rules#accessing-the-source-code - https://eslint.org/docs/latest/extend/custom-rules#accessing-comments
This commit is contained in:
parent
e1e67a703c
commit
c015b8affd
11 changed files with 352 additions and 7 deletions
|
@ -263,6 +263,79 @@ export class SourceCode {
|
||||||
return ancestors;
|
return ancestors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Array<Deno.lint.LineComment | Deno.lint.BlockComment>}
|
||||||
|
*/
|
||||||
|
getAllComments() {
|
||||||
|
materializeComments(this.#ctx);
|
||||||
|
return this.#ctx.comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Deno.lint.Node} node
|
||||||
|
* @returns {Array<Deno.lint.LineComment | Deno.lint.BlockComment>}
|
||||||
|
*/
|
||||||
|
getCommentsBefore(node) {
|
||||||
|
materializeComments(this.#ctx);
|
||||||
|
|
||||||
|
/** @type {Array<Deno.lint.LineComment | Deno.lint.BlockComment>} */
|
||||||
|
const before = [];
|
||||||
|
|
||||||
|
const { comments } = this.#ctx;
|
||||||
|
for (let i = 0; i < comments.length; i++) {
|
||||||
|
const comment = comments[i];
|
||||||
|
if (comment.range[0] <= node.range[0]) {
|
||||||
|
before.push(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return before;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Deno.lint.Node} node
|
||||||
|
* @returns {Array<Deno.lint.LineComment | Deno.lint.BlockComment>}
|
||||||
|
*/
|
||||||
|
getCommentsAfter(node) {
|
||||||
|
materializeComments(this.#ctx);
|
||||||
|
|
||||||
|
/** @type {Array<Deno.lint.LineComment | Deno.lint.BlockComment>} */
|
||||||
|
const after = [];
|
||||||
|
|
||||||
|
const { comments } = this.#ctx;
|
||||||
|
for (let i = 0; i < comments.length; i++) {
|
||||||
|
const comment = comments[i];
|
||||||
|
if (comment.range[0] >= node.range[1]) {
|
||||||
|
after.push(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return after;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Deno.lint.Node} node
|
||||||
|
* @returns {Array<Deno.lint.LineComment | Deno.lint.BlockComment>}
|
||||||
|
*/
|
||||||
|
getCommentsInside(node) {
|
||||||
|
materializeComments(this.#ctx);
|
||||||
|
|
||||||
|
/** @type {Array<Deno.lint.LineComment | Deno.lint.BlockComment>} */
|
||||||
|
const inside = [];
|
||||||
|
|
||||||
|
const { comments } = this.#ctx;
|
||||||
|
for (let i = 0; i < comments.length; i++) {
|
||||||
|
const comment = comments[i];
|
||||||
|
if (
|
||||||
|
comment.range[0] >= node.range[0] && comment.range[1] <= node.range[1]
|
||||||
|
) {
|
||||||
|
inside.push(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inside;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
|
@ -345,6 +418,34 @@ export class Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {AstContext} ctx
|
||||||
|
*/
|
||||||
|
function materializeComments(ctx) {
|
||||||
|
const { buf, commentsOffset, comments, strTable } = ctx;
|
||||||
|
|
||||||
|
let offset = commentsOffset;
|
||||||
|
const count = readU32(buf, offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (comments.length === count) return;
|
||||||
|
|
||||||
|
while (offset < buf.length && comments.length < count) {
|
||||||
|
const kind = buf[offset];
|
||||||
|
offset++;
|
||||||
|
const spanId = readU32(buf, offset);
|
||||||
|
offset += 4;
|
||||||
|
const strId = readU32(buf, offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
comments.push({
|
||||||
|
type: kind === 0 ? "Line" : "Block",
|
||||||
|
range: readSpan(ctx, spanId),
|
||||||
|
value: getString(strTable, strId),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Deno.lint.Plugin[]} plugins
|
* @param {Deno.lint.Plugin[]} plugins
|
||||||
* @param {string[]} exclude
|
* @param {string[]} exclude
|
||||||
|
@ -489,6 +590,7 @@ class FacadeNode {
|
||||||
|
|
||||||
/** @type {Set<number>} */
|
/** @type {Set<number>} */
|
||||||
const appliedGetters = new Set();
|
const appliedGetters = new Set();
|
||||||
|
let hasCommenstGetter = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add getters for all potential properties found in the message.
|
* Add getters for all potential properties found in the message.
|
||||||
|
@ -515,6 +617,16 @@ function setNodeGetters(ctx) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasCommenstGetter) {
|
||||||
|
hasCommenstGetter = true;
|
||||||
|
Object.defineProperty(FacadeNode.prototype, "comments", {
|
||||||
|
get() {
|
||||||
|
materializeComments(ctx);
|
||||||
|
return ctx.comments;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -994,6 +1106,7 @@ function createAstContext(buf, token) {
|
||||||
|
|
||||||
// The buffer has a few offsets at the end which allows us to easily
|
// The buffer has a few offsets at the end which allows us to easily
|
||||||
// jump to the relevant sections of the message.
|
// jump to the relevant sections of the message.
|
||||||
|
const commentsOffset = readU32(buf, buf.length - 28);
|
||||||
const propsOffset = readU32(buf, buf.length - 24);
|
const propsOffset = readU32(buf, buf.length - 24);
|
||||||
const spansOffset = readU32(buf, buf.length - 20);
|
const spansOffset = readU32(buf, buf.length - 20);
|
||||||
const typeMapOffset = readU32(buf, buf.length - 16);
|
const typeMapOffset = readU32(buf, buf.length - 16);
|
||||||
|
@ -1060,7 +1173,9 @@ function createAstContext(buf, token) {
|
||||||
rootOffset,
|
rootOffset,
|
||||||
spansOffset,
|
spansOffset,
|
||||||
propsOffset,
|
propsOffset,
|
||||||
|
commentsOffset,
|
||||||
nodes: new Map(),
|
nodes: new Map(),
|
||||||
|
comments: [],
|
||||||
strTableOffset,
|
strTableOffset,
|
||||||
strByProp,
|
strByProp,
|
||||||
strByType,
|
strByType,
|
||||||
|
|
2
cli/js/40_lint_types.d.ts
vendored
2
cli/js/40_lint_types.d.ts
vendored
|
@ -8,6 +8,8 @@ export interface AstContext {
|
||||||
nodes: Map<number, Deno.lint.Node>;
|
nodes: Map<number, Deno.lint.Node>;
|
||||||
spansOffset: number;
|
spansOffset: number;
|
||||||
propsOffset: number;
|
propsOffset: number;
|
||||||
|
commentsOffset: number;
|
||||||
|
comments: Array<Deno.lint.LineComment | Deno.lint.BlockComment>;
|
||||||
strByType: number[];
|
strByType: number[];
|
||||||
strByProp: number[];
|
strByProp: number[];
|
||||||
typeByStr: Map<string, number>;
|
typeByStr: Map<string, number>;
|
||||||
|
|
|
@ -142,6 +142,19 @@ struct Node {
|
||||||
parent: u32,
|
parent: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CommentKind {
|
||||||
|
Line,
|
||||||
|
Block,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Comment {
|
||||||
|
kind: CommentKind,
|
||||||
|
str_id: usize,
|
||||||
|
span_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SerializeCtx {
|
pub struct SerializeCtx {
|
||||||
root_idx: Index,
|
root_idx: Index,
|
||||||
|
@ -161,6 +174,9 @@ pub struct SerializeCtx {
|
||||||
kind_name_map: Vec<usize>,
|
kind_name_map: Vec<usize>,
|
||||||
/// Maps prop id to string id
|
/// Maps prop id to string id
|
||||||
prop_name_map: Vec<usize>,
|
prop_name_map: Vec<usize>,
|
||||||
|
|
||||||
|
/// Comments
|
||||||
|
comments: Vec<Comment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the internal context used to allocate and fill the buffer. The point
|
/// This is the internal context used to allocate and fill the buffer. The point
|
||||||
|
@ -185,6 +201,7 @@ impl SerializeCtx {
|
||||||
str_table: StringTable::new(),
|
str_table: StringTable::new(),
|
||||||
kind_name_map: vec![0; kind_size],
|
kind_name_map: vec![0; kind_size],
|
||||||
prop_name_map: vec![0; prop_size],
|
prop_name_map: vec![0; prop_size],
|
||||||
|
comments: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let empty_str = ctx.str_table.insert("");
|
let empty_str = ctx.str_table.insert("");
|
||||||
|
@ -285,12 +302,7 @@ impl SerializeCtx {
|
||||||
where
|
where
|
||||||
K: Into<u8> + Display + Clone,
|
K: Into<u8> + Display + Clone,
|
||||||
{
|
{
|
||||||
let (start, end) = if *span == DUMMY_SP {
|
let (start, end) = span_to_value(span);
|
||||||
(0, 0)
|
|
||||||
} else {
|
|
||||||
// -1 is because swc stores spans 1-indexed
|
|
||||||
(span.lo.0 - 1, span.hi.0 - 1)
|
|
||||||
};
|
|
||||||
self.append_inner(kind, start, end)
|
self.append_inner(kind, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +571,21 @@ impl SerializeCtx {
|
||||||
self.write_ref_vec(prop, parent_ref, actual)
|
self.write_ref_vec(prop, parent_ref, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_comment(&mut self, kind: CommentKind, value: &str, span: &Span) {
|
||||||
|
let str_id = self.str_table.insert(value);
|
||||||
|
|
||||||
|
let span_id = self.spans.len() / 2;
|
||||||
|
let (span_lo, span_hi) = span_to_value(span);
|
||||||
|
self.spans.push(span_lo);
|
||||||
|
self.spans.push(span_hi);
|
||||||
|
|
||||||
|
self.comments.push(Comment {
|
||||||
|
kind,
|
||||||
|
str_id,
|
||||||
|
span_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize all information we have into a buffer that can be sent to JS.
|
/// Serialize all information we have into a buffer that can be sent to JS.
|
||||||
/// It has the following structure:
|
/// It has the following structure:
|
||||||
///
|
///
|
||||||
|
@ -629,10 +656,24 @@ impl SerializeCtx {
|
||||||
let offset_props = buf.len();
|
let offset_props = buf.len();
|
||||||
buf.append(&mut self.field_buf);
|
buf.append(&mut self.field_buf);
|
||||||
|
|
||||||
|
// Serialize comments
|
||||||
|
let offset_comments = buf.len();
|
||||||
|
append_usize(&mut buf, self.comments.len());
|
||||||
|
for comment in &self.comments {
|
||||||
|
let kind = match comment.kind {
|
||||||
|
CommentKind::Line => 0,
|
||||||
|
CommentKind::Block => 1,
|
||||||
|
};
|
||||||
|
buf.push(kind);
|
||||||
|
append_usize(&mut buf, comment.span_id);
|
||||||
|
append_usize(&mut buf, comment.str_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Putting offsets of relevant parts of the buffer at the end. This
|
// Putting offsets of relevant parts of the buffer at the end. This
|
||||||
// allows us to hop to the relevant part by merely looking at the last
|
// allows us to hop to the relevant part by merely looking at the last
|
||||||
// for values in the message. Each value represents an offset into the
|
// for values in the message. Each value represents an offset into the
|
||||||
// buffer.
|
// buffer.
|
||||||
|
append_usize(&mut buf, offset_comments);
|
||||||
append_usize(&mut buf, offset_props);
|
append_usize(&mut buf, offset_props);
|
||||||
append_usize(&mut buf, offset_spans);
|
append_usize(&mut buf, offset_spans);
|
||||||
append_usize(&mut buf, offset_kind_map);
|
append_usize(&mut buf, offset_kind_map);
|
||||||
|
@ -643,3 +684,12 @@ impl SerializeCtx {
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn span_to_value(span: &Span) -> (u32, u32) {
|
||||||
|
if *span == DUMMY_SP {
|
||||||
|
(0, 0)
|
||||||
|
} else {
|
||||||
|
// -1 is because swc stores spans 1-indexed
|
||||||
|
(span.lo.0 - 1, span.hi.0 - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ use deno_ast::view::VarDeclKind;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
|
|
||||||
use super::buffer::AstBufSerializer;
|
use super::buffer::AstBufSerializer;
|
||||||
|
use super::buffer::CommentKind;
|
||||||
use super::buffer::NodeRef;
|
use super::buffer::NodeRef;
|
||||||
use super::ts_estree::AstNode;
|
use super::ts_estree::AstNode;
|
||||||
use super::ts_estree::MethodKind as TsEstreeMethodKind;
|
use super::ts_estree::MethodKind as TsEstreeMethodKind;
|
||||||
|
@ -134,6 +135,14 @@ pub fn serialize_swc_to_buffer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for comment in parsed_source.comments().get_vec() {
|
||||||
|
let kind = match comment.kind {
|
||||||
|
deno_ast::swc::common::comments::CommentKind::Line => CommentKind::Line,
|
||||||
|
deno_ast::swc::common::comments::CommentKind::Block => CommentKind::Block,
|
||||||
|
};
|
||||||
|
ctx.write_comment(kind, &comment.text, &comment.span);
|
||||||
|
}
|
||||||
|
|
||||||
ctx.map_utf8_spans_to_utf16(utf16_map);
|
ctx.map_utf8_spans_to_utf16(utf16_map);
|
||||||
ctx.serialize()
|
ctx.serialize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use deno_ast::swc::common::Span;
|
||||||
use deno_ast::view::TruePlusMinus;
|
use deno_ast::view::TruePlusMinus;
|
||||||
|
|
||||||
use super::buffer::AstBufSerializer;
|
use super::buffer::AstBufSerializer;
|
||||||
|
use super::buffer::CommentKind;
|
||||||
use super::buffer::NodeRef;
|
use super::buffer::NodeRef;
|
||||||
use super::buffer::SerializeCtx;
|
use super::buffer::SerializeCtx;
|
||||||
use crate::util::text_encoding::Utf16Map;
|
use crate::util::text_encoding::Utf16Map;
|
||||||
|
@ -2890,6 +2891,10 @@ impl TsEsTreeBuilder {
|
||||||
_ => self.ctx.write_undefined(prop),
|
_ => self.ctx.write_undefined(prop),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_comment(&mut self, kind: CommentKind, value: &str, span: &Span) {
|
||||||
|
self.ctx.write_comment(kind, value, span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
48
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
48
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -1406,6 +1406,27 @@ declare namespace Deno {
|
||||||
* current node.
|
* current node.
|
||||||
*/
|
*/
|
||||||
getAncestors(node: Node): Node[];
|
getAncestors(node: Node): Node[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all comments inside the source.
|
||||||
|
*/
|
||||||
|
getAllComments(): Array<LineComment | BlockComment>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get leading comments before a node.
|
||||||
|
*/
|
||||||
|
getCommentsBefore(node: Node): Array<LineComment | BlockComment>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get trailing comments after a node.
|
||||||
|
*/
|
||||||
|
getCommentsAfter(node: Node): Array<LineComment | BlockComment>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get comments inside a node.
|
||||||
|
*/
|
||||||
|
getCommentsInside(node: Node): Array<LineComment | BlockComment>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full source code.
|
* Get the full source code.
|
||||||
*/
|
*/
|
||||||
|
@ -1532,6 +1553,7 @@ declare namespace Deno {
|
||||||
range: Range;
|
range: Range;
|
||||||
sourceType: "module" | "script";
|
sourceType: "module" | "script";
|
||||||
body: Statement[];
|
body: Statement[];
|
||||||
|
comments: Array<LineComment | BlockComment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4335,6 +4357,28 @@ declare namespace Deno {
|
||||||
| TSUnknownKeyword
|
| TSUnknownKeyword
|
||||||
| TSVoidKeyword;
|
| TSVoidKeyword;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single line comment
|
||||||
|
* @category Linter
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export interface LineComment {
|
||||||
|
type: "Line";
|
||||||
|
range: Range;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A potentially multi-line block comment
|
||||||
|
* @category Linter
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export interface BlockComment {
|
||||||
|
type: "Block";
|
||||||
|
range: Range;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Union type of all possible AST nodes
|
* Union type of all possible AST nodes
|
||||||
* @category Linter
|
* @category Linter
|
||||||
|
@ -4394,7 +4438,9 @@ declare namespace Deno {
|
||||||
| TSIndexSignature
|
| TSIndexSignature
|
||||||
| TSTypeAnnotation
|
| TSTypeAnnotation
|
||||||
| TSTypeParameterDeclaration
|
| TSTypeParameterDeclaration
|
||||||
| TSTypeParameter;
|
| TSTypeParameter
|
||||||
|
| LineComment
|
||||||
|
| BlockComment;
|
||||||
|
|
||||||
export {}; // only export exports
|
export {}; // only export exports
|
||||||
}
|
}
|
||||||
|
|
6
tests/specs/lint/lint_plugin_comments/__test__.jsonc
Normal file
6
tests/specs/lint/lint_plugin_comments/__test__.jsonc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"args": "lint main.ts",
|
||||||
|
"output": "comments.out",
|
||||||
|
"exitCode": 0
|
||||||
|
}
|
67
tests/specs/lint/lint_plugin_comments/comments.out
Normal file
67
tests/specs/lint/lint_plugin_comments/comments.out
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
program: [
|
||||||
|
{ type: "Line", range: [ 0, 14 ], value: " before line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 15, 38 ],
|
||||||
|
value: "*\n * before block\n "
|
||||||
|
},
|
||||||
|
{ type: "Line", range: [ 58, 72 ], value: " inside line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 75, 102 ],
|
||||||
|
value: "*\n * inside block\n "
|
||||||
|
},
|
||||||
|
{ type: "Line", range: [ 106, 119 ], value: " after line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 120, 142 ],
|
||||||
|
value: "*\n * after block\n "
|
||||||
|
}
|
||||||
|
],
|
||||||
|
all: [
|
||||||
|
{ type: "Line", range: [ 0, 14 ], value: " before line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 15, 38 ],
|
||||||
|
value: "*\n * before block\n "
|
||||||
|
},
|
||||||
|
{ type: "Line", range: [ 58, 72 ], value: " inside line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 75, 102 ],
|
||||||
|
value: "*\n * inside block\n "
|
||||||
|
},
|
||||||
|
{ type: "Line", range: [ 106, 119 ], value: " after line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 120, 142 ],
|
||||||
|
value: "*\n * after block\n "
|
||||||
|
}
|
||||||
|
],
|
||||||
|
before: [
|
||||||
|
{ type: "Line", range: [ 0, 14 ], value: " before line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 15, 38 ],
|
||||||
|
value: "*\n * before block\n "
|
||||||
|
}
|
||||||
|
],
|
||||||
|
after: [
|
||||||
|
{ type: "Line", range: [ 106, 119 ], value: " after line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 120, 142 ],
|
||||||
|
value: "*\n * after block\n "
|
||||||
|
}
|
||||||
|
],
|
||||||
|
inside: [
|
||||||
|
{ type: "Line", range: [ 58, 72 ], value: " inside line" },
|
||||||
|
{
|
||||||
|
type: "Block",
|
||||||
|
range: [ 75, 102 ],
|
||||||
|
value: "*\n * inside block\n "
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Checked 1 file
|
5
tests/specs/lint/lint_plugin_comments/deno.json
Normal file
5
tests/specs/lint/lint_plugin_comments/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"lint": {
|
||||||
|
"plugins": ["./plugin.ts"]
|
||||||
|
}
|
||||||
|
}
|
17
tests/specs/lint/lint_plugin_comments/main.ts
Normal file
17
tests/specs/lint/lint_plugin_comments/main.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// before line
|
||||||
|
/**
|
||||||
|
* before block
|
||||||
|
*/
|
||||||
|
function foo() {
|
||||||
|
// inside line
|
||||||
|
/**
|
||||||
|
* inside block
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// after line
|
||||||
|
/**
|
||||||
|
* after block
|
||||||
|
*/
|
||||||
|
|
||||||
|
foo();
|
23
tests/specs/lint/lint_plugin_comments/plugin.ts
Normal file
23
tests/specs/lint/lint_plugin_comments/plugin.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export default {
|
||||||
|
name: "foo",
|
||||||
|
rules: {
|
||||||
|
foo: {
|
||||||
|
create(ctx) {
|
||||||
|
let program: Array<Deno.lint.LineComment | Deno.lint.BlockComment> = [];
|
||||||
|
return {
|
||||||
|
Program(node) {
|
||||||
|
program = node.comments;
|
||||||
|
},
|
||||||
|
FunctionDeclaration(node) {
|
||||||
|
const all = ctx.sourceCode.getAllComments();
|
||||||
|
const before = ctx.sourceCode.getCommentsBefore(node);
|
||||||
|
const after = ctx.sourceCode.getCommentsAfter(node);
|
||||||
|
const inside = ctx.sourceCode.getCommentsInside(node);
|
||||||
|
|
||||||
|
console.log({ program, all, before, after, inside });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} satisfies Deno.lint.Plugin;
|
Loading…
Add table
Add a link
Reference in a new issue