Skip to content

Commit ae2fde2

Browse files
authored
Merge branch 'main' into dev/joyceerhl/inevitable-porcupine
2 parents 43ae67e + 1715e06 commit ae2fde2

File tree

73 files changed

+1220
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1220
-257
lines changed

.eslintrc.json

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
"plugins": [
99
"@typescript-eslint",
1010
"jsdoc",
11-
"header",
12-
"@vscode"
11+
"header"
1312
],
1413
"rules": {
1514
"constructor-super": "warn",
@@ -62,17 +61,17 @@
6261
]
6362
}
6463
],
65-
"@vscode/code-no-unused-expressions": [
64+
"code-no-unused-expressions": [
6665
"warn",
6766
{
6867
"allowTernary": true
6968
}
7069
],
71-
"@vscode/code-translation-remind": "warn",
72-
"@vscode/code-no-nls-in-standalone-editor": "warn",
73-
"@vscode/code-no-standalone-editor": "warn",
74-
"@vscode/code-no-unexternalized-strings": "warn",
75-
"@vscode/code-layering": [
70+
"code-translation-remind": "warn",
71+
"code-no-nls-in-standalone-editor": "warn",
72+
"code-no-standalone-editor": "warn",
73+
"code-no-unexternalized-strings": "warn",
74+
"code-layering": [
7675
"warn",
7776
{
7877
"common": [],
@@ -123,8 +122,8 @@
123122
"**/*.test.ts"
124123
],
125124
"rules": {
126-
"@vscode/code-no-test-only": "error",
127-
"@vscode/code-no-unexternalized-strings": "off"
125+
"code-no-test-only": "error",
126+
"code-no-unexternalized-strings": "off"
128127
}
129128
},
130129
{
@@ -133,14 +132,14 @@
133132
"**/vscode.proposed.*.d.ts"
134133
],
135134
"rules": {
136-
"@vscode/vscode-dts-create-func": "warn",
137-
"@vscode/vscode-dts-literal-or-types": "warn",
138-
"@vscode/vscode-dts-interface-naming": "warn",
139-
"@vscode/vscode-dts-cancellation": "warn",
140-
"@vscode/vscode-dts-use-thenable": "warn",
141-
"@vscode/vscode-dts-region-comments": "warn",
142-
"@vscode/vscode-dts-vscode-in-comments": "warn",
143-
"@vscode/vscode-dts-provider-naming": [
135+
"vscode-dts-create-func": "warn",
136+
"vscode-dts-literal-or-types": "warn",
137+
"vscode-dts-interface-naming": "warn",
138+
"vscode-dts-cancellation": "warn",
139+
"vscode-dts-use-thenable": "warn",
140+
"vscode-dts-region-comments": "warn",
141+
"vscode-dts-vscode-in-comments": "warn",
142+
"vscode-dts-provider-naming": [
144143
"warn",
145144
{
146145
"allowed": [
@@ -155,7 +154,7 @@
155154
]
156155
}
157156
],
158-
"@vscode/vscode-dts-event-naming": [
157+
"vscode-dts-event-naming": [
159158
"warn",
160159
{
161160
"allowed": [
@@ -201,8 +200,8 @@
201200
"src/**/*.ts"
202201
],
203202
"rules": {
204-
"@vscode/code-no-look-behind-regex": "warn",
205-
"@vscode/code-import-patterns": [
203+
"code-no-look-behind-regex": "warn",
204+
"code-import-patterns": [
206205
"warn",
207206
{
208207
// imports that are allowed in all files of layers:
@@ -577,7 +576,7 @@
577576
"test/**/*.ts"
578577
],
579578
"rules": {
580-
"@vscode/code-import-patterns": [
579+
"code-import-patterns": [
581580
"warn",
582581
{
583582
"target": "test/smoke/**",

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
}
4242
}
4343
],
44+
"eslint.options": {
45+
"rulePaths": [
46+
"./build/lib/eslint"
47+
]
48+
},
4449
"typescript.tsdk": "node_modules/typescript/lib",
4550
"npm.exclude": "**/extensions/**",
4651
"npm.packageManager": "yarn",

build/eslint.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ function eslint() {
1313
.src(eslintFilter, { base: '.', follow: true, allowEmpty: true })
1414
.pipe(
1515
gulpeslint({
16-
configFile: '.eslintrc.json'
16+
configFile: '.eslintrc.json',
17+
rulePaths: ['./build/lib/eslint'],
1718
})
1819
)
1920
.pipe(gulpeslint.formatEach('compact'))

build/hygiene.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ function hygiene(some, linting = true) {
173173
.pipe(filter(eslintFilter))
174174
.pipe(
175175
gulpeslint({
176-
configFile: '.eslintrc.json'
176+
configFile: '.eslintrc.json',
177+
rulePaths: ['./build/lib/eslint'],
177178
})
178179
)
179180
.pipe(gulpeslint.formatEach('compact'))

build/lib/eslint-plugin-vscode/index.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

build/lib/eslint-plugin-vscode/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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 = require("path");
7+
const minimatch = require("minimatch");
8+
const utils_1 = require("./utils");
9+
const REPO_ROOT = path.normalize(path.join(__dirname, '../../../'));
10+
function isLayerAllowRule(option) {
11+
return !!(option.when && option.allow);
12+
}
13+
/**
14+
* Returns the filename relative to the project root and using `/` as separators
15+
*/
16+
function getRelativeFilename(context) {
17+
const filename = path.normalize(context.getFilename());
18+
return filename.substring(REPO_ROOT.length).replace(/\\/g, '/');
19+
}
20+
module.exports = new class {
21+
constructor() {
22+
this.meta = {
23+
messages: {
24+
badImport: 'Imports violates \'{{restrictions}}\' restrictions. See https://github.com/microsoft/vscode/wiki/Source-Code-Organization',
25+
badFilename: 'Missing definition in `code-import-patterns` for this file. Define rules at https://github.com/microsoft/vscode/blob/main/.eslintrc.json'
26+
},
27+
docs: {
28+
url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization'
29+
}
30+
};
31+
this._optionsCache = new WeakMap();
32+
}
33+
create(context) {
34+
const options = context.options;
35+
const configs = this._processOptions(options);
36+
const relativeFilename = getRelativeFilename(context);
37+
for (const config of configs) {
38+
if (minimatch(relativeFilename, config.target)) {
39+
return (0, utils_1.createImportRuleListener)((node, value) => this._checkImport(context, config, node, value));
40+
}
41+
}
42+
context.report({
43+
loc: { line: 1, column: 0 },
44+
messageId: 'badFilename'
45+
});
46+
return {};
47+
}
48+
_processOptions(options) {
49+
if (this._optionsCache.has(options)) {
50+
return this._optionsCache.get(options);
51+
}
52+
function orSegment(variants) {
53+
return (variants.length === 1 ? variants[0] : `{${variants.join(',')}}`);
54+
}
55+
const layerRules = [
56+
{ layer: 'common', deps: orSegment(['common']) },
57+
{ layer: 'worker', deps: orSegment(['common', 'worker']) },
58+
{ layer: 'browser', deps: orSegment(['common', 'browser']), isBrowser: true },
59+
{ layer: 'electron-sandbox', deps: orSegment(['common', 'browser', 'electron-sandbox']), isBrowser: true },
60+
{ layer: 'node', deps: orSegment(['common', 'node']), isNode: true },
61+
{ layer: 'electron-browser', deps: orSegment(['common', 'browser', 'node', 'electron-sandbox', 'electron-browser']), isBrowser: true, isNode: true },
62+
{ layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-main']), isNode: true },
63+
];
64+
let browserAllow = [];
65+
let nodeAllow = [];
66+
let testAllow = [];
67+
for (const option of options) {
68+
if (isLayerAllowRule(option)) {
69+
if (option.when === 'hasBrowser') {
70+
browserAllow = option.allow.slice(0);
71+
}
72+
else if (option.when === 'hasNode') {
73+
nodeAllow = option.allow.slice(0);
74+
}
75+
else if (option.when === 'test') {
76+
testAllow = option.allow.slice(0);
77+
}
78+
}
79+
}
80+
function findLayer(layer) {
81+
for (const layerRule of layerRules) {
82+
if (layerRule.layer === layer) {
83+
return layerRule;
84+
}
85+
}
86+
return null;
87+
}
88+
function generateConfig(layerRule, target, rawRestrictions) {
89+
const restrictions = [];
90+
const testRestrictions = [...testAllow];
91+
if (layerRule.isBrowser) {
92+
restrictions.push(...browserAllow);
93+
}
94+
if (layerRule.isNode) {
95+
restrictions.push(...nodeAllow);
96+
}
97+
for (const rawRestriction of rawRestrictions) {
98+
let importPattern;
99+
let when = undefined;
100+
if (typeof rawRestriction === 'string') {
101+
importPattern = rawRestriction;
102+
}
103+
else {
104+
importPattern = rawRestriction.pattern;
105+
when = rawRestriction.when;
106+
}
107+
if (typeof when === 'undefined'
108+
|| (when === 'hasBrowser' && layerRule.isBrowser)
109+
|| (when === 'hasNode' && layerRule.isNode)) {
110+
restrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`));
111+
testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`));
112+
}
113+
else if (when === 'test') {
114+
testRestrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`));
115+
testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`));
116+
}
117+
}
118+
testRestrictions.push(...restrictions);
119+
return [
120+
{
121+
target: target.replace(/\/\~$/, `/${layerRule.layer}/**`),
122+
restrictions: restrictions
123+
},
124+
{
125+
target: target.replace(/\/\~$/, `/test/${layerRule.layer}/**`),
126+
restrictions: testRestrictions
127+
}
128+
];
129+
}
130+
const configs = [];
131+
for (const option of options) {
132+
if (isLayerAllowRule(option)) {
133+
continue;
134+
}
135+
const target = option.target;
136+
const targetIsVS = /^src\/vs\//.test(target);
137+
const restrictions = (typeof option.restrictions === 'string' ? [option.restrictions] : option.restrictions).slice(0);
138+
if (targetIsVS) {
139+
// Always add "vs/nls"
140+
restrictions.push('vs/nls');
141+
}
142+
if (targetIsVS && option.layer) {
143+
// single layer => simple substitution for /~
144+
const layerRule = findLayer(option.layer);
145+
if (layerRule) {
146+
const [config, testConfig] = generateConfig(layerRule, target, restrictions);
147+
if (option.test) {
148+
configs.push(testConfig);
149+
}
150+
else {
151+
configs.push(config);
152+
}
153+
}
154+
}
155+
else if (targetIsVS && /\/\~$/.test(target)) {
156+
// generate all layers
157+
for (const layerRule of layerRules) {
158+
const [config, testConfig] = generateConfig(layerRule, target, restrictions);
159+
configs.push(config);
160+
configs.push(testConfig);
161+
}
162+
}
163+
else {
164+
configs.push({ target, restrictions: restrictions.filter(r => typeof r === 'string') });
165+
}
166+
}
167+
this._optionsCache.set(options, configs);
168+
return configs;
169+
}
170+
_checkImport(context, config, node, importPath) {
171+
// resolve relative paths
172+
if (importPath[0] === '.') {
173+
const relativeFilename = getRelativeFilename(context);
174+
importPath = path.posix.join(path.posix.dirname(relativeFilename), importPath);
175+
if (/^src\/vs\//.test(importPath)) {
176+
// resolve using AMD base url
177+
importPath = importPath.substring('src/'.length);
178+
}
179+
}
180+
const restrictions = config.restrictions;
181+
let matched = false;
182+
for (const pattern of restrictions) {
183+
if (minimatch(importPath, pattern)) {
184+
matched = true;
185+
break;
186+
}
187+
}
188+
if (!matched) {
189+
// None of the restrictions matched
190+
context.report({
191+
loc: node.loc,
192+
messageId: 'badImport',
193+
data: {
194+
restrictions: restrictions.join(' or ')
195+
}
196+
});
197+
}
198+
}
199+
};

build/lib/eslint-plugin-vscode/code-import-patterns.ts renamed to build/lib/eslint/code-import-patterns.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import * as eslint from 'eslint';
77
import { TSESTree } from '@typescript-eslint/experimental-utils';
88
import * as path from 'path';
9-
import minimatch from 'minimatch';
9+
import * as minimatch from 'minimatch';
1010
import { createImportRuleListener } from './utils';
1111

1212
const REPO_ROOT = path.normalize(path.join(__dirname, '../../../'));

0 commit comments

Comments
 (0)