mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 09:18:59 +00:00
extract import path detection into util
This commit is contained in:
parent
b05b481265
commit
808865cf57
|
@ -5,6 +5,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
const path_1 = require("path");
|
||||
const minimatch = require("minimatch");
|
||||
const utils_1 = require("./utils");
|
||||
module.exports = new class {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
|
@ -19,26 +20,12 @@ module.exports = new class {
|
|||
const configs = context.options;
|
||||
for (const config of configs) {
|
||||
if (minimatch(context.getFilename(), config.target)) {
|
||||
return {
|
||||
ImportDeclaration: (node) => {
|
||||
this._checkImport(context, config, node, node.source.value);
|
||||
},
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
this._checkImport(context, config, node, args[0].value);
|
||||
}
|
||||
}
|
||||
};
|
||||
return utils_1.createImportRuleListener((node, value) => this._checkImport(context, config, node, value));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
_checkImport(context, config, node, path) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(context.getFilename(), path);
|
||||
|
|
|
@ -7,6 +7,7 @@ import * as eslint from 'eslint';
|
|||
import * as estree from 'estree';
|
||||
import { join } from 'path';
|
||||
import * as minimatch from 'minimatch';
|
||||
import { createImportRuleListener } from './utils';
|
||||
|
||||
interface ImportPatternsConfig {
|
||||
target: string;
|
||||
|
@ -29,28 +30,14 @@ export = new class implements eslint.Rule.RuleModule {
|
|||
|
||||
for (const config of configs) {
|
||||
if (minimatch(context.getFilename(), config.target)) {
|
||||
return {
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
this._checkImport(context, config!, node, (<estree.ImportDeclaration>node).source.value);
|
||||
},
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
this._checkImport(context, config!, node, (<estree.Literal>args[0]).value);
|
||||
}
|
||||
}
|
||||
};
|
||||
return createImportRuleListener((node, value) => this._checkImport(context, config, node, value));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
}
|
||||
|
||||
private _checkImport(context: eslint.Rule.RuleContext, config: ImportPatternsConfig, node: estree.Node, path: any) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
private _checkImport(context: eslint.Rule.RuleContext, config: ImportPatternsConfig, node: estree.Node, path: string) {
|
||||
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const path_1 = require("path");
|
||||
const utils_1 = require("./utils");
|
||||
module.exports = new class {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
|
@ -37,45 +38,30 @@ module.exports = new class {
|
|||
// nothing
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
ImportDeclaration: (node) => {
|
||||
this._checkImport(context, config, node, node.source.value);
|
||||
},
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
this._checkImport(context, config, node, args[0].value);
|
||||
return utils_1.createImportRuleListener((node, path) => {
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(path_1.dirname(context.getFilename()), path);
|
||||
}
|
||||
const parts = path_1.dirname(path).split(/\\|\//);
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
const part = parts[i];
|
||||
if (config.allowed.has(part)) {
|
||||
// GOOD - same layer
|
||||
break;
|
||||
}
|
||||
if (config.disallowed.has(part)) {
|
||||
// BAD - wrong layer
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'layerbreaker',
|
||||
data: {
|
||||
from: part,
|
||||
allowed: [...config.allowed.keys()].join(', ')
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
_checkImport(context, config, node, path) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(path_1.dirname(context.getFilename()), path);
|
||||
}
|
||||
const parts = path_1.dirname(path).split(/\\|\//);
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
const part = parts[i];
|
||||
if (config.allowed.has(part)) {
|
||||
// GOOD - same layer
|
||||
break;
|
||||
}
|
||||
if (config.disallowed.has(part)) {
|
||||
// BAD - wrong layer
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'layerbreaker',
|
||||
data: {
|
||||
from: part,
|
||||
allowed: [...config.allowed.keys()].join(', ')
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as eslint from 'eslint';
|
||||
import * as estree from 'estree';
|
||||
import { join, dirname } from 'path';
|
||||
import { createImportRuleListener } from './utils';
|
||||
|
||||
type Config = {
|
||||
allowed: Set<string>;
|
||||
|
@ -49,51 +49,34 @@ export = new class implements eslint.Rule.RuleModule {
|
|||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
this._checkImport(context, config!, node, (<estree.ImportDeclaration>node).source.value);
|
||||
},
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
this._checkImport(context, config!, node, (<estree.Literal>args[0]).value);
|
||||
return createImportRuleListener((node, path) => {
|
||||
if (path[0] === '.') {
|
||||
path = join(dirname(context.getFilename()), path);
|
||||
}
|
||||
|
||||
const parts = dirname(path).split(/\\|\//);
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
const part = parts[i];
|
||||
|
||||
if (config!.allowed.has(part)) {
|
||||
// GOOD - same layer
|
||||
break;
|
||||
}
|
||||
|
||||
if (config!.disallowed.has(part)) {
|
||||
// BAD - wrong layer
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'layerbreaker',
|
||||
data: {
|
||||
from: part,
|
||||
allowed: [...config!.allowed.keys()].join(', ')
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _checkImport(context: eslint.Rule.RuleContext, config: Config, node: estree.Node, path: any) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path[0] === '.') {
|
||||
path = join(dirname(context.getFilename()), path);
|
||||
}
|
||||
|
||||
const parts = dirname(path).split(/\\|\//);
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
const part = parts[i];
|
||||
|
||||
if (config.allowed.has(part)) {
|
||||
// GOOD - same layer
|
||||
break;
|
||||
}
|
||||
|
||||
if (config.disallowed.has(part)) {
|
||||
// BAD - wrong layer
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'layerbreaker',
|
||||
data: {
|
||||
from: part,
|
||||
allowed: [...config.allowed.keys()].join(', ')
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const path_1 = require("path");
|
||||
const utils_1 = require("./utils");
|
||||
module.exports = new class NoNlsInStandaloneEditorRule {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
|
@ -16,39 +17,24 @@ module.exports = new class NoNlsInStandaloneEditorRule {
|
|||
}
|
||||
create(context) {
|
||||
const fileName = context.getFilename();
|
||||
if (!(/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(fileName)
|
||||
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(fileName))) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
ImportDeclaration: (node) => {
|
||||
this._checkImport(context, node, node.source.value);
|
||||
},
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
this._checkImport(context, node, args[0].value);
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(fileName)) {
|
||||
return utils_1.createImportRuleListener((node, path) => {
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(context.getFilename(), path);
|
||||
}
|
||||
if (/vs(\/|\\)nls/.test(path)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noNls'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
_checkImport(context, node, path) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(context.getFilename(), path);
|
||||
}
|
||||
if (/vs(\/|\\)nls/.test(path)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noNls'
|
||||
});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as eslint from 'eslint';
|
||||
import * as estree from 'estree';
|
||||
import { join } from 'path';
|
||||
import { createImportRuleListener } from './utils';
|
||||
|
||||
export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule {
|
||||
|
||||
|
@ -20,48 +20,31 @@ export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule
|
|||
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
|
||||
|
||||
const fileName = context.getFilename();
|
||||
if (!(
|
||||
if (
|
||||
/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(fileName)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(fileName)
|
||||
)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
this._checkImport(context, node, (<estree.ImportDeclaration>node).source.value);
|
||||
},
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
this._checkImport(context, node, (<estree.Literal>args[0]).value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _checkImport(context: eslint.Rule.RuleContext, node: estree.Node, path: any) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = join(context.getFilename(), path);
|
||||
}
|
||||
|
||||
if (
|
||||
/vs(\/|\\)nls/.test(path)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noNls'
|
||||
return createImportRuleListener((node, path) => {
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = join(context.getFilename(), path);
|
||||
}
|
||||
|
||||
if (
|
||||
/vs(\/|\\)nls/.test(path)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noNls'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const path_1 = require("path");
|
||||
const utils_1 = require("./utils");
|
||||
module.exports = new class NoNlsInStandaloneEditorRule {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
|
@ -19,36 +20,21 @@ module.exports = new class NoNlsInStandaloneEditorRule {
|
|||
// the vs/editor folder is allowed to use the standalone editor
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
ImportDeclaration: (node) => {
|
||||
this._checkImport(context, node, node.source.value);
|
||||
},
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
this._checkImport(context, node, args[0].value);
|
||||
}
|
||||
return utils_1.createImportRuleListener((node, path) => {
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(context.getFilename(), path);
|
||||
}
|
||||
};
|
||||
}
|
||||
_checkImport(context, node, path) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(context.getFilename(), path);
|
||||
}
|
||||
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badImport'
|
||||
});
|
||||
}
|
||||
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badImport'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as eslint from 'eslint';
|
||||
import * as estree from 'estree';
|
||||
import { join } from 'path';
|
||||
import { createImportRuleListener } from './utils';
|
||||
|
||||
export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule {
|
||||
|
||||
|
@ -24,41 +24,26 @@ export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule
|
|||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
this._checkImport(context, node, (<estree.ImportDeclaration>node).source.value);
|
||||
},
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
this._checkImport(context, node, (<estree.Literal>args[0]).value);
|
||||
}
|
||||
return createImportRuleListener((node, path) => {
|
||||
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = join(context.getFilename(), path);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _checkImport(context: eslint.Rule.RuleContext, node: estree.Node, path: any) {
|
||||
if (typeof path !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = join(context.getFilename(), path);
|
||||
}
|
||||
|
||||
if (
|
||||
/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badImport'
|
||||
});
|
||||
}
|
||||
if (
|
||||
/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badImport'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
var _a;
|
||||
const fs_1 = require("fs");
|
||||
const utils_1 = require("./utils");
|
||||
module.exports = new (_a = class TranslationRemind {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
|
@ -16,51 +17,41 @@ module.exports = new (_a = class TranslationRemind {
|
|||
};
|
||||
}
|
||||
create(context) {
|
||||
return {
|
||||
ImportDeclaration: (node) => {
|
||||
this._checkImport(context, node, node.source.value);
|
||||
},
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
this._checkImport(context, node, args[0].value);
|
||||
}
|
||||
}
|
||||
};
|
||||
return utils_1.createImportRuleListener((node, path) => this._checkImport(context, node, path));
|
||||
}
|
||||
_checkImport(context, node, path) {
|
||||
if (path === TranslationRemind.NLS_MODULE) {
|
||||
const currentFile = context.getFilename();
|
||||
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
|
||||
if (!matchService && !matchPart) {
|
||||
if (path !== TranslationRemind.NLS_MODULE) {
|
||||
return;
|
||||
}
|
||||
const currentFile = context.getFilename();
|
||||
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
|
||||
if (!matchService && !matchPart) {
|
||||
return;
|
||||
}
|
||||
const resource = matchService ? matchService[0] : matchPart[0];
|
||||
let resourceDefined = false;
|
||||
let json;
|
||||
try {
|
||||
json = fs_1.readFileSync('./build/lib/i18n.resources.json', 'utf8');
|
||||
}
|
||||
catch (e) {
|
||||
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
|
||||
return;
|
||||
}
|
||||
const workbenchResources = JSON.parse(json).workbench;
|
||||
workbenchResources.forEach((existingResource) => {
|
||||
if (existingResource.name === resource) {
|
||||
resourceDefined = true;
|
||||
return;
|
||||
}
|
||||
const resource = matchService ? matchService[0] : matchPart[0];
|
||||
let resourceDefined = false;
|
||||
let json;
|
||||
try {
|
||||
json = fs_1.readFileSync('./build/lib/i18n.resources.json', 'utf8');
|
||||
}
|
||||
catch (e) {
|
||||
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
|
||||
return;
|
||||
}
|
||||
const workbenchResources = JSON.parse(json).workbench;
|
||||
workbenchResources.forEach((existingResource) => {
|
||||
if (existingResource.name === resource) {
|
||||
resourceDefined = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!resourceDefined) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'missing',
|
||||
data: { resource }
|
||||
});
|
||||
if (!resourceDefined) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'missing',
|
||||
data: { resource }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import * as eslint from 'eslint';
|
||||
import * as estree from 'estree';
|
||||
import { readFileSync } from 'fs';
|
||||
import { createImportRuleListener } from './utils';
|
||||
|
||||
|
||||
export = new class TranslationRemind implements eslint.Rule.RuleModule {
|
||||
|
@ -21,59 +22,48 @@ export = new class TranslationRemind implements eslint.Rule.RuleModule {
|
|||
};
|
||||
|
||||
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
|
||||
|
||||
return {
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
this._checkImport(context, node, (<estree.ImportDeclaration>node).source.value);
|
||||
},
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
this._checkImport(context, node, (<estree.Literal>args[0]).value);
|
||||
}
|
||||
}
|
||||
};
|
||||
return createImportRuleListener((node, path) => this._checkImport(context, node, path));
|
||||
}
|
||||
|
||||
private _checkImport(context: eslint.Rule.RuleContext, node: estree.Node, path: any) {
|
||||
private _checkImport(context: eslint.Rule.RuleContext, node: estree.Node, path: string) {
|
||||
|
||||
if (path === TranslationRemind.NLS_MODULE) {
|
||||
|
||||
const currentFile = context.getFilename();
|
||||
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
|
||||
if (!matchService && !matchPart) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resource = matchService ? matchService[0] : matchPart![0];
|
||||
let resourceDefined = false;
|
||||
|
||||
let json;
|
||||
try {
|
||||
json = readFileSync('./build/lib/i18n.resources.json', 'utf8');
|
||||
} catch (e) {
|
||||
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
|
||||
return;
|
||||
}
|
||||
const workbenchResources = JSON.parse(json).workbench;
|
||||
|
||||
workbenchResources.forEach((existingResource: any) => {
|
||||
if (existingResource.name === resource) {
|
||||
resourceDefined = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!resourceDefined) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'missing',
|
||||
data: { resource }
|
||||
});
|
||||
}
|
||||
if (path !== TranslationRemind.NLS_MODULE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentFile = context.getFilename();
|
||||
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
|
||||
if (!matchService && !matchPart) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resource = matchService ? matchService[0] : matchPart![0];
|
||||
let resourceDefined = false;
|
||||
|
||||
let json;
|
||||
try {
|
||||
json = readFileSync('./build/lib/i18n.resources.json', 'utf8');
|
||||
} catch (e) {
|
||||
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
|
||||
return;
|
||||
}
|
||||
const workbenchResources = JSON.parse(json).workbench;
|
||||
|
||||
workbenchResources.forEach((existingResource: any) => {
|
||||
if (existingResource.name === resource) {
|
||||
resourceDefined = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!resourceDefined) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'missing',
|
||||
data: { resource }
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
36
build/lib/eslint/utils.js
Normal file
36
build/lib/eslint/utils.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function createImportRuleListener(validateImport) {
|
||||
function _checkImport(node) {
|
||||
if (node && node.type === 'Literal' && typeof node.value === 'string') {
|
||||
validateImport(node, node.value);
|
||||
}
|
||||
}
|
||||
return {
|
||||
// import ??? from 'module'
|
||||
ImportDeclaration: (node) => {
|
||||
_checkImport(node.source);
|
||||
},
|
||||
// import('module').then(...)
|
||||
CallExpression: (node) => {
|
||||
var _a;
|
||||
const { callee, arguments: args } = node;
|
||||
if (callee.type === 'Import' && ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.type) === 'Literal') {
|
||||
_checkImport(args[0]);
|
||||
}
|
||||
},
|
||||
// export ?? from 'module'
|
||||
ExportAllDeclaration: (node) => {
|
||||
_checkImport(node.source);
|
||||
},
|
||||
// export {foo} from 'module'
|
||||
ExportNamedDeclaration: (node) => {
|
||||
_checkImport(node.source);
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.createImportRuleListener = createImportRuleListener;
|
46
build/lib/eslint/utils.ts
Normal file
46
build/lib/eslint/utils.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as eslint from 'eslint';
|
||||
import * as estree from 'estree';
|
||||
|
||||
//https://github.com/estree/estree/blob/master/es2015.md#exportnameddeclaration
|
||||
declare interface ExportNamedDeclaration {
|
||||
type: "ExportNamedDeclaration";
|
||||
declaration: estree.Declaration | null;
|
||||
specifiers: [estree.ExportSpecifier];
|
||||
source: estree.Literal | null;
|
||||
}
|
||||
|
||||
export function createImportRuleListener(validateImport: (node: estree.SimpleLiteral, value: string) => any): eslint.Rule.RuleListener {
|
||||
|
||||
function _checkImport(node: estree.Literal | null) {
|
||||
if (node && node.type === 'Literal' && typeof node.value === 'string') {
|
||||
validateImport(<estree.SimpleLiteral>node, node.value);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// import ??? from 'module'
|
||||
ImportDeclaration: (node: estree.Node) => {
|
||||
_checkImport((<estree.ImportDeclaration>node).source);
|
||||
},
|
||||
// import('module').then(...)
|
||||
CallExpression: (node: estree.Node) => {
|
||||
const { callee, arguments: args } = <estree.CallExpression>node;
|
||||
if ((<any>callee.type) === 'Import' && args[0]?.type === 'Literal') {
|
||||
_checkImport(<estree.SimpleLiteral>args[0]);
|
||||
}
|
||||
},
|
||||
// export ?? from 'module'
|
||||
ExportAllDeclaration: (node: estree.Node) => {
|
||||
_checkImport((<estree.ExportAllDeclaration>node).source);
|
||||
},
|
||||
// export {foo} from 'module'
|
||||
ExportNamedDeclaration: (node: estree.Node) => {
|
||||
_checkImport((<ExportNamedDeclaration>node).source);
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue