Skip to content

Commit 556475c

Browse files
committed
add eslint-rules "module" and use it in eslintrc-file
1 parent 5c9a0af commit 556475c

10 files changed

Lines changed: 1560 additions & 20 deletions

File tree

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
**/insane/**
2+
**/marked/**
3+
**/test/**/*.js

.eslintrc.json

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
11
{
2+
"$schema": "http://json.schemastore.org/eslintrc",
23
"root": true,
3-
"env": {
4-
"node": true,
5-
"es6": true
4+
"parser": "@typescript-eslint/parser",
5+
"parserOptions": {
6+
"ecmaVersion": 6,
7+
"sourceType": "module",
8+
"project": "./src/tsconfig.json"
69
},
10+
"plugins": [
11+
"code-oss-eslint"
12+
],
713
"rules": {
8-
"no-console": 0,
9-
"no-cond-assign": 0,
10-
"no-unused-vars": 1,
11-
"no-extra-semi": "warn",
12-
"semi": "warn"
13-
},
14-
"extends": "eslint:recommended",
15-
"parserOptions": {
16-
"ecmaFeatures": {
17-
"experimentalObjectRestSpread": true
18-
}
14+
"no-extra-semi": "off",
15+
"no-unused-vars": "off",
16+
"semi": "warn",
17+
"eqeqeq": "warn",
18+
"no-duplicate-imports": "warn",
19+
"code-oss-eslint/layering": [
20+
"warn",
21+
{
22+
"common": [],
23+
"node": [
24+
"common"
25+
],
26+
"browser": [
27+
"common"
28+
],
29+
"electron-main": [
30+
"common",
31+
"node"
32+
],
33+
"electron-browser": [
34+
"common",
35+
"browser",
36+
"node"
37+
]
38+
}
39+
]
1940
}
2041
}

build/lib/eslint/lib/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"use strict";
2+
/*---------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All rights reserved.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
const layering = require('./rules/layering');
7+
const rules = {
8+
'layering': layering
9+
};
10+
module.exports = { rules };

build/lib/eslint/lib/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
const layering = require('./rules/layering');
7+
8+
const rules = {
9+
'layering': layering
10+
};
11+
12+
export = { rules };
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"use strict";
2+
/*---------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All rights reserved.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
const path_1 = require("path");
7+
module.exports = new class {
8+
constructor() {
9+
this.meta = {
10+
type: 'problem',
11+
schema: {},
12+
messages: {
13+
layerbreaker: 'Bad layering. You are not allowed to access {{from}} from here, allowed layers are: [{{allowed}}]'
14+
}
15+
};
16+
}
17+
create(context) {
18+
const fileDirname = path_1.dirname(context.getFilename());
19+
const parts = fileDirname.split(/\\|\//);
20+
const ruleArgs = context.options[0];
21+
let config;
22+
for (let i = parts.length - 1; i >= 0; i--) {
23+
if (ruleArgs[parts[i]]) {
24+
config = {
25+
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
26+
disallowed: new Set()
27+
};
28+
Object.keys(ruleArgs).forEach(key => {
29+
if (!config.allowed.has(key)) {
30+
config.disallowed.add(key);
31+
}
32+
});
33+
break;
34+
}
35+
}
36+
if (!config) {
37+
// nothing
38+
return {};
39+
}
40+
return {
41+
ImportDeclaration: (node) => {
42+
this._checkImport(context, config, node, node.source.value);
43+
},
44+
CallExpression: (node) => {
45+
var _a;
46+
const { callee, arguments: args } = node;
47+
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
48+
this._checkImport(context, config, node, args[0].value);
49+
}
50+
}
51+
};
52+
}
53+
_checkImport(context, config, node, path) {
54+
if (typeof path !== 'string') {
55+
return;
56+
}
57+
if (path[0] === '.') {
58+
path = path_1.join(path_1.dirname(context.getFilename()), path);
59+
}
60+
const parts = path_1.dirname(path).split(/\\|\//);
61+
for (let i = parts.length - 1; i >= 0; i--) {
62+
const part = parts[i];
63+
if (config.allowed.has(part)) {
64+
// GOOD - same layer
65+
break;
66+
}
67+
if (config.disallowed.has(part)) {
68+
// BAD - wrong layer
69+
context.report({
70+
node,
71+
messageId: 'layerbreaker',
72+
data: {
73+
from: part,
74+
allowed: [...config.allowed.keys()].join(', ')
75+
}
76+
});
77+
break;
78+
}
79+
}
80+
}
81+
};
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as eslint from 'eslint';
7+
import * as estree from 'estree';
8+
import { join, dirname } from 'path';
9+
10+
type Config = {
11+
allowed: Set<string>;
12+
disallowed: Set<string>;
13+
};
14+
15+
export = new class implements eslint.Rule.RuleModule {
16+
17+
meta = {
18+
type: 'problem',
19+
schema: {},
20+
messages: {
21+
layerbreaker: 'Bad layering. You are not allowed to access {{from}} from here, allowed layers are: [{{allowed}}]'
22+
}
23+
};
24+
25+
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
26+
27+
const fileDirname = dirname(context.getFilename());
28+
const parts = fileDirname.split(/\\|\//);
29+
const ruleArgs = <Record<string, string[]>>context.options[0];
30+
31+
let config: Config | undefined;
32+
for (let i = parts.length - 1; i >= 0; i--) {
33+
if (ruleArgs[parts[i]]) {
34+
config = {
35+
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
36+
disallowed: new Set()
37+
};
38+
Object.keys(ruleArgs).forEach(key => {
39+
if (!config!.allowed.has(key)) {
40+
config!.disallowed.add(key);
41+
}
42+
});
43+
break;
44+
}
45+
}
46+
47+
if (!config) {
48+
// nothing
49+
return {};
50+
}
51+
52+
return {
53+
ImportDeclaration: (node: estree.Node) => {
54+
this._checkImport(context, config!, node, (<estree.ImportDeclaration>node).source.value);
55+
},
56+
CallExpression: (node: estree.Node) => {
57+
const { callee, arguments: args } = <estree.CallExpression>node;
58+
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
59+
this._checkImport(context, config!, node, (<estree.Literal>args[0]).value);
60+
}
61+
}
62+
};
63+
}
64+
65+
private _checkImport(context: eslint.Rule.RuleContext, config: Config, node: estree.Node, path: any) {
66+
if (typeof path !== 'string') {
67+
return;
68+
}
69+
70+
if (path[0] === '.') {
71+
path = join(dirname(context.getFilename()), path);
72+
}
73+
74+
const parts = dirname(path).split(/\\|\//);
75+
for (let i = parts.length - 1; i >= 0; i--) {
76+
const part = parts[i];
77+
78+
if (config!.allowed.has(part)) {
79+
// GOOD - same layer
80+
break;
81+
}
82+
83+
if (config!.disallowed.has(part)) {
84+
// BAD - wrong layer
85+
context.report({
86+
node,
87+
messageId: 'layerbreaker',
88+
data: {
89+
from: part,
90+
allowed: [...config!.allowed.keys()].join(', ')
91+
}
92+
});
93+
94+
break;
95+
}
96+
}
97+
}
98+
};
99+

build/lib/eslint/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "code-oss-eslint",
3+
"version": "1.0.0",
4+
"license": "MIT",
5+
"description": "ESLint rules for code oss",
6+
"engines": {
7+
"node": ">=0.10.0"
8+
},
9+
"keywords": [
10+
"eslint",
11+
"eslintplugin",
12+
"eslint-plugin"
13+
],
14+
"author": "vscode",
15+
"main": "lib/index.js",
16+
"devDependencies": {
17+
"@types/eslint": "4.16.1",
18+
"eslint": "~3.9.1"
19+
}
20+
}

0 commit comments

Comments
 (0)