forked from enviPath/enviPy
Current Dev State
This commit is contained in:
116
static/js/ketcher2/node_modules/eslint/lib/util/comment-event-generator.js
generated
vendored
Normal file
116
static/js/ketcher2/node_modules/eslint/lib/util/comment-event-generator.js
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @fileoverview The event generator for comments.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check collection of comments to prevent double event for comment as
|
||||
* leading and trailing, then emit event if passing
|
||||
* @param {ASTNode[]} comments - Collection of comment nodes
|
||||
* @param {EventEmitter} emitter - The event emitter which is the destination of events.
|
||||
* @param {Object[]} locs - List of locations of previous comment nodes
|
||||
* @param {string} eventName - Event name postfix
|
||||
* @returns {void}
|
||||
*/
|
||||
function emitComments(comments, emitter, locs, eventName) {
|
||||
if (comments.length > 0) {
|
||||
comments.forEach(node => {
|
||||
const index = locs.indexOf(node.loc);
|
||||
|
||||
if (index >= 0) {
|
||||
locs.splice(index, 1);
|
||||
} else {
|
||||
locs.push(node.loc);
|
||||
emitter.emit(node.type + eventName, node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to check and emit enter of comment nodes
|
||||
* @param {CommentEventGenerator} generator - A generator to emit.
|
||||
* @param {ASTNode[]} comments - Collection of comment nodes
|
||||
* @returns {void}
|
||||
*/
|
||||
function emitCommentsEnter(generator, comments) {
|
||||
emitComments(
|
||||
comments,
|
||||
generator.emitter,
|
||||
generator.commentLocsEnter,
|
||||
"Comment");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to check and emit exit of comment nodes
|
||||
* @param {CommentEventGenerator} generator - A generator to emit.
|
||||
* @param {ASTNode[]} comments Collection of comment nodes
|
||||
* @returns {void}
|
||||
*/
|
||||
function emitCommentsExit(generator, comments) {
|
||||
emitComments(
|
||||
comments,
|
||||
generator.emitter,
|
||||
generator.commentLocsExit,
|
||||
"Comment:exit");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The event generator for comments.
|
||||
* This is the decorator pattern.
|
||||
* This generates events of comments before/after events which are generated the original generator.
|
||||
*
|
||||
* Comment event generator class
|
||||
*/
|
||||
class CommentEventGenerator {
|
||||
|
||||
/**
|
||||
* @param {EventGenerator} originalEventGenerator - An event generator which is the decoration target.
|
||||
* @param {SourceCode} sourceCode - A source code which has comments.
|
||||
*/
|
||||
constructor(originalEventGenerator, sourceCode) {
|
||||
this.original = originalEventGenerator;
|
||||
this.emitter = originalEventGenerator.emitter;
|
||||
this.sourceCode = sourceCode;
|
||||
this.commentLocsEnter = [];
|
||||
this.commentLocsExit = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event of entering comments.
|
||||
* @param {ASTNode} node - A node which was entered.
|
||||
* @returns {void}
|
||||
*/
|
||||
enterNode(node) {
|
||||
const comments = this.sourceCode.getComments(node);
|
||||
|
||||
emitCommentsEnter(this, comments.leading);
|
||||
this.original.enterNode(node);
|
||||
emitCommentsEnter(this, comments.trailing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event of leaving comments.
|
||||
* @param {ASTNode} node - A node which was left.
|
||||
* @returns {void}
|
||||
*/
|
||||
leaveNode(node) {
|
||||
const comments = this.sourceCode.getComments(node);
|
||||
|
||||
emitCommentsExit(this, comments.trailing);
|
||||
this.original.leaveNode(node);
|
||||
emitCommentsExit(this, comments.leading);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CommentEventGenerator;
|
||||
121
static/js/ketcher2/node_modules/eslint/lib/util/fix-tracker.js
generated
vendored
Normal file
121
static/js/ketcher2/node_modules/eslint/lib/util/fix-tracker.js
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @fileoverview Helper class to aid in constructing fix commands.
|
||||
* @author Alan Pierce
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("../ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A helper class to combine fix options into a fix command. Currently, it
|
||||
* exposes some "retain" methods that extend the range of the text being
|
||||
* replaced so that other fixes won't touch that region in the same pass.
|
||||
*/
|
||||
class FixTracker {
|
||||
|
||||
/**
|
||||
* Create a new FixTracker.
|
||||
*
|
||||
* @param {ruleFixer} fixer A ruleFixer instance.
|
||||
* @param {SourceCode} sourceCode A SourceCode object for the current code.
|
||||
*/
|
||||
constructor(fixer, sourceCode) {
|
||||
this.fixer = fixer;
|
||||
this.sourceCode = sourceCode;
|
||||
this.retainedRange = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the given range as "retained", meaning that other fixes may not
|
||||
* may not modify this region in the same pass.
|
||||
*
|
||||
* @param {int[]} range The range to retain.
|
||||
* @returns {FixTracker} The same RuleFixer, for chained calls.
|
||||
*/
|
||||
retainRange(range) {
|
||||
this.retainedRange = range;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node, find the function containing it (or the entire program) and
|
||||
* mark it as retained, meaning that other fixes may not modify it in this
|
||||
* pass. This is useful for avoiding conflicts in fixes that modify control
|
||||
* flow.
|
||||
*
|
||||
* @param {ASTNode} node The node to use as a starting point.
|
||||
* @returns {FixTracker} The same RuleFixer, for chained calls.
|
||||
*/
|
||||
retainEnclosingFunction(node) {
|
||||
const functionNode = astUtils.getUpperFunction(node);
|
||||
|
||||
return this.retainRange(
|
||||
functionNode ? functionNode.range : this.sourceCode.ast.range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node or token, find the token before and afterward, and mark that
|
||||
* range as retained, meaning that other fixes may not modify it in this
|
||||
* pass. This is useful for avoiding conflicts in fixes that make a small
|
||||
* change to the code where the AST should not be changed.
|
||||
*
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to use as a starting
|
||||
* point. The token to the left and right are use in the range.
|
||||
* @returns {FixTracker} The same RuleFixer, for chained calls.
|
||||
*/
|
||||
retainSurroundingTokens(nodeOrToken) {
|
||||
const tokenBefore = this.sourceCode.getTokenBefore(nodeOrToken) || nodeOrToken;
|
||||
const tokenAfter = this.sourceCode.getTokenAfter(nodeOrToken) || nodeOrToken;
|
||||
|
||||
return this.retainRange([tokenBefore.range[0], tokenAfter.range[1]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fix command that replaces the given range with the given text,
|
||||
* accounting for any retained ranges.
|
||||
*
|
||||
* @param {int[]} range The range to remove in the fix.
|
||||
* @param {string} text The text to insert in place of the range.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
replaceTextRange(range, text) {
|
||||
let actualRange;
|
||||
|
||||
if (this.retainedRange) {
|
||||
actualRange = [
|
||||
Math.min(this.retainedRange[0], range[0]),
|
||||
Math.max(this.retainedRange[1], range[1])
|
||||
];
|
||||
} else {
|
||||
actualRange = range;
|
||||
}
|
||||
|
||||
return this.fixer.replaceTextRange(
|
||||
actualRange,
|
||||
this.sourceCode.text.slice(actualRange[0], range[0]) +
|
||||
text +
|
||||
this.sourceCode.text.slice(range[1], actualRange[1])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fix command that removes the given node or token, accounting for
|
||||
* any retained ranges.
|
||||
*
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to remove.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
remove(nodeOrToken) {
|
||||
return this.replaceTextRange(nodeOrToken.range, "");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FixTracker;
|
||||
183
static/js/ketcher2/node_modules/eslint/lib/util/glob-util.js
generated
vendored
Normal file
183
static/js/ketcher2/node_modules/eslint/lib/util/glob-util.js
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @fileoverview Utilities for working with globs and the filesystem.
|
||||
* @author Ian VanSchooten
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const fs = require("fs"),
|
||||
path = require("path"),
|
||||
GlobSync = require("./glob"),
|
||||
shell = require("shelljs"),
|
||||
|
||||
pathUtil = require("./path-util"),
|
||||
IgnoredPaths = require("../ignored-paths");
|
||||
|
||||
const debug = require("debug")("eslint:glob-util");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if a provided path is a directory and returns a glob string matching
|
||||
* all files under that directory if so, the path itself otherwise.
|
||||
*
|
||||
* Reason for this is that `glob` needs `/**` to collect all the files under a
|
||||
* directory where as our previous implementation without `glob` simply walked
|
||||
* a directory that is passed. So this is to maintain backwards compatibility.
|
||||
*
|
||||
* Also makes sure all path separators are POSIX style for `glob` compatibility.
|
||||
*
|
||||
* @param {Object} [options] An options object
|
||||
* @param {string[]} [options.extensions=[".js"]] An array of accepted extensions
|
||||
* @param {string} [options.cwd=process.cwd()] The cwd to use to resolve relative pathnames
|
||||
* @returns {Function} A function that takes a pathname and returns a glob that
|
||||
* matches all files with the provided extensions if
|
||||
* pathname is a directory.
|
||||
*/
|
||||
function processPath(options) {
|
||||
const cwd = (options && options.cwd) || process.cwd();
|
||||
let extensions = (options && options.extensions) || [".js"];
|
||||
|
||||
extensions = extensions.map(ext => ext.replace(/^\./, ""));
|
||||
|
||||
let suffix = "/**";
|
||||
|
||||
if (extensions.length === 1) {
|
||||
suffix += `/*.${extensions[0]}`;
|
||||
} else {
|
||||
suffix += `/*.{${extensions.join(",")}}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that converts a directory name to a glob pattern
|
||||
*
|
||||
* @param {string} pathname The directory path to be modified
|
||||
* @returns {string} The glob path or the file path itself
|
||||
* @private
|
||||
*/
|
||||
return function(pathname) {
|
||||
let newPath = pathname;
|
||||
const resolvedPath = path.resolve(cwd, pathname);
|
||||
|
||||
if (shell.test("-d", resolvedPath)) {
|
||||
newPath = pathname.replace(/[/\\]$/, "") + suffix;
|
||||
}
|
||||
|
||||
return pathUtil.convertPathToPosix(newPath);
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolves any directory patterns into glob-based patterns for easier handling.
|
||||
* @param {string[]} patterns File patterns (such as passed on the command line).
|
||||
* @param {Object} options An options object.
|
||||
* @returns {string[]} The equivalent glob patterns and filepath strings.
|
||||
*/
|
||||
function resolveFileGlobPatterns(patterns, options) {
|
||||
|
||||
const processPathExtensions = processPath(options);
|
||||
|
||||
return patterns.filter(p => p.length).map(processPathExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of absolute filesnames on which ESLint will act.
|
||||
* Ignored files are excluded from the results, as are duplicates.
|
||||
*
|
||||
* @param {string[]} globPatterns Glob patterns.
|
||||
* @param {Object} [options] An options object.
|
||||
* @param {string} [options.cwd] CWD (considered for relative filenames)
|
||||
* @param {boolean} [options.ignore] False disables use of .eslintignore.
|
||||
* @param {string} [options.ignorePath] The ignore file to use instead of .eslintignore.
|
||||
* @param {string} [options.ignorePattern] A pattern of files to ignore.
|
||||
* @returns {string[]} Resolved absolute filenames.
|
||||
*/
|
||||
function listFilesToProcess(globPatterns, options) {
|
||||
options = options || { ignore: true };
|
||||
const files = [],
|
||||
added = {};
|
||||
|
||||
const cwd = (options && options.cwd) || process.cwd();
|
||||
|
||||
/**
|
||||
* Executes the linter on a file defined by the `filename`. Skips
|
||||
* unsupported file extensions and any files that are already linted.
|
||||
* @param {string} filename The file to be processed
|
||||
* @param {boolean} shouldWarnIgnored Whether or not a report should be made if
|
||||
* the file is ignored
|
||||
* @param {IgnoredPaths} ignoredPaths An instance of IgnoredPaths
|
||||
* @returns {void}
|
||||
*/
|
||||
function addFile(filename, shouldWarnIgnored, ignoredPaths) {
|
||||
let ignored = false;
|
||||
let isSilentlyIgnored;
|
||||
|
||||
if (ignoredPaths.contains(filename, "default")) {
|
||||
ignored = (options.ignore !== false) && shouldWarnIgnored;
|
||||
isSilentlyIgnored = !shouldWarnIgnored;
|
||||
}
|
||||
|
||||
if (options.ignore !== false) {
|
||||
if (ignoredPaths.contains(filename, "custom")) {
|
||||
if (shouldWarnIgnored) {
|
||||
ignored = true;
|
||||
} else {
|
||||
isSilentlyIgnored = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isSilentlyIgnored && !ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (added[filename]) {
|
||||
return;
|
||||
}
|
||||
files.push({ filename, ignored });
|
||||
added[filename] = true;
|
||||
}
|
||||
|
||||
debug("Creating list of files to process.");
|
||||
globPatterns.forEach(pattern => {
|
||||
const file = path.resolve(cwd, pattern);
|
||||
|
||||
if (shell.test("-f", file)) {
|
||||
const ignoredPaths = new IgnoredPaths(options);
|
||||
|
||||
addFile(fs.realpathSync(file), !shell.test("-d", file), ignoredPaths);
|
||||
} else {
|
||||
|
||||
// regex to find .hidden or /.hidden patterns, but not ./relative or ../relative
|
||||
const globIncludesDotfiles = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/.test(pattern);
|
||||
|
||||
const ignoredPaths = new IgnoredPaths(Object.assign({}, options, { dotfiles: options.dotfiles || globIncludesDotfiles }));
|
||||
const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker();
|
||||
const globOptions = {
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd
|
||||
};
|
||||
|
||||
new GlobSync(pattern, globOptions, shouldIgnore).found.forEach(globMatch => {
|
||||
addFile(path.resolve(cwd, globMatch), false, ignoredPaths);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
resolveFileGlobPatterns,
|
||||
listFilesToProcess
|
||||
};
|
||||
63
static/js/ketcher2/node_modules/eslint/lib/util/glob.js
generated
vendored
Normal file
63
static/js/ketcher2/node_modules/eslint/lib/util/glob.js
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @fileoverview An inherited `glob.GlobSync` to support .gitignore patterns.
|
||||
* @author Kael Zhang
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const Sync = require("glob").GlobSync,
|
||||
util = require("util");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const IGNORE = Symbol("ignore");
|
||||
|
||||
/**
|
||||
* Subclass of `glob.GlobSync`
|
||||
* @param {string} pattern Pattern to be matched.
|
||||
* @param {Object} options `options` for `glob`
|
||||
* @param {function()} shouldIgnore Method to check whether a directory should be ignored.
|
||||
* @constructor
|
||||
*/
|
||||
function GlobSync(pattern, options, shouldIgnore) {
|
||||
|
||||
/**
|
||||
* We don't put this thing to argument `options` to avoid
|
||||
* further problems, such as `options` validation.
|
||||
*
|
||||
* Use `Symbol` as much as possible to avoid confliction.
|
||||
*/
|
||||
this[IGNORE] = shouldIgnore;
|
||||
|
||||
Sync.call(this, pattern, options);
|
||||
}
|
||||
|
||||
util.inherits(GlobSync, Sync);
|
||||
|
||||
/* eslint no-underscore-dangle: ["error", { "allow": ["_readdir", "_mark"] }] */
|
||||
|
||||
GlobSync.prototype._readdir = function(abs, inGlobStar) {
|
||||
|
||||
/**
|
||||
* `options.nodir` makes `options.mark` as `true`.
|
||||
* Mark `abs` first
|
||||
* to make sure `"node_modules"` will be ignored immediately with ignore pattern `"node_modules/"`.
|
||||
|
||||
* There is a built-in cache about marked `File.Stat` in `glob`, so that we could not worry about the extra invocation of `this._mark()`
|
||||
*/
|
||||
const marked = this._mark(abs);
|
||||
|
||||
if (this[IGNORE](marked)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Sync.prototype._readdir.call(this, abs, inGlobStar);
|
||||
};
|
||||
|
||||
|
||||
module.exports = GlobSync;
|
||||
35
static/js/ketcher2/node_modules/eslint/lib/util/hash.js
generated
vendored
Normal file
35
static/js/ketcher2/node_modules/eslint/lib/util/hash.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @fileoverview Defining the hashing function in one place.
|
||||
* @author Michael Ficarra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const murmur = require("imurmurhash");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* hash the given string
|
||||
* @param {string} str the string to hash
|
||||
* @returns {string} the hash
|
||||
*/
|
||||
function hash(str) {
|
||||
return murmur(str).result().toString(36);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = hash;
|
||||
67
static/js/ketcher2/node_modules/eslint/lib/util/keywords.js
generated
vendored
Normal file
67
static/js/ketcher2/node_modules/eslint/lib/util/keywords.js
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @fileoverview A shared list of ES3 keywords.
|
||||
* @author Josh Perez
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
module.exports = [
|
||||
"abstract",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"catch",
|
||||
"char",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"enum",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"final",
|
||||
"finally",
|
||||
"float",
|
||||
"for",
|
||||
"function",
|
||||
"goto",
|
||||
"if",
|
||||
"implements",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"int",
|
||||
"interface",
|
||||
"long",
|
||||
"native",
|
||||
"new",
|
||||
"null",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"static",
|
||||
"super",
|
||||
"switch",
|
||||
"synchronized",
|
||||
"this",
|
||||
"throw",
|
||||
"throws",
|
||||
"transient",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"volatile",
|
||||
"while",
|
||||
"with"
|
||||
];
|
||||
85
static/js/ketcher2/node_modules/eslint/lib/util/module-resolver.js
generated
vendored
Normal file
85
static/js/ketcher2/node_modules/eslint/lib/util/module-resolver.js
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @fileoverview Implements the Node.js require.resolve algorithm
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const Module = require("module");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
|
||||
/*
|
||||
* module.paths is an array of paths to search for resolving things relative
|
||||
* to this file. Module.globalPaths contains all of the special Node.js
|
||||
* directories that can also be searched for modules.
|
||||
*
|
||||
* Need to check for existence of module.paths because Jest seems not to
|
||||
* include it. See https://github.com/eslint/eslint/issues/5791.
|
||||
*/
|
||||
lookupPaths: module.paths ? module.paths.concat(Module.globalPaths) : Module.globalPaths.concat()
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves modules based on a set of options.
|
||||
*/
|
||||
class ModuleResolver {
|
||||
|
||||
/**
|
||||
* Resolves modules based on a set of options.
|
||||
* @param {Object} options The options for resolving modules.
|
||||
* @param {string[]} options.lookupPaths An array of paths to include in the
|
||||
* lookup with the highest priority paths coming first.
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = Object.assign({}, DEFAULT_OPTIONS, options || {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the file location of a given module relative to the configured
|
||||
* lookup paths.
|
||||
* @param {string} name The module name to resolve.
|
||||
* @param {string} extraLookupPath An extra path to look into for the module.
|
||||
* This path is used with the highest priority.
|
||||
* @returns {string} The resolved file path for the module.
|
||||
* @throws {Error} If the module cannot be resolved.
|
||||
*/
|
||||
resolve(name, extraLookupPath) {
|
||||
|
||||
/*
|
||||
* First, clone the lookup paths so we're not messing things up for
|
||||
* subsequent calls to this function. Then, move the extraLookupPath to the
|
||||
* top of the lookup paths list so it will be searched first.
|
||||
*/
|
||||
const lookupPaths = this.options.lookupPaths.concat();
|
||||
|
||||
lookupPaths.unshift(extraLookupPath);
|
||||
|
||||
/**
|
||||
* Module._findPath is an internal method to Node.js, then one they use to
|
||||
* lookup file paths when require() is called. So, we are hooking into the
|
||||
* exact same logic that Node.js uses.
|
||||
*/
|
||||
const result = Module._findPath(name, lookupPaths); // eslint-disable-line no-underscore-dangle
|
||||
|
||||
if (!result) {
|
||||
throw new Error(`Cannot find module '${name}'`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public API
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = ModuleResolver;
|
||||
322
static/js/ketcher2/node_modules/eslint/lib/util/node-event-generator.js
generated
vendored
Normal file
322
static/js/ketcher2/node_modules/eslint/lib/util/node-event-generator.js
generated
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
/**
|
||||
* @fileoverview The event generator for AST nodes.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const esquery = require("esquery");
|
||||
const lodash = require("lodash");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* An object describing an AST selector
|
||||
* @typedef {Object} ASTSelector
|
||||
* @property {string} rawSelector The string that was parsed into this selector
|
||||
* @property {boolean} isExit `true` if this should be emitted when exiting the node rather than when entering
|
||||
* @property {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector
|
||||
* @property {string[]|null} listenerTypes A list of node types that could possibly cause the selector to match,
|
||||
* or `null` if all node types could cause a match
|
||||
* @property {number} attributeCount The total number of classes, pseudo-classes, and attribute queries in this selector
|
||||
* @property {number} identifierCount The total number of identifier queries in this selector
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the possible types of a selector
|
||||
* @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector
|
||||
* @returns {string[]|null} The node types that could possibly trigger this selector, or `null` if all node types could trigger it
|
||||
*/
|
||||
function getPossibleTypes(parsedSelector) {
|
||||
switch (parsedSelector.type) {
|
||||
case "identifier":
|
||||
return [parsedSelector.value];
|
||||
|
||||
case "matches": {
|
||||
const typesForComponents = parsedSelector.selectors.map(getPossibleTypes);
|
||||
|
||||
if (typesForComponents.every(typesForComponent => typesForComponent)) {
|
||||
return lodash.union.apply(null, typesForComponents);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
case "compound": {
|
||||
const typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(typesForComponent => typesForComponent);
|
||||
|
||||
// If all of the components could match any type, then the compound could also match any type.
|
||||
if (!typesForComponents.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* If at least one of the components could only match a particular type, the compound could only match
|
||||
* the intersection of those types.
|
||||
*/
|
||||
return lodash.intersection.apply(null, typesForComponents);
|
||||
}
|
||||
|
||||
case "child":
|
||||
case "descendant":
|
||||
case "sibling":
|
||||
case "adjacent":
|
||||
return getPossibleTypes(parsedSelector.right);
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of class, pseudo-class, and attribute queries in this selector
|
||||
* @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior
|
||||
* @returns {number} The number of class, pseudo-class, and attribute queries in this selector
|
||||
*/
|
||||
function countClassAttributes(parsedSelector) {
|
||||
switch (parsedSelector.type) {
|
||||
case "child":
|
||||
case "descendant":
|
||||
case "sibling":
|
||||
case "adjacent":
|
||||
return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right);
|
||||
|
||||
case "compound":
|
||||
case "not":
|
||||
case "matches":
|
||||
return parsedSelector.selectors.reduce((sum, childSelector) => sum + countClassAttributes(childSelector), 0);
|
||||
|
||||
case "attribute":
|
||||
case "field":
|
||||
case "nth-child":
|
||||
case "nth-last-child":
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of identifier queries in this selector
|
||||
* @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior
|
||||
* @returns {number} The number of identifier queries
|
||||
*/
|
||||
function countIdentifiers(parsedSelector) {
|
||||
switch (parsedSelector.type) {
|
||||
case "child":
|
||||
case "descendant":
|
||||
case "sibling":
|
||||
case "adjacent":
|
||||
return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right);
|
||||
|
||||
case "compound":
|
||||
case "not":
|
||||
case "matches":
|
||||
return parsedSelector.selectors.reduce((sum, childSelector) => sum + countIdentifiers(childSelector), 0);
|
||||
|
||||
case "identifier":
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specificity of two selector objects, with CSS-like rules.
|
||||
* @param {ASTSelector} selectorA An AST selector descriptor
|
||||
* @param {ASTSelector} selectorB Another AST selector descriptor
|
||||
* @returns {number}
|
||||
* a value less than 0 if selectorA is less specific than selectorB
|
||||
* a value greater than 0 if selectorA is more specific than selectorB
|
||||
* a value less than 0 if selectorA and selectorB have the same specificity, and selectorA <= selectorB alphabetically
|
||||
* a value greater than 0 if selectorA and selectorB have the same specificity, and selectorA > selectorB alphabetically
|
||||
*/
|
||||
function compareSpecificity(selectorA, selectorB) {
|
||||
return selectorA.attributeCount - selectorB.attributeCount ||
|
||||
selectorA.identifierCount - selectorB.identifierCount ||
|
||||
(selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a raw selector string, and throws a useful error if parsing fails.
|
||||
* @param {string} rawSelector A raw AST selector
|
||||
* @returns {Object} An object (from esquery) describing the matching behavior of this selector
|
||||
* @throws {Error} An error if the selector is invalid
|
||||
*/
|
||||
function tryParseSelector(rawSelector) {
|
||||
try {
|
||||
return esquery.parse(rawSelector.replace(/:exit$/, ""));
|
||||
} catch (err) {
|
||||
if (typeof err.offset === "number") {
|
||||
throw new Error(`Syntax error in selector "${rawSelector}" at position ${err.offset}: ${err.message}`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a raw selector string, and returns the parsed selector along with specificity and type information.
|
||||
* @param {string} rawSelector A raw AST selector
|
||||
* @returns {ASTSelector} A selector descriptor
|
||||
*/
|
||||
const parseSelector = lodash.memoize(rawSelector => {
|
||||
const parsedSelector = tryParseSelector(rawSelector);
|
||||
|
||||
return {
|
||||
rawSelector,
|
||||
isExit: rawSelector.endsWith(":exit"),
|
||||
parsedSelector,
|
||||
listenerTypes: getPossibleTypes(parsedSelector),
|
||||
attributeCount: countClassAttributes(parsedSelector),
|
||||
identifierCount: countIdentifiers(parsedSelector)
|
||||
};
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The event generator for AST nodes.
|
||||
* This implements below interface.
|
||||
*
|
||||
* ```ts
|
||||
* interface EventGenerator {
|
||||
* emitter: EventEmitter;
|
||||
* enterNode(node: ASTNode): void;
|
||||
* leaveNode(node: ASTNode): void;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class NodeEventGenerator {
|
||||
|
||||
/**
|
||||
* @param {EventEmitter} emitter - An event emitter which is the destination of events. This emitter must already
|
||||
* have registered listeners for all of the events that it needs to listen for.
|
||||
* @returns {NodeEventGenerator} new instance
|
||||
*/
|
||||
constructor(emitter) {
|
||||
this.emitter = emitter;
|
||||
this.currentAncestry = [];
|
||||
this.enterSelectorsByNodeType = new Map();
|
||||
this.exitSelectorsByNodeType = new Map();
|
||||
this.anyTypeEnterSelectors = [];
|
||||
this.anyTypeExitSelectors = [];
|
||||
|
||||
const eventNames = typeof emitter.eventNames === "function"
|
||||
|
||||
// Use the built-in eventNames() function if available (Node 6+)
|
||||
? emitter.eventNames()
|
||||
|
||||
/*
|
||||
* Otherwise, use the private _events property.
|
||||
* Using a private property isn't ideal here, but this seems to
|
||||
* be the best way to get a list of event names without overriding
|
||||
* addEventListener, which would hurt performance. This property
|
||||
* is widely used and unlikely to be removed in a future version
|
||||
* (see https://github.com/nodejs/node/issues/1817). Also, future
|
||||
* node versions will have eventNames() anyway.
|
||||
*/
|
||||
: Object.keys(emitter._events); // eslint-disable-line no-underscore-dangle
|
||||
|
||||
eventNames.forEach(rawSelector => {
|
||||
const selector = parseSelector(rawSelector);
|
||||
|
||||
if (selector.listenerTypes) {
|
||||
selector.listenerTypes.forEach(nodeType => {
|
||||
const typeMap = selector.isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType;
|
||||
|
||||
if (!typeMap.has(nodeType)) {
|
||||
typeMap.set(nodeType, []);
|
||||
}
|
||||
typeMap.get(nodeType).push(selector);
|
||||
});
|
||||
} else {
|
||||
(selector.isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors).push(selector);
|
||||
}
|
||||
});
|
||||
|
||||
this.anyTypeEnterSelectors.sort(compareSpecificity);
|
||||
this.anyTypeExitSelectors.sort(compareSpecificity);
|
||||
this.enterSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity));
|
||||
this.exitSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a selector against a node, and emits it if it matches
|
||||
* @param {ASTNode} node The node to check
|
||||
* @param {ASTSelector} selector An AST selector descriptor
|
||||
* @returns {void}
|
||||
*/
|
||||
applySelector(node, selector) {
|
||||
if (esquery.matches(node, selector.parsedSelector, this.currentAncestry)) {
|
||||
this.emitter.emit(selector.rawSelector, node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all appropriate selectors to a node, in specificity order
|
||||
* @param {ASTNode} node The node to check
|
||||
* @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited
|
||||
* @returns {void}
|
||||
*/
|
||||
applySelectors(node, isExit) {
|
||||
const selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || [];
|
||||
const anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors;
|
||||
|
||||
/*
|
||||
* selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor.
|
||||
* Iterate through each of them, applying selectors in the right order.
|
||||
*/
|
||||
let selectorsByTypeIndex = 0;
|
||||
let anyTypeSelectorsIndex = 0;
|
||||
|
||||
while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) {
|
||||
if (
|
||||
selectorsByTypeIndex >= selectorsByNodeType.length ||
|
||||
anyTypeSelectorsIndex < anyTypeSelectors.length &&
|
||||
compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0
|
||||
) {
|
||||
this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]);
|
||||
} else {
|
||||
this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event of entering AST node.
|
||||
* @param {ASTNode} node - A node which was entered.
|
||||
* @returns {void}
|
||||
*/
|
||||
enterNode(node) {
|
||||
if (node.parent) {
|
||||
this.currentAncestry.unshift(node.parent);
|
||||
}
|
||||
this.applySelectors(node, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event of leaving AST node.
|
||||
* @param {ASTNode} node - A node which was left.
|
||||
* @returns {void}
|
||||
*/
|
||||
leaveNode(node) {
|
||||
this.applySelectors(node, true);
|
||||
this.currentAncestry.shift();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NodeEventGenerator;
|
||||
146
static/js/ketcher2/node_modules/eslint/lib/util/npm-util.js
generated
vendored
Normal file
146
static/js/ketcher2/node_modules/eslint/lib/util/npm-util.js
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @fileoverview Utility for executing npm commands.
|
||||
* @author Ian VanSchooten
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const fs = require("fs"),
|
||||
path = require("path"),
|
||||
shell = require("shelljs"),
|
||||
log = require("../logging");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find the closest package.json file, starting at process.cwd (by default),
|
||||
* and working up to root.
|
||||
*
|
||||
* @param {string} [startDir=process.cwd()] Starting directory
|
||||
* @returns {string} Absolute path to closest package.json file
|
||||
*/
|
||||
function findPackageJson(startDir) {
|
||||
let dir = path.resolve(startDir || process.cwd());
|
||||
|
||||
do {
|
||||
const pkgfile = path.join(dir, "package.json");
|
||||
|
||||
if (!shell.test("-f", pkgfile)) {
|
||||
dir = path.join(dir, "..");
|
||||
continue;
|
||||
}
|
||||
return pkgfile;
|
||||
} while (dir !== path.resolve(dir, ".."));
|
||||
return null;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Install node modules synchronously and save to devDependencies in package.json
|
||||
* @param {string|string[]} packages Node module or modules to install
|
||||
* @returns {void}
|
||||
*/
|
||||
function installSyncSaveDev(packages) {
|
||||
if (Array.isArray(packages)) {
|
||||
packages = packages.join(" ");
|
||||
}
|
||||
shell.exec(`npm i --save-dev ${packages}`, { stdio: "inherit" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether node modules are include in a project's package.json.
|
||||
*
|
||||
* @param {string[]} packages Array of node module names
|
||||
* @param {Object} opt Options Object
|
||||
* @param {boolean} opt.dependencies Set to true to check for direct dependencies
|
||||
* @param {boolean} opt.devDependencies Set to true to check for development dependencies
|
||||
* @param {boolean} opt.startdir Directory to begin searching from
|
||||
* @returns {Object} An object whose keys are the module names
|
||||
* and values are booleans indicating installation.
|
||||
*/
|
||||
function check(packages, opt) {
|
||||
let deps = [];
|
||||
const pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson();
|
||||
let fileJson;
|
||||
|
||||
if (!pkgJson) {
|
||||
throw new Error("Could not find a package.json file. Run 'npm init' to create one.");
|
||||
}
|
||||
|
||||
try {
|
||||
fileJson = JSON.parse(fs.readFileSync(pkgJson, "utf8"));
|
||||
} catch (e) {
|
||||
log.info("Could not read package.json file. Please check that the file contains valid JSON.");
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
if (opt.devDependencies && typeof fileJson.devDependencies === "object") {
|
||||
deps = deps.concat(Object.keys(fileJson.devDependencies));
|
||||
}
|
||||
if (opt.dependencies && typeof fileJson.dependencies === "object") {
|
||||
deps = deps.concat(Object.keys(fileJson.dependencies));
|
||||
}
|
||||
return packages.reduce((status, pkg) => {
|
||||
status[pkg] = deps.indexOf(pkg) !== -1;
|
||||
return status;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether node modules are included in the dependencies of a project's
|
||||
* package.json.
|
||||
*
|
||||
* Convienience wrapper around check().
|
||||
*
|
||||
* @param {string[]} packages Array of node modules to check.
|
||||
* @param {string} rootDir The directory contianing a package.json
|
||||
* @returns {Object} An object whose keys are the module names
|
||||
* and values are booleans indicating installation.
|
||||
*/
|
||||
function checkDeps(packages, rootDir) {
|
||||
return check(packages, { dependencies: true, startDir: rootDir });
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether node modules are included in the devDependencies of a project's
|
||||
* package.json.
|
||||
*
|
||||
* Convienience wrapper around check().
|
||||
*
|
||||
* @param {string[]} packages Array of node modules to check.
|
||||
* @returns {Object} An object whose keys are the module names
|
||||
* and values are booleans indicating installation.
|
||||
*/
|
||||
function checkDevDeps(packages) {
|
||||
return check(packages, { devDependencies: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether package.json is found in current path.
|
||||
*
|
||||
* @param {string=} startDir Starting directory
|
||||
* @returns {boolean} Whether a package.json is found in current path.
|
||||
*/
|
||||
function checkPackageJson(startDir) {
|
||||
return !!findPackageJson(startDir);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
installSyncSaveDev,
|
||||
checkDeps,
|
||||
checkDevDeps,
|
||||
checkPackageJson
|
||||
};
|
||||
74
static/js/ketcher2/node_modules/eslint/lib/util/path-util.js
generated
vendored
Normal file
74
static/js/ketcher2/node_modules/eslint/lib/util/path-util.js
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @fileoverview Common helpers for operations on filenames and paths
|
||||
* @author Ian VanSchooten
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const path = require("path");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Replace Windows with posix style paths
|
||||
*
|
||||
* @param {string} filepath Path to convert
|
||||
* @returns {string} Converted filepath
|
||||
*/
|
||||
function convertPathToPosix(filepath) {
|
||||
const normalizedFilepath = path.normalize(filepath);
|
||||
const posixFilepath = normalizedFilepath.replace(/\\/g, "/");
|
||||
|
||||
return posixFilepath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an absolute filepath to a relative path from a given base path
|
||||
*
|
||||
* For example, if the filepath is `/my/awesome/project/foo.bar`,
|
||||
* and the base directory is `/my/awesome/project/`,
|
||||
* then this function should return `foo.bar`.
|
||||
*
|
||||
* path.relative() does something similar, but it requires a baseDir (`from` argument).
|
||||
* This function makes it optional and just removes a leading slash if the baseDir is not given.
|
||||
*
|
||||
* It does not take into account symlinks (for now).
|
||||
*
|
||||
* @param {string} filepath Path to convert to relative path. If already relative,
|
||||
* it will be assumed to be relative to process.cwd(),
|
||||
* converted to absolute, and then processed.
|
||||
* @param {string} [baseDir] Absolute base directory to resolve the filepath from.
|
||||
* If not provided, all this function will do is remove
|
||||
* a leading slash.
|
||||
* @returns {string} Relative filepath
|
||||
*/
|
||||
function getRelativePath(filepath, baseDir) {
|
||||
let relativePath;
|
||||
|
||||
if (!path.isAbsolute(filepath)) {
|
||||
filepath = path.resolve(filepath);
|
||||
}
|
||||
if (baseDir) {
|
||||
if (!path.isAbsolute(baseDir)) {
|
||||
throw new Error("baseDir should be an absolute path");
|
||||
}
|
||||
relativePath = path.relative(baseDir, filepath);
|
||||
} else {
|
||||
relativePath = filepath.replace(/^\//, "");
|
||||
}
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
convertPathToPosix,
|
||||
getRelativePath
|
||||
};
|
||||
37
static/js/ketcher2/node_modules/eslint/lib/util/patterns/letters.js
generated
vendored
Normal file
37
static/js/ketcher2/node_modules/eslint/lib/util/patterns/letters.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
140
static/js/ketcher2/node_modules/eslint/lib/util/rule-fixer.js
generated
vendored
Normal file
140
static/js/ketcher2/node_modules/eslint/lib/util/rule-fixer.js
generated
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @fileoverview An object that creates fix commands for rules.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// none!
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a fix command that inserts text at the specified index in the source text.
|
||||
* @param {int} index The 0-based index at which to insert the new text.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
* @private
|
||||
*/
|
||||
function insertTextAt(index, text) {
|
||||
return {
|
||||
range: [index, index],
|
||||
text
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates code fixing commands for rules.
|
||||
*/
|
||||
|
||||
const ruleFixer = Object.freeze({
|
||||
|
||||
/**
|
||||
* Creates a fix command that inserts text after the given node or token.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to insert after.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
insertTextAfter(nodeOrToken, text) {
|
||||
return this.insertTextAfterRange(nodeOrToken.range, text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that inserts text after the specified range in the source text.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {int[]} range The range to replace, first item is start of range, second
|
||||
* is end of range.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
insertTextAfterRange(range, text) {
|
||||
return insertTextAt(range[1], text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that inserts text before the given node or token.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to insert before.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
insertTextBefore(nodeOrToken, text) {
|
||||
return this.insertTextBeforeRange(nodeOrToken.range, text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that inserts text before the specified range in the source text.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {int[]} range The range to replace, first item is start of range, second
|
||||
* is end of range.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
insertTextBeforeRange(range, text) {
|
||||
return insertTextAt(range[0], text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that replaces text at the node or token.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to remove.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
replaceText(nodeOrToken, text) {
|
||||
return this.replaceTextRange(nodeOrToken.range, text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that replaces text at the specified range in the source text.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {int[]} range The range to replace, first item is start of range, second
|
||||
* is end of range.
|
||||
* @param {string} text The text to insert.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
replaceTextRange(range, text) {
|
||||
return {
|
||||
range,
|
||||
text
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that removes the node or token from the source.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {ASTNode|Token} nodeOrToken The node or token to remove.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
remove(nodeOrToken) {
|
||||
return this.removeRange(nodeOrToken.range);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fix command that removes the specified range of text from the source.
|
||||
* The fix is not applied until applyFixes() is called.
|
||||
* @param {int[]} range The range to remove, first item is start of range, second
|
||||
* is end of range.
|
||||
* @returns {Object} The fix command.
|
||||
*/
|
||||
removeRange(range) {
|
||||
return {
|
||||
range,
|
||||
text: ""
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
module.exports = ruleFixer;
|
||||
131
static/js/ketcher2/node_modules/eslint/lib/util/source-code-fixer.js
generated
vendored
Normal file
131
static/js/ketcher2/node_modules/eslint/lib/util/source-code-fixer.js
generated
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @fileoverview An object that caches and applies source code fixes.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const debug = require("debug")("eslint:text-fixer");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const BOM = "\uFEFF";
|
||||
|
||||
/**
|
||||
* Compares items in a messages array by range.
|
||||
* @param {Message} a The first message.
|
||||
* @param {Message} b The second message.
|
||||
* @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
|
||||
* @private
|
||||
*/
|
||||
function compareMessagesByFixRange(a, b) {
|
||||
return a.fix.range[0] - b.fix.range[0] || a.fix.range[1] - b.fix.range[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares items in a messages array by line and column.
|
||||
* @param {Message} a The first message.
|
||||
* @param {Message} b The second message.
|
||||
* @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
|
||||
* @private
|
||||
*/
|
||||
function compareMessagesByLocation(a, b) {
|
||||
return a.line - b.line || a.column - b.column;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Utility for apply fixes to source code.
|
||||
* @constructor
|
||||
*/
|
||||
function SourceCodeFixer() {
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the fixes specified by the messages to the given text. Tries to be
|
||||
* smart about the fixes and won't apply fixes over the same area in the text.
|
||||
* @param {SourceCode} sourceCode The source code to apply the changes to.
|
||||
* @param {Message[]} messages The array of messages reported by ESLint.
|
||||
* @returns {Object} An object containing the fixed text and any unfixed messages.
|
||||
*/
|
||||
SourceCodeFixer.applyFixes = function(sourceCode, messages) {
|
||||
|
||||
debug("Applying fixes");
|
||||
|
||||
if (!sourceCode) {
|
||||
debug("No source code to fix");
|
||||
return {
|
||||
fixed: false,
|
||||
messages,
|
||||
output: ""
|
||||
};
|
||||
}
|
||||
|
||||
// clone the array
|
||||
const remainingMessages = [],
|
||||
fixes = [],
|
||||
bom = (sourceCode.hasBOM ? BOM : ""),
|
||||
text = sourceCode.text;
|
||||
let lastPos = Number.NEGATIVE_INFINITY,
|
||||
output = bom;
|
||||
|
||||
messages.forEach(problem => {
|
||||
if (problem.hasOwnProperty("fix")) {
|
||||
fixes.push(problem);
|
||||
} else {
|
||||
remainingMessages.push(problem);
|
||||
}
|
||||
});
|
||||
|
||||
if (fixes.length) {
|
||||
debug("Found fixes to apply");
|
||||
|
||||
for (const problem of fixes.sort(compareMessagesByFixRange)) {
|
||||
const fix = problem.fix;
|
||||
const start = fix.range[0];
|
||||
const end = fix.range[1];
|
||||
|
||||
// Remain it as a problem if it's overlapped or it's a negative range
|
||||
if (lastPos >= start || start > end) {
|
||||
remainingMessages.push(problem);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove BOM.
|
||||
if ((start < 0 && end >= 0) || (start === 0 && fix.text.startsWith(BOM))) {
|
||||
output = "";
|
||||
}
|
||||
|
||||
// Make output to this fix.
|
||||
output += text.slice(Math.max(0, lastPos), Math.max(0, start));
|
||||
output += fix.text;
|
||||
lastPos = end;
|
||||
}
|
||||
output += text.slice(Math.max(0, lastPos));
|
||||
|
||||
return {
|
||||
fixed: true,
|
||||
messages: remainingMessages.sort(compareMessagesByLocation),
|
||||
output
|
||||
};
|
||||
}
|
||||
|
||||
debug("No fixes to apply");
|
||||
return {
|
||||
fixed: false,
|
||||
messages,
|
||||
output: bom + text
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports = SourceCodeFixer;
|
||||
110
static/js/ketcher2/node_modules/eslint/lib/util/source-code-util.js
generated
vendored
Normal file
110
static/js/ketcher2/node_modules/eslint/lib/util/source-code-util.js
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @fileoverview Tools for obtaining SourceCode objects.
|
||||
* @author Ian VanSchooten
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const CLIEngine = require("../cli-engine"),
|
||||
eslint = require("../eslint"),
|
||||
globUtil = require("./glob-util"),
|
||||
baseDefaultOptions = require("../../conf/cli-options");
|
||||
|
||||
const debug = require("debug")("eslint:source-code-util");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the SourceCode object for a single file
|
||||
* @param {string} filename The fully resolved filename to get SourceCode from.
|
||||
* @param {Object} options A CLIEngine options object.
|
||||
* @returns {Array} Array of the SourceCode object representing the file
|
||||
* and fatal error message.
|
||||
*/
|
||||
function getSourceCodeOfFile(filename, options) {
|
||||
debug("getting sourceCode of", filename);
|
||||
const opts = Object.assign({}, options, { rules: {} });
|
||||
const cli = new CLIEngine(opts);
|
||||
const results = cli.executeOnFiles([filename]);
|
||||
|
||||
if (results && results.results[0] && results.results[0].messages[0] && results.results[0].messages[0].fatal) {
|
||||
const msg = results.results[0].messages[0];
|
||||
|
||||
throw new Error(`(${filename}:${msg.line}:${msg.column}) ${msg.message}`);
|
||||
}
|
||||
const sourceCode = eslint.getSourceCode();
|
||||
|
||||
return sourceCode;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This callback is used to measure execution status in a progress bar
|
||||
* @callback progressCallback
|
||||
* @param {number} The total number of times the callback will be called.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the SourceCode of a single file, or set of files.
|
||||
* @param {string[]|string} patterns A filename, directory name, or glob,
|
||||
* or an array of them
|
||||
* @param {Object} [options] A CLIEngine options object. If not provided,
|
||||
* the default cli options will be used.
|
||||
* @param {progressCallback} [cb] Callback for reporting execution status
|
||||
* @returns {Object} The SourceCode of all processed files.
|
||||
*/
|
||||
function getSourceCodeOfFiles(patterns, options, cb) {
|
||||
const sourceCodes = {};
|
||||
let opts;
|
||||
|
||||
if (typeof patterns === "string") {
|
||||
patterns = [patterns];
|
||||
}
|
||||
|
||||
const defaultOptions = Object.assign({}, baseDefaultOptions, { cwd: process.cwd() });
|
||||
|
||||
if (typeof options === "undefined") {
|
||||
opts = defaultOptions;
|
||||
} else if (typeof options === "function") {
|
||||
cb = options;
|
||||
opts = defaultOptions;
|
||||
} else if (typeof options === "object") {
|
||||
opts = Object.assign({}, defaultOptions, options);
|
||||
}
|
||||
debug("constructed options:", opts);
|
||||
patterns = globUtil.resolveFileGlobPatterns(patterns, opts);
|
||||
|
||||
const filenames = globUtil.listFilesToProcess(patterns, opts)
|
||||
.filter(fileInfo => !fileInfo.ignored)
|
||||
.reduce((files, fileInfo) => files.concat(fileInfo.filename), []);
|
||||
|
||||
if (filenames.length === 0) {
|
||||
debug(`Did not find any files matching pattern(s): ${patterns}`);
|
||||
}
|
||||
filenames.forEach(filename => {
|
||||
const sourceCode = getSourceCodeOfFile(filename, opts);
|
||||
|
||||
if (sourceCode) {
|
||||
debug("got sourceCode of", filename);
|
||||
sourceCodes[filename] = sourceCode;
|
||||
}
|
||||
if (cb) {
|
||||
cb(filenames.length); // eslint-disable-line callback-return
|
||||
}
|
||||
});
|
||||
return sourceCodes;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSourceCodeOfFiles
|
||||
};
|
||||
416
static/js/ketcher2/node_modules/eslint/lib/util/source-code.js
generated
vendored
Normal file
416
static/js/ketcher2/node_modules/eslint/lib/util/source-code.js
generated
vendored
Normal file
@ -0,0 +1,416 @@
|
||||
/**
|
||||
* @fileoverview Abstraction of JavaScript source code.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const TokenStore = require("../token-store"),
|
||||
Traverser = require("./traverser"),
|
||||
astUtils = require("../ast-utils"),
|
||||
lodash = require("lodash");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validates that the given AST has the required information.
|
||||
* @param {ASTNode} ast The Program node of the AST to check.
|
||||
* @throws {Error} If the AST doesn't contain the correct information.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function validate(ast) {
|
||||
|
||||
if (!ast.tokens) {
|
||||
throw new Error("AST is missing the tokens array.");
|
||||
}
|
||||
|
||||
if (!ast.comments) {
|
||||
throw new Error("AST is missing the comments array.");
|
||||
}
|
||||
|
||||
if (!ast.loc) {
|
||||
throw new Error("AST is missing location information.");
|
||||
}
|
||||
|
||||
if (!ast.range) {
|
||||
throw new Error("AST is missing range information");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a JSDoc comment node in an array of comment nodes.
|
||||
* @param {ASTNode[]} comments The array of comment nodes to search.
|
||||
* @param {int} line Line number to look around
|
||||
* @returns {ASTNode} The node if found, null if not.
|
||||
* @private
|
||||
*/
|
||||
function findJSDocComment(comments, line) {
|
||||
|
||||
if (comments) {
|
||||
for (let i = comments.length - 1; i >= 0; i--) {
|
||||
if (comments[i].type === "Block" && comments[i].value.charAt(0) === "*") {
|
||||
|
||||
if (line - comments[i].loc.end.line <= 1) {
|
||||
return comments[i];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if its a ES6 export declaration
|
||||
* @param {ASTNode} astNode - any node
|
||||
* @returns {boolean} whether the given node represents a export declaration
|
||||
* @private
|
||||
*/
|
||||
function looksLikeExport(astNode) {
|
||||
return astNode.type === "ExportDefaultDeclaration" || astNode.type === "ExportNamedDeclaration" ||
|
||||
astNode.type === "ExportAllDeclaration" || astNode.type === "ExportSpecifier";
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two sorted lists into a larger sorted list in O(n) time
|
||||
* @param {Token[]} tokens The list of tokens
|
||||
* @param {Token[]} comments The list of comments
|
||||
* @returns {Token[]} A sorted list of tokens and comments
|
||||
*/
|
||||
function sortedMerge(tokens, comments) {
|
||||
const result = [];
|
||||
let tokenIndex = 0;
|
||||
let commentIndex = 0;
|
||||
|
||||
while (tokenIndex < tokens.length || commentIndex < comments.length) {
|
||||
if (commentIndex >= comments.length || tokenIndex < tokens.length && tokens[tokenIndex].range[0] < comments[commentIndex].range[0]) {
|
||||
result.push(tokens[tokenIndex++]);
|
||||
} else {
|
||||
result.push(comments[commentIndex++]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Represents parsed source code.
|
||||
* @param {string} text - The source code text.
|
||||
* @param {ASTNode} ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
|
||||
* @constructor
|
||||
*/
|
||||
function SourceCode(text, ast) {
|
||||
validate(ast);
|
||||
|
||||
/**
|
||||
* The flag to indicate that the source code has Unicode BOM.
|
||||
* @type boolean
|
||||
*/
|
||||
this.hasBOM = (text.charCodeAt(0) === 0xFEFF);
|
||||
|
||||
/**
|
||||
* The original text source code.
|
||||
* BOM was stripped from this text.
|
||||
* @type string
|
||||
*/
|
||||
this.text = (this.hasBOM ? text.slice(1) : text);
|
||||
|
||||
/**
|
||||
* The parsed AST for the source code.
|
||||
* @type ASTNode
|
||||
*/
|
||||
this.ast = ast;
|
||||
|
||||
/**
|
||||
* The source code split into lines according to ECMA-262 specification.
|
||||
* This is done to avoid each rule needing to do so separately.
|
||||
* @type string[]
|
||||
*/
|
||||
this.lines = [];
|
||||
this.lineStartIndices = [0];
|
||||
|
||||
const lineEndingPattern = astUtils.createGlobalLinebreakMatcher();
|
||||
let match;
|
||||
|
||||
/*
|
||||
* Previously, this was implemented using a regex that
|
||||
* matched a sequence of non-linebreak characters followed by a
|
||||
* linebreak, then adding the lengths of the matches. However,
|
||||
* this caused a catastrophic backtracking issue when the end
|
||||
* of a file contained a large number of non-newline characters.
|
||||
* To avoid this, the current implementation just matches newlines
|
||||
* and uses match.index to get the correct line start indices.
|
||||
*/
|
||||
while ((match = lineEndingPattern.exec(this.text))) {
|
||||
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1], match.index));
|
||||
this.lineStartIndices.push(match.index + match[0].length);
|
||||
}
|
||||
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1]));
|
||||
|
||||
this.tokensAndComments = sortedMerge(ast.tokens, ast.comments);
|
||||
|
||||
// create token store methods
|
||||
const tokenStore = new TokenStore(ast.tokens, ast.comments);
|
||||
|
||||
for (const methodName of TokenStore.PUBLIC_METHODS) {
|
||||
this[methodName] = tokenStore[methodName].bind(tokenStore);
|
||||
}
|
||||
|
||||
// don't allow modification of this object
|
||||
Object.freeze(this);
|
||||
Object.freeze(this.lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the source code into multiple lines based on the line delimiters
|
||||
* @param {string} text Source code as a string
|
||||
* @returns {string[]} Array of source code lines
|
||||
* @public
|
||||
*/
|
||||
SourceCode.splitLines = function(text) {
|
||||
return text.split(astUtils.createGlobalLinebreakMatcher());
|
||||
};
|
||||
|
||||
SourceCode.prototype = {
|
||||
constructor: SourceCode,
|
||||
|
||||
/**
|
||||
* Gets the source code for the given node.
|
||||
* @param {ASTNode=} node The AST node to get the text for.
|
||||
* @param {int=} beforeCount The number of characters before the node to retrieve.
|
||||
* @param {int=} afterCount The number of characters after the node to retrieve.
|
||||
* @returns {string} The text representing the AST node.
|
||||
*/
|
||||
getText(node, beforeCount, afterCount) {
|
||||
if (node) {
|
||||
return this.text.slice(Math.max(node.range[0] - (beforeCount || 0), 0),
|
||||
node.range[1] + (afterCount || 0));
|
||||
}
|
||||
return this.text;
|
||||
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the entire source text split into an array of lines.
|
||||
* @returns {Array} The source text as an array of lines.
|
||||
*/
|
||||
getLines() {
|
||||
return this.lines;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves an array containing all comments in the source code.
|
||||
* @returns {ASTNode[]} An array of comment nodes.
|
||||
*/
|
||||
getAllComments() {
|
||||
return this.ast.comments;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets all comments for the given node.
|
||||
* @param {ASTNode} node The AST node to get the comments for.
|
||||
* @returns {Object} The list of comments indexed by their position.
|
||||
* @public
|
||||
*/
|
||||
getComments(node) {
|
||||
|
||||
let leadingComments = node.leadingComments || [];
|
||||
const trailingComments = node.trailingComments || [];
|
||||
|
||||
/*
|
||||
* espree adds a "comments" array on Program nodes rather than
|
||||
* leadingComments/trailingComments. Comments are only left in the
|
||||
* Program node comments array if there is no executable code.
|
||||
*/
|
||||
if (node.type === "Program") {
|
||||
if (node.body.length === 0) {
|
||||
leadingComments = node.comments;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
leading: leadingComments,
|
||||
trailing: trailingComments
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the JSDoc comment for a given node.
|
||||
* @param {ASTNode} node The AST node to get the comment for.
|
||||
* @returns {ASTNode} The BlockComment node containing the JSDoc for the
|
||||
* given node or null if not found.
|
||||
* @public
|
||||
*/
|
||||
getJSDocComment(node) {
|
||||
|
||||
let parent = node.parent;
|
||||
|
||||
switch (node.type) {
|
||||
case "ClassDeclaration":
|
||||
case "FunctionDeclaration":
|
||||
if (looksLikeExport(parent)) {
|
||||
return findJSDocComment(parent.leadingComments, parent.loc.start.line);
|
||||
}
|
||||
return findJSDocComment(node.leadingComments, node.loc.start.line);
|
||||
|
||||
case "ClassExpression":
|
||||
return findJSDocComment(parent.parent.leadingComments, parent.parent.loc.start.line);
|
||||
|
||||
case "ArrowFunctionExpression":
|
||||
case "FunctionExpression":
|
||||
|
||||
if (parent.type !== "CallExpression" && parent.type !== "NewExpression") {
|
||||
while (parent && !parent.leadingComments && !/Function/.test(parent.type) && parent.type !== "MethodDefinition" && parent.type !== "Property") {
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
return parent && (parent.type !== "FunctionDeclaration") ? findJSDocComment(parent.leadingComments, parent.loc.start.line) : null;
|
||||
} else if (node.leadingComments) {
|
||||
return findJSDocComment(node.leadingComments, node.loc.start.line);
|
||||
}
|
||||
|
||||
// falls through
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the deepest node containing a range index.
|
||||
* @param {int} index Range index of the desired node.
|
||||
* @returns {ASTNode} The node if found or null if not found.
|
||||
*/
|
||||
getNodeByRangeIndex(index) {
|
||||
let result = null,
|
||||
resultParent = null;
|
||||
const traverser = new Traverser();
|
||||
|
||||
traverser.traverse(this.ast, {
|
||||
enter(node, parent) {
|
||||
if (node.range[0] <= index && index < node.range[1]) {
|
||||
result = node;
|
||||
resultParent = parent;
|
||||
} else {
|
||||
this.skip();
|
||||
}
|
||||
},
|
||||
leave(node) {
|
||||
if (node === result) {
|
||||
this.break();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result ? Object.assign({ parent: resultParent }, result) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines if two tokens have at least one whitespace character
|
||||
* between them. This completely disregards comments in making the
|
||||
* determination, so comments count as zero-length substrings.
|
||||
* @param {Token} first The token to check after.
|
||||
* @param {Token} second The token to check before.
|
||||
* @returns {boolean} True if there is only space between tokens, false
|
||||
* if there is anything other than whitespace between tokens.
|
||||
*/
|
||||
isSpaceBetweenTokens(first, second) {
|
||||
const text = this.text.slice(first.range[1], second.range[0]);
|
||||
|
||||
return /\s/.test(text.replace(/\/\*.*?\*\//g, ""));
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a source text index into a (line, column) pair.
|
||||
* @param {number} index The index of a character in a file
|
||||
* @returns {Object} A {line, column} location object with a 0-indexed column
|
||||
*/
|
||||
getLocFromIndex(index) {
|
||||
if (typeof index !== "number") {
|
||||
throw new TypeError("Expected `index` to be a number.");
|
||||
}
|
||||
|
||||
if (index < 0 || index > this.text.length) {
|
||||
throw new RangeError(`Index out of range (requested index ${index}, but source text has length ${this.text.length}).`);
|
||||
}
|
||||
|
||||
/*
|
||||
* For an argument of this.text.length, return the location one "spot" past the last character
|
||||
* of the file. If the last character is a linebreak, the location will be column 0 of the next
|
||||
* line; otherwise, the location will be in the next column on the same line.
|
||||
*
|
||||
* See getIndexFromLoc for the motivation for this special case.
|
||||
*/
|
||||
if (index === this.text.length) {
|
||||
return { line: this.lines.length, column: this.lines[this.lines.length - 1].length };
|
||||
}
|
||||
|
||||
/*
|
||||
* To figure out which line rangeIndex is on, determine the last index at which rangeIndex could
|
||||
* be inserted into lineIndices to keep the list sorted.
|
||||
*/
|
||||
const lineNumber = lodash.sortedLastIndex(this.lineStartIndices, index);
|
||||
|
||||
return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] };
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a (line, column) pair into a range index.
|
||||
* @param {Object} loc A line/column location
|
||||
* @param {number} loc.line The line number of the location (1-indexed)
|
||||
* @param {number} loc.column The column number of the location (0-indexed)
|
||||
* @returns {number} The range index of the location in the file.
|
||||
*/
|
||||
getIndexFromLoc(loc) {
|
||||
if (typeof loc !== "object" || typeof loc.line !== "number" || typeof loc.column !== "number") {
|
||||
throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties.");
|
||||
}
|
||||
|
||||
if (loc.line <= 0) {
|
||||
throw new RangeError(`Line number out of range (line ${loc.line} requested). Line numbers should be 1-based.`);
|
||||
}
|
||||
|
||||
if (loc.line > this.lineStartIndices.length) {
|
||||
throw new RangeError(`Line number out of range (line ${loc.line} requested, but only ${this.lineStartIndices.length} lines present).`);
|
||||
}
|
||||
|
||||
const lineStartIndex = this.lineStartIndices[loc.line - 1];
|
||||
const lineEndIndex = loc.line === this.lineStartIndices.length ? this.text.length : this.lineStartIndices[loc.line];
|
||||
const positionIndex = lineStartIndex + loc.column;
|
||||
|
||||
/*
|
||||
* By design, getIndexFromLoc({ line: lineNum, column: 0 }) should return the start index of
|
||||
* the given line, provided that the line number is valid element of this.lines. Since the
|
||||
* last element of this.lines is an empty string for files with trailing newlines, add a
|
||||
* special case where getting the index for the first location after the end of the file
|
||||
* will return the length of the file, rather than throwing an error. This allows rules to
|
||||
* use getIndexFromLoc consistently without worrying about edge cases at the end of a file.
|
||||
*/
|
||||
if (
|
||||
loc.line === this.lineStartIndices.length && positionIndex > lineEndIndex ||
|
||||
loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex
|
||||
) {
|
||||
throw new RangeError(`Column number out of range (column ${loc.column} requested, but the length of line ${loc.line} is ${lineEndIndex - lineStartIndex}).`);
|
||||
}
|
||||
|
||||
return positionIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = SourceCode;
|
||||
45
static/js/ketcher2/node_modules/eslint/lib/util/traverser.js
generated
vendored
Normal file
45
static/js/ketcher2/node_modules/eslint/lib/util/traverser.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @fileoverview Wrapper around estraverse
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const estraverse = require("estraverse");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const KEY_BLACKLIST = new Set([
|
||||
"parent",
|
||||
"leadingComments",
|
||||
"trailingComments"
|
||||
]);
|
||||
|
||||
/**
|
||||
* Wrapper around an estraverse controller that ensures the correct keys
|
||||
* are visited.
|
||||
* @constructor
|
||||
*/
|
||||
class Traverser extends estraverse.Controller {
|
||||
traverse(node, visitor) {
|
||||
visitor.fallback = Traverser.getKeys;
|
||||
return super.traverse(node, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the keys to use for traversal.
|
||||
* @param {ASTNode} node The node to read keys from.
|
||||
* @returns {string[]} An array of keys to visit on the node.
|
||||
* @private
|
||||
*/
|
||||
static getKeys(node) {
|
||||
return Object.keys(node).filter(key => !KEY_BLACKLIST.has(key));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Traverser;
|
||||
34
static/js/ketcher2/node_modules/eslint/lib/util/xml-escape.js
generated
vendored
Normal file
34
static/js/ketcher2/node_modules/eslint/lib/util/xml-escape.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @fileoverview XML character escaper
|
||||
* @author George Chung
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the escaped value for a character
|
||||
* @param {string} s string to examine
|
||||
* @returns {string} severity level
|
||||
* @private
|
||||
*/
|
||||
module.exports = function(s) {
|
||||
return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, c => { // eslint-disable-line no-control-regex
|
||||
switch (c) {
|
||||
case "<":
|
||||
return "<";
|
||||
case ">":
|
||||
return ">";
|
||||
case "&":
|
||||
return "&";
|
||||
case "\"":
|
||||
return """;
|
||||
case "'":
|
||||
return "'";
|
||||
default:
|
||||
return `&#${c.charCodeAt(0)};`;
|
||||
}
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user