-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(@rsbuild/doctor): rsbuild doctor add rule-utils package (#220)
Co-authored-by: easy1090 <[email protected]>
- Loading branch information
Showing
17 changed files
with
821 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@rsbuild/doctor-utils': patch | ||
'@rsbuild/doctor-sdk': patch | ||
--- | ||
|
||
feat: rsbuild doctor add rule-utils package |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './build'; | ||
export * from './common'; | ||
export * as RuleUtils from './rule-utils'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { LinesAndColumns } from 'lines-and-columns'; | ||
import { isUndefined, isNumber } from 'lodash'; | ||
import { Range, OffsetRange, Position, DocumentEditData } from './types'; | ||
|
||
/** Document Catalogue */ | ||
export class Document { | ||
/** Actual document content. */ | ||
private _text = ''; | ||
|
||
/** Get the displacement of the file position in the text. */ | ||
positionAt!: (offset: number) => Position | undefined; | ||
|
||
/** Get the position of the displacement point in the file. */ | ||
offsetAt!: (position: Position) => number | undefined; | ||
|
||
constructor(content: string) { | ||
this._text; | ||
this._text = content; | ||
this.createFinder(); | ||
} | ||
|
||
/** Generate location search */ | ||
private createFinder() { | ||
const find = new LinesAndColumns(this._text); | ||
|
||
this.positionAt = (offset) => { | ||
if (offset >= this._text.length) { | ||
offset = this._text.length - 1; | ||
} | ||
|
||
if (offset < 0) { | ||
offset = 0; | ||
} | ||
|
||
const result = find.locationForIndex(offset); | ||
|
||
if (!result) { | ||
return; | ||
} | ||
|
||
return { | ||
line: result.line + 1, | ||
column: result.column, | ||
}; | ||
}; | ||
|
||
this.offsetAt = (position) => { | ||
return ( | ||
find.indexForLocation({ | ||
line: position.line - 1, | ||
column: position.column, | ||
}) ?? undefined | ||
); | ||
}; | ||
} | ||
|
||
getText(range?: Range | OffsetRange) { | ||
if (!range) { | ||
return this._text; | ||
} | ||
|
||
const start = | ||
typeof range.start === 'number' | ||
? range.start | ||
: this.offsetAt(range.start); | ||
const end = | ||
typeof range.end === 'number' ? range.end : this.offsetAt(range.end); | ||
|
||
if (isUndefined(start)) { | ||
throw new Error(`Location ${JSON.stringify(start)} is illegal`); | ||
} | ||
|
||
if (isUndefined(end)) { | ||
throw new Error(`Location ${JSON.stringify(end)} is illegal`); | ||
} | ||
|
||
return this._text.slice(start, end); | ||
} | ||
|
||
/** Edit document data */ | ||
edit(data: DocumentEditData) { | ||
let { _text: content } = this; | ||
const startOffset = isNumber(data.start) | ||
? data.start | ||
: this.offsetAt(data.start); | ||
const endOffset = isNumber(data.end) ? data.end : this.offsetAt(data.end); | ||
|
||
if (isUndefined(startOffset) || isUndefined(endOffset)) { | ||
return; | ||
} | ||
|
||
const startTxt = content.substring(0, startOffset); | ||
const endTxt = content.substring(endOffset, content.length); | ||
|
||
content = startTxt + data.newText + endTxt; | ||
|
||
return content; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './document'; | ||
export * from './types'; | ||
export * from './server'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Document } from './document'; | ||
|
||
const store = new Map<string, Document>(); | ||
|
||
/** Create Document */ | ||
export function getDocument(content: string) { | ||
if (store.has(content)) { | ||
return store.get(content)!; | ||
} | ||
|
||
const doc = new Document(content); | ||
store.set(content, doc); | ||
return doc; | ||
} | ||
|
||
export function clearDocument() { | ||
store.clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Location | ||
* - line starting point is 1 | ||
* - column starting point is 0 | ||
*/ | ||
export interface Position { | ||
line: number; | ||
column: number; | ||
} | ||
|
||
/** Location range */ | ||
export interface Range { | ||
start: Position; | ||
end: Position; | ||
} | ||
|
||
/** Offset range */ | ||
export interface OffsetRange { | ||
start: number; | ||
end: number; | ||
} | ||
|
||
/** Text repair data */ | ||
export interface DocumentEditData { | ||
/** Modify the starting position of string in the original text */ | ||
start: number | Position; | ||
/** Modify string in the key position of the original text */ | ||
end: number | Position; | ||
/** | ||
* Replaced new text | ||
* - If empty, delete the original text | ||
*/ | ||
newText?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './document'; | ||
export * from './parser'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { isObject } from 'lodash'; | ||
import { Node } from './types'; | ||
|
||
function isSyntaxNode(node: unknown): node is Node.SyntaxNode { | ||
return isObject(node) && 'type' in node; | ||
} | ||
|
||
function assertCreator<T>(type: string) { | ||
return (node: unknown): node is T => { | ||
return isSyntaxNode(node) && node.type === type; | ||
}; | ||
} | ||
|
||
export const asserts = { | ||
isProgram: assertCreator<Node.Program>('Program'), | ||
isEmptyStatement: assertCreator<Node.EmptyStatement>('EmptyStatement'), | ||
isBlockStatement: assertCreator<Node.BlockStatement>('BlockStatement'), | ||
isStaticBlock: assertCreator<Node.StaticBlock>('StaticBlock'), | ||
isExpressionStatement: assertCreator<Node.ExpressionStatement>( | ||
'ExpressionStatement', | ||
), | ||
isIfStatement: assertCreator<Node.IfStatement>('IfStatement'), | ||
isLabeledStatement: assertCreator<Node.LabeledStatement>('LabeledStatement'), | ||
isBreakStatement: assertCreator<Node.BreakStatement>('BreakStatement'), | ||
isContinueStatement: | ||
assertCreator<Node.ContinueStatement>('ContinueStatement'), | ||
isWithStatement: assertCreator<Node.WithStatement>('WithStatement'), | ||
isSwitchStatement: assertCreator<Node.SwitchStatement>('SwitchStatement'), | ||
isReturnStatement: assertCreator<Node.ReturnStatement>('ReturnStatement'), | ||
isThrowStatement: assertCreator<Node.ThrowStatement>('ThrowStatement'), | ||
isTryStatement: assertCreator<Node.TryStatement>('TryStatement'), | ||
isWhileStatement: assertCreator<Node.WhileStatement>('WhileStatement'), | ||
isDoWhileStatement: assertCreator<Node.DoWhileStatement>('DoWhileStatement'), | ||
isForStatement: assertCreator<Node.ForStatement>('ForStatement'), | ||
isForInStatement: assertCreator<Node.ForInStatement>('ForInStatement'), | ||
isForOfStatement: assertCreator<Node.ForOfStatement>('ForOfStatement'), | ||
isDebuggerStatement: | ||
assertCreator<Node.DebuggerStatement>('DebuggerStatement'), | ||
isFunctionDeclaration: assertCreator<Node.FunctionDeclaration>( | ||
'FunctionDeclaration', | ||
), | ||
isVariableDeclaration: assertCreator<Node.VariableDeclaration>( | ||
'VariableDeclaration', | ||
), | ||
isVariableDeclarator: | ||
assertCreator<Node.VariableDeclarator>('VariableDeclarator'), | ||
isChainExpression: assertCreator<Node.ChainExpression>('ChainExpression'), | ||
isThisExpression: assertCreator<Node.ThisExpression>('ThisExpression'), | ||
isArrayExpression: assertCreator<Node.ArrayExpression>('ArrayExpression'), | ||
isObjectExpression: assertCreator<Node.ObjectExpression>('ObjectExpression'), | ||
isPrivateIdentifier: | ||
assertCreator<Node.PrivateIdentifier>('PrivateIdentifier'), | ||
isProperty: assertCreator<Node.Property>('Property'), | ||
isPropertyDefinition: | ||
assertCreator<Node.PropertyDefinition>('PropertyDefinition'), | ||
isFunctionExpression: | ||
assertCreator<Node.FunctionExpression>('FunctionExpression'), | ||
isSequenceExpression: | ||
assertCreator<Node.SequenceExpression>('SequenceExpression'), | ||
isUnaryExpression: assertCreator<Node.UnaryExpression>('UnaryExpression'), | ||
isBinaryExpression: assertCreator<Node.BinaryExpression>('BinaryExpression'), | ||
isAssignmentExpression: assertCreator<Node.AssignmentExpression>( | ||
'AssignmentExpression', | ||
), | ||
isUpdateExpression: assertCreator<Node.UpdateExpression>('UpdateExpression'), | ||
isLogicalExpression: | ||
assertCreator<Node.LogicalExpression>('LogicalExpression'), | ||
isConditionalExpression: assertCreator<Node.ConditionalExpression>( | ||
'ConditionalExpression', | ||
), | ||
isNewExpression: assertCreator<Node.NewExpression>('NewExpression'), | ||
isSwitchCase: assertCreator<Node.SwitchCase>('SwitchCase'), | ||
isCatchClause: assertCreator<Node.CatchClause>('CatchClause'), | ||
isIdentifier: assertCreator<Node.Identifier>('Identifier'), | ||
isLiteral: assertCreator<Node.Literal>('Literal'), | ||
isSuper: assertCreator<Node.Super>('Super'), | ||
isSpreadElement: assertCreator<Node.SpreadElement>('SpreadElement'), | ||
isArrowFunctionExpression: assertCreator<Node.ArrowFunctionExpression>( | ||
'ArrowFunctionExpression', | ||
), | ||
isYieldExpression: assertCreator<Node.YieldExpression>('YieldExpression'), | ||
isTemplateLiteral: assertCreator<Node.TemplateLiteral>('TemplateLiteral'), | ||
isTaggedTemplateExpression: assertCreator<Node.TaggedTemplateExpression>( | ||
'TaggedTemplateExpression', | ||
), | ||
isTemplateElement: assertCreator<Node.TemplateElement>('TemplateElement'), | ||
isObjectPattern: assertCreator<Node.ObjectPattern>('ObjectPattern'), | ||
isArrayPattern: assertCreator<Node.ArrayPattern>('ArrayPattern'), | ||
isRestElement: assertCreator<Node.RestElement>('RestElement'), | ||
isAssignmentPattern: | ||
assertCreator<Node.AssignmentPattern>('AssignmentPattern'), | ||
isClassBody: assertCreator<Node.ClassBody>('ClassBody'), | ||
isClassDeclaration: assertCreator<Node.ClassDeclaration>('ClassDeclaration'), | ||
isClassExpression: assertCreator<Node.ClassExpression>('ClassExpression'), | ||
isMetaProperty: assertCreator<Node.MetaProperty>('MetaProperty'), | ||
isImportDeclaration: | ||
assertCreator<Node.ImportDeclaration>('ImportDeclaration'), | ||
isImportSpecifier: assertCreator<Node.ImportSpecifier>('ImportSpecifier'), | ||
isImportExpression: assertCreator<Node.ImportExpression>('ImportExpression'), | ||
isImportDefaultSpecifier: assertCreator<Node.ImportDefaultSpecifier>( | ||
'ImportDefaultSpecifier', | ||
), | ||
isImportNamespaceSpecifier: assertCreator<Node.ImportNamespaceSpecifier>( | ||
'ImportNamespaceSpecifier', | ||
), | ||
isExportNamedDeclaration: assertCreator<Node.ExportNamedDeclaration>( | ||
'ExportNamedDeclaration', | ||
), | ||
isExportSpecifier: assertCreator<Node.ExportSpecifier>('ExportSpecifier'), | ||
isExportDefaultDeclaration: assertCreator<Node.ExportDefaultDeclaration>( | ||
'ExportDefaultDeclaration', | ||
), | ||
isExportAllDeclaration: assertCreator<Node.ExportAllDeclaration>( | ||
'ExportAllDeclaration', | ||
), | ||
isAwaitExpression: assertCreator<Node.AwaitExpression>('AwaitExpression'), | ||
isMethodDefinition: assertCreator<Node.MethodDefinition>('MethodDefinition'), | ||
isMemberExpression: assertCreator<Node.MemberExpression>('MemberExpression'), | ||
|
||
isComment(node: unknown): node is Node.Comment { | ||
return ( | ||
isSyntaxNode(node) && (node.type === 'Line' || node.type === 'Block') | ||
); | ||
}, | ||
isDirective(node: unknown): node is Node.Directive { | ||
return asserts.isExpressionStatement(node) && 'directive' in node; | ||
}, | ||
isSimpleCallExpression(node: unknown): node is Node.SimpleCallExpression { | ||
return isSyntaxNode(node) && node.type === 'CallExpression'; | ||
}, | ||
isAssignmentProperty(node: unknown): node is Node.AssignmentProperty { | ||
return asserts.isProperty(node) && node.kind === 'init'; | ||
}, | ||
isSimpleLiteral(node: unknown): node is Node.SimpleLiteral { | ||
return ( | ||
asserts.isLiteral(node) && | ||
!asserts.isRegExpLiteral(node) && | ||
!asserts.isBigIntLiteral(node) | ||
); | ||
}, | ||
isRegExpLiteral(node: unknown): node is Node.RegExpLiteral { | ||
return asserts.isLiteral(node) && 'regex' in node; | ||
}, | ||
isBigIntLiteral(node: unknown): node is Node.BigIntLiteral { | ||
return asserts.isLiteral(node) && 'bigint' in node; | ||
}, | ||
isExportStatement(node: unknown): node is Node.ExportStatement { | ||
return ( | ||
asserts.isExportAllDeclaration(node) || | ||
asserts.isExportDefaultDeclaration(node) || | ||
asserts.isExportNamedDeclaration(node) | ||
); | ||
}, | ||
} as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './asserts'; | ||
export * from './parser'; | ||
export * from './utils'; | ||
export * from './types'; |
Oops, something went wrong.