Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.0.0 #14

Draft
wants to merge 54 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
142ebcb
Added setup for TypeScript-based ESLint rules.
bre1470 Nov 8, 2021
c8a29a0
Added pretty-length rule with doclet AST, fix mode not working.
bre1470 Nov 8, 2021
702994e
Migrated pretty-length to TypeScript AST.
bre1470 Nov 10, 2021
7aa38f8
Added TypeScript scanner and JSDoc extractor.
bre1470 Nov 11, 2021
b800155
Added source styling detection.
bre1470 Jan 21, 2022
ac50d41
Improved source doclet parsing.
bre1470 Apr 11, 2022
f9265d2
Added SourceTree with SourceNodes.
bre1470 Apr 11, 2022
bfcadc7
Added TypeScript debug rule.
bre1470 Apr 11, 2022
5c7d435
Added SourceParser.
bre1470 Apr 12, 2022
1da7da6
Added types extraction.
bre1470 Apr 13, 2022
361e115
Improved variable parsing.
bre1470 Apr 13, 2022
1e815e9
Added SourcePosition.
bre1470 Apr 20, 2022
1f9f155
Added generic-array-type rule with fix.
bre1470 Apr 21, 2022
2fe190e
Added SourceComment tokens.
bre1470 Apr 21, 2022
1dac366
Refactored positioning calculations.
bre1470 Apr 22, 2022
7383be4
Improved marker of pretty-length rule.
bre1470 Apr 22, 2022
2713cca
Added doc parsing.
bre1470 Apr 23, 2022
d7a7b1a
Improved detection of advanced tags.
bre1470 Apr 25, 2022
edafc32
Fixed double line ending.
bre1470 Apr 25, 2022
b6f7ccb
Removed line breaks from all logical line tokens.
bre1470 Apr 28, 2022
6fd6c7d
Fixed positioning of multiline comments.
bre1470 Apr 28, 2022
3c57b5e
Added line extraction.
bre1470 Apr 28, 2022
1e5c003
Added support for sublines.
bre1470 Apr 29, 2022
ecf89df
Added string pad function.
bre1470 Apr 29, 2022
c07039f
Optimized token scanning.
bre1470 Apr 29, 2022
bf6e875
Added some debug test code.
bre1470 May 2, 2022
cb3e4d2
Fixed SourceComment.
bre1470 May 2, 2022
0cee6f3
Improved tags parsing.
bre1470 May 2, 2022
446c5f5
Fixed tsconfig.json.
bre1470 May 2, 2022
59dfd61
Fixed indent function.
bre1470 May 2, 2022
f119e51
Fixed MD code blocks.
bre1470 May 2, 2022
9a189b5
Fixed doclet indent and line breaks.
bre1470 May 2, 2022
51377ac
Improved handling of LB in ML comments.
bre1470 May 2, 2022
13625b0
Fixed edge cases.
bre1470 May 3, 2022
c1fa4fe
Fixed tag decoration.
bre1470 May 4, 2022
a9f0dd3
Added reports stack with finalized fix.
bre1470 May 4, 2022
22a71a2
Improved handling of custom tags.
bre1470 May 5, 2022
a4f2a3b
Updated transpiled rules.
bre1470 May 5, 2022
26e13ae
Added SourceLine.getEssentialTokens.
bre1470 May 5, 2022
121b02b
Added kinds extractor to SourceLine.
bre1470 May 9, 2022
1792b28
Added source cache to RuleContext.
bre1470 May 9, 2022
016a228
Added no-import-modification rule.
bre1470 May 9, 2022
51fb7ef
Replaced source cache with global scanner.
bre1470 May 10, 2022
1a388c1
Optimized no-import-modification rule.
bre1470 May 12, 2022
9e44421
Migrated no-optional-chaining rule.
bre1470 May 12, 2022
5a41136
Added no-import-type rule.
bre1470 May 12, 2022
6ed49eb
Improved typing of rules.
bre1470 May 12, 2022
531eb65
Fixed calculation of column positions.
bre1470 May 12, 2022
c6110ff
Fixed handling of custom JSDoc tags.
bre1470 May 12, 2022
434d01d
Fixed token positions in line.
bre1470 May 12, 2022
f5f5e79
Limited reports to avoid range mismatch.
bre1470 May 12, 2022
22f9fe8
Fixed no-import-type fix.
bre1470 May 12, 2022
2f32e16
Fixed generic-array-type fix.
bre1470 May 12, 2022
5431917
Fixed handling of generic and union.
bre1470 May 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"func-style": 0,
"quotes": 0,
"max-len": [
"error",
"warn",
{
"code": 120,
"comments": 80,
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules
*.tsbuildinfo
lib/**/*.d.ts
node_modules/
107 changes: 107 additions & 0 deletions lib/RuleContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* @author Sophie Bremer
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.RuleContext = void 0;
const FS = require("fs");
const Path = require("path");
const SourceCode_1 = require("./SourceCode");
const SourceTree_1 = require("./SourceTree");
/* *
*
* Class
*
* */
class RuleContext {
/* *
*
* Constructor
*
* */
constructor(esLintContext, ruleOptionsDefault) {
this.cwd = esLintContext.getCwd();
this.esLintContext = esLintContext;
this.settings = ((esLintContext.settings || {}).highcharts || {});
this.options = Object.assign(Object.assign(Object.assign({}, ruleOptionsDefault), this.settings), (esLintContext.options[1] || {}));
this.preparedReports = [];
this.sourcePath = Path.relative(this.cwd, esLintContext.getFilename());
}
/* *
*
* Static Properties
*
* */
static setupRuleExport(ruleType, ruleOptionsSchema, ruleOptionsDefault, lintFunction, reportWithFix) {
return {
meta: {
fixable: reportWithFix ? 'code' : void 0,
schema: [{
additionalProperties: false,
properties: ruleOptionsSchema,
type: 'object'
}],
type: ruleType
},
create: (esLintRuleContext) => ({
Program: () => lintFunction(new RuleContext(esLintRuleContext, ruleOptionsDefault))
})
};
}
get sourceCode() {
if (!this._sourceCode) {
const sourcePath = this.sourcePath;
this._sourceCode = new SourceCode_1.default(sourcePath, FS.readFileSync(sourcePath).toString());
}
return this._sourceCode;
}
get sourceTree() {
if (!this._sourceTree) {
const sourcePath = this.sourcePath;
this._sourceTree = new SourceTree_1.default(sourcePath, FS.readFileSync(sourcePath).toString());
}
return this._sourceTree;
}
/* *
*
* Functions
*
* */
prepareReport(position, message) {
this.preparedReports.push({
loc: {
// ESLint needs column zero-based:
column: position.column - 1,
line: position.line
},
message
});
}
sendReports(finalFix) {
const esLintContext = this.esLintContext, reports = this.preparedReports.splice(0);
if (finalFix) {
for (let i = 0, iEnd = reports.length - 1, report; i <= iEnd; ++i) {
report = reports[i];
if (i === iEnd) {
report.fix = finalFix;
}
else {
report.fix = () => null;
}
esLintContext.report(report);
}
}
else {
for (const report of reports) {
esLintContext.report(report);
}
}
}
}
exports.RuleContext = RuleContext;
/* *
*
* Default Export
*
* */
exports.default = RuleContext;
133 changes: 133 additions & 0 deletions lib/SourceCode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* @author Sophie Bremer
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceCode = void 0;
const TS = require("typescript");
const U = require("./Utilities");
const SourceComment_1 = require("./SourceComment");
const SourceDoc_1 = require("./SourceDoc");
const SourceLine_1 = require("./SourceLine");
/* *
*
* Constant
*
* */
const tsScanner = TS.createScanner(TS.ScriptTarget.Latest, false);
/* *
*
* Class
*
* */
class SourceCode {
/* *
*
* Constructor
*
* */
constructor(fileName, sourceCode) {
this.fileName = fileName;
this.lineBreak = U.detectLineBreak(sourceCode) || '\n';
this.lines = [];
this.raw = sourceCode;
this.parse(sourceCode);
}
/* *
*
* Functions
*
* */
getLinePosition(line) {
const lines = this.lines, lineIndex = lines.indexOf(line), position = {
column: 1,
end: 0,
line: 1,
start: 0
};
if (lineIndex < 0) {
return null;
}
for (let i = 0, tokens, tokenLength, tokenText; i < lineIndex; ++i) {
tokens = lines[i].tokens;
for (const token of tokens) {
tokenText = token.text;
if (token.kind === TS.SyntaxKind.JSDocComment ||
token.kind === TS.SyntaxKind.MultiLineCommentTrivia) {
tokenLength = tokenText.split(U.LINE_BREAKS).length;
if (tokenLength > 1) {
position.line += tokenLength - 1;
}
}
position.start += tokenText.length;
}
position.line += 1;
position.start += 1; // line break
}
position.end = position.start + line.toString().length;
return position;
}
/**
* Returns the token position relative to the code.
*/
getTokenPosition(line, token) {
const linePosition = this.getLinePosition(line), tokenPosition = line.getTokenPosition(token);
if (!linePosition || !tokenPosition) {
return null;
}
return {
column: tokenPosition.column,
end: linePosition.start + tokenPosition.end,
line: linePosition.line + tokenPosition.line - 1,
start: linePosition.start + tokenPosition.start
};
}
parse(sourceCode, replace = false) {
const lineBreak = this.lineBreak, lines = this.lines;
if (replace) {
lines.length = 0;
}
if (!sourceCode) {
return;
}
let indent, kind, line = new SourceLine_1.default(lineBreak), text, token;
tsScanner.setText(sourceCode);
do {
kind = tsScanner.scan();
text = tsScanner.getTokenText();
if (kind === TS.SyntaxKind.NewLineTrivia ||
kind === TS.SyntaxKind.EndOfFileToken) {
lines.push(line);
line = new SourceLine_1.default(lineBreak);
continue;
}
if (kind === TS.SyntaxKind.MultiLineCommentTrivia) {
indent = Math.floor(line.getIndent() / 2) * 2;
if (SourceDoc_1.default.isSourceDoc(text)) {
token = new SourceDoc_1.default(text, lineBreak, indent);
}
else {
token = new SourceComment_1.default(text, lineBreak, indent);
}
}
else {
token = { kind, text };
}
line.tokens.push(token);
} while (kind !== TS.SyntaxKind.EndOfFileToken);
}
toString(maximalLength) {
const lines = this.lines, strings = [];
for (const line of lines) {
strings.push(line.toString(maximalLength));
}
return strings.join(this.lineBreak);
}
}
exports.SourceCode = SourceCode;
/* *
*
* Default Export
*
* */
exports.default = SourceCode;
114 changes: 114 additions & 0 deletions lib/SourceComment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* @author Sophie Bremer
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceComment = void 0;
/* *
*
* Imports
*
* */
const TS = require("typescript");
const U = require("./Utilities");
const SourceLine_1 = require("./SourceLine");
/* *
*
* Constants
*
* */
const starPattern = /^[ \t]+\*[ \t]?/u;
/* *
*
* Class
*
* */
class SourceComment extends SourceLine_1.default {
/* *
*
* Constructor
*
* */
constructor(text, lineBreak = '\n', indent = 0) {
super(lineBreak);
this.indent = indent;
this.kind = TS.SyntaxKind.MultiLineCommentTrivia;
const lines = text.split(U.LINE_BREAKS), tokens = this.tokens;
for (let i = 0, iEnd = lines.length; i < iEnd; ++i) {
tokens.push({
kind: TS.SyntaxKind.SingleLineCommentTrivia,
text: (i ? lines[i].substr(indent) : lines[i])
});
}
}
/* *
*
* Static Functions
*
* */
static extractCommentLines(text, indent = 0) {
let lines = text.split(U.LINE_BREAKS);
if (lines.length === 1) {
// remove /** and */
return [text.substr(4, text.length - 7)];
}
// remove /**\n and \n*/
lines = lines.slice(1, -1);
for (let i = 0, iEnd = lines.length, line; i < iEnd; ++i) {
line = lines[i];
if (line.match(starPattern)) {
// remove *
lines[i] = line.replace(starPattern, '');
}
else if (indent) {
// remove indent
lines[i] = line.substr(indent);
}
}
return lines;
}
get text() {
return this.toString();
}
/* *
*
* Functions
*
* */
getIndent() {
return this.indent;
}
toString(maximalLength) {
const indent = this.indent, lines = [];
if (maximalLength) {
let line = '', words;
for (const token of this.tokens) {
words = token.text.split(' ');
line = words.shift() || '';
for (const word of words) {
if (line.length + 1 + word.length > maximalLength) {
lines.push(line.trimRight());
line = U.pad(indent, word);
}
else {
line += ` ${word}`;
}
}
lines.push(line.trimRight());
}
}
else {
for (const token of this.tokens) {
lines.push(U.pad(indent, token.text));
}
}
return lines.join(this.lineBreak).substr(indent);
}
}
exports.SourceComment = SourceComment;
/* *
*
* Default Export
*
* */
exports.default = SourceComment;
Loading