Skip to content

Commit 3f3dc73

Browse files
authored
Merge pull request #190 from bafolts/eslint-plugin
Addition of eslint plugin
2 parents c7a417d + fc16343 commit 3f3dc73

File tree

12 files changed

+436
-159
lines changed

12 files changed

+436
-159
lines changed

common/config/rush/yarn.lock

Lines changed: 196 additions & 157 deletions
Large diffs are not rendered by default.

eslint-plugin/.eslintrc.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// This is a workaround for https://github.com/eslint/eslint/issues/3458
2+
require("@rushstack/eslint-config/patch-eslint6");
3+
4+
module.exports = {
5+
extends: [ "@rushstack/eslint-config" ],
6+
parserOptions: { tsconfigRootDir: __dirname },
7+
};

eslint-plugin/.npmignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Ignore everything by default
2+
**
3+
4+
# Use negative patterns to bring back the specific things we want to publish
5+
!/bin/**
6+
!/lib/**
7+
!/dist/**
8+
!ThirdPartyNotice.txt
9+
10+
# Ignore certain files in the above folder
11+
/dist/*.stats.*
12+
/lib/**/test/*
13+
/lib/**/__tests__/*
14+
15+
# NOTE: These don't need to be specified, because NPM includes them automatically.
16+
#
17+
# package.json
18+
# README (and its variants)
19+
# CHANGELOG (and its variants)
20+
# LICENSE / LICENCE
21+
22+
## Project specific definitions
23+
# -----------------------------
24+
25+
# (Add your exceptions here)

eslint-plugin/.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
registry=https://registry.npmjs.org/
2+
always-auth=false

eslint-plugin/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright (c) Microsoft Corporation. All rights reserved.
2+
3+
MIT License
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
"Software"), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

eslint-plugin/build.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const child_process = require('child_process');
4+
const path = require('path');
5+
6+
const production = process.argv.indexOf('--production') >= 0;
7+
const baseDir = __dirname;
8+
9+
process.chdir(baseDir);
10+
11+
process.exitCode = 1;
12+
try {
13+
child_process.execSync(path.join(baseDir, 'node_modules/.bin/rimraf')
14+
+ ' ./lib/', { stdio: 'inherit' });
15+
16+
console.log('-- TYPESCRIPT --\n');
17+
child_process.execSync(path.join(baseDir, 'node_modules/.bin/tsc'), { stdio: 'inherit' });
18+
19+
console.log('-- ESLINT --\n');
20+
child_process.execSync(path.join(baseDir, 'node_modules/.bin/eslint')
21+
+ ' -f unix \"src/**/*.{ts,tsx}\"',
22+
{ stdio: 'inherit' });
23+
24+
if (production) {
25+
console.log('-- TEST --\n');
26+
27+
require('./lib/tests/index.js');
28+
}
29+
30+
process.exitCode = 0;
31+
} catch (e) {
32+
console.log('ERROR: ' + e.message);
33+
}

eslint-plugin/package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "eslint-plugin-tsdoc",
3+
"version": "0.1.0",
4+
"description": "eslint plugin for tsdoc",
5+
"private": false,
6+
"license": "MIT",
7+
"scripts": {
8+
"build": "node ./build.js",
9+
"lint": "eslint -f unix \"src/**/*.{ts,tsx}\"",
10+
"test": "node lib/tests/index.js"
11+
},
12+
"dependencies": {
13+
"@microsoft/tsdoc": "0.12.14"
14+
},
15+
"devDependencies": {
16+
"@rushstack/eslint-config": "0.4.0",
17+
"@types/eslint": "6.1.3",
18+
"@types/node": "10.7.1",
19+
"eslint": "^6.0.0",
20+
"typescript": "~3.5.3"
21+
}
22+
}

eslint-plugin/src/index.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
import { ParserMessageLog, TSDocParser } from "@microsoft/tsdoc";
3+
import { allTsdocMessageIds } from "@microsoft/tsdoc/lib/parser/TSDocMessageId";
4+
import * as eslint from "eslint";
5+
import * as ESTree from "estree";
6+
7+
const messageIds: {[x: string]: string} = {};
8+
9+
allTsdocMessageIds.forEach((messageId: string) => {
10+
messageIds[messageId] = `${messageId}: {{ unformattedText }}`;
11+
});
12+
13+
interface IPlugin {
14+
rules: {[x: string]: eslint.Rule.RuleModule};
15+
}
16+
17+
export const plugin: IPlugin = {
18+
rules: {
19+
"tsdoc-comments": {
20+
meta: {
21+
messages: messageIds,
22+
type: "problem",
23+
docs: {
24+
description: "Validates tsdoc comments",
25+
category: "Typescript",
26+
recommended: false,
27+
url: "https://github.com/microsoft/tsdoc"
28+
}
29+
},
30+
create: (context: eslint.Rule.RuleContext) => {
31+
const tsDocParser: TSDocParser = new TSDocParser();
32+
const sourceCode: eslint.SourceCode = context.getSourceCode();
33+
const checkCommentBlocks: (node: ESTree.Node) => void = function (node: ESTree.Node) {
34+
const commentBlocks: ESTree.Comment[] = sourceCode.getCommentsBefore(node).filter(function (comment: ESTree.Comment) {
35+
return comment.type === "Block";
36+
});
37+
if (commentBlocks.length > 0) {
38+
const commentBlock: ESTree.Comment = commentBlocks[0];
39+
const commentString: string = "/*" + commentBlock.value + "*/";
40+
const results: ParserMessageLog = tsDocParser.parseString(commentString).log;
41+
for (const message of results.messages) {
42+
context.report({
43+
node: node,
44+
messageId: message.messageId,
45+
data: {
46+
unformattedText: message.unformattedText
47+
}
48+
});
49+
}
50+
}
51+
}
52+
53+
return {
54+
ClassDeclaration: checkCommentBlocks,
55+
FunctionDeclaration: checkCommentBlocks
56+
};
57+
}
58+
}
59+
}
60+
}

eslint-plugin/src/tests/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
import { RuleTester } from "eslint";
3+
import { plugin } from "../index";
4+
5+
const ruleTester: RuleTester = new RuleTester({
6+
env: {
7+
es6: true
8+
}
9+
});
10+
ruleTester.run("tsdoc-comments", plugin.rules["tsdoc-comments"], {
11+
valid: [
12+
"/**\nA great function!\n */\nfunction foobar() {}\n",
13+
"/**\nA great class!\n */\nclass FooBar {}\n"
14+
],
15+
invalid: [{
16+
code: "/**\n * This `is wrong\n */\nfunction foobar() {}\n",
17+
errors: [{
18+
messageId: "tsdoc-code-span-missing-delimiter"
19+
}]
20+
}, {
21+
code: "/**\n * This `is wrong\n */\nclass FooBar {}\n",
22+
errors: [{
23+
messageId: "tsdoc-code-span-missing-delimiter"
24+
}]
25+
}]
26+
});

eslint-plugin/tsconfig.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"$schema": "http://json.schemastore.org/tsconfig",
3+
4+
"compilerOptions": {
5+
"target": "es5",
6+
"forceConsistentCasingInFileNames": true,
7+
"module": "commonjs",
8+
"declaration": true,
9+
"sourceMap": false,
10+
"experimentalDecorators": true,
11+
"types": [
12+
"eslint",
13+
"node"
14+
],
15+
16+
"lib": [
17+
"es5",
18+
"scripthost",
19+
"es2015.collection",
20+
"es2015.promise",
21+
"es2015.iterable"
22+
],
23+
24+
"noImplicitAny": true,
25+
"noImplicitReturns": true,
26+
"noImplicitThis": true,
27+
"noUnusedLocals": true,
28+
"strictFunctionTypes": true,
29+
"strictNullChecks": true,
30+
"strictPropertyInitialization": true,
31+
32+
"outDir": "lib"
33+
},
34+
"include": [
35+
"src/**/*.ts"
36+
]
37+
}

0 commit comments

Comments
 (0)