lab_work3

This commit is contained in:
2025-05-05 17:26:53 +04:00
parent 307c2b89d0
commit edd470aa16
8988 changed files with 857846 additions and 609 deletions

261
node_modules/eslint-plugin-html/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,261 @@
2024-09-21 v8.1.2
- Fix sourceType config for ESLint 9
- Don't require espree directly #271
2024-04-22 v8.1.1
- Fix compatibility with @eslint/config-inspector #267
- Drop Jest #266
- Update dependencies
2024-04-10 v8.1.0
- Introduce the `html/ignore-tags-without-type` setting #249
- Fix files with unknown extensions being considered as XML #257
- Fix plugin applied even if it's not in the configuration #263
- Update dependencies
2024-02-09 v8.0.0
- **Breaking: drop Node 12 and 14 support**
- ESLint 9 support (flat config)
2022-07-25 v7.1.0
- Add support for @html-eslint and @angular-eslint/template plugins #176
2022-07-18 v7.0.0
- **Breaking: drop Node 10 support**
- Allow temporarily disabling ESLint with HTML comments
- Allow configuring which script tag names should be considered as JavaScript #137
2021-09-20 v6.2.0
- Update dependencies
- Fix support for ESLint v8.0.0-beta.2
- Add .riot extension #146
2021-03-08 v6.1.2
- Update htmlparser2 #141
- Update dependencies
2020-11-11 v6.1.1
- Update dependencies
- Move from travis to github actions
2020-09-06 v6.1.0
- Allow dots in extensions #127
2020-08-08 v6.0.3
- Update dependencies
2020-04-15 v6.0.2
- Remove npm-shrinkwrap.json from the npm package #125
2020-04-05 v6.0.1 (the 5th anniversary release)
- Update dependencies
- Run CI against eslint@next
- Add eslint-plugin-php-markup reference to the README
2019-06-26 v6.0.0 (the 666 release)
- **Breaking: drop Node 6 support**
- Fix support for ESLint v6
2019-05-13 v5.0.5
- Fix support for ESLint v6.0.0-alpha.1 (again)
- Improved integration tests
2019-05-12 v5.0.4
- Fix support for ESLint v6.0.0-alpha.1 #117
2019-02-02 v5.0.3
- Fix support for `parserOptions.ecmaFeatures.globalReturn: true` while sharing scope between multiple script tags
2019-02-02 v5.0.2
- Fix support for the --report-unused-disabled-directives option #111
2019-02-02 v5.0.1
- Fix compatibility with ESLint 5.13.0
- Update dependencies
2018-11-11 v5.0.0
- **Breaking: drop Node 4 support**
- **Breaking: don't lint .vue files by default**
- Update dependencies
2018-09-22 v4.0.6
- Ignore script tags with a `src` attribute #102
- More detailed error reporting
2018-06-20 v4.0.5
- Fix typo regression from v4.0.4
2018-06-20 v4.0.4
- Request detailed informations when ESLint is not found
2018-04-11 v4.0.3
- Prevent patching ESLint multiple times #89
2018-01-24 v4.0.2
- Fix compatibility with tslint #85
2017-11-22 v4.0.1
- Fix processing files after processing a HTML file without script tag #82
2017-11-12 v4.0.0
- **Breaking: drop ESLint < 4.7 support**
- **Breaking: Non-module script tags are sharing the global scope** #66
- Lint script tags with `type="module"` by default
2017-09-16 v3.2.2
- Fix ESLint 4.7 support
2017-09-03 v3.2.1
- Fix ESLint 4.6 support #77
2017-08-12 v3.2.0
- improve compatibility with the `prettier` plugin by ignoring the first empty script line #76
- fix compatibility with the `eslint-comments` plugin #70
- add some _Troubleshooting_ documentation about linting template markup and Vue files
2017-07-18 v3.1.1
- Fix node 4 support #71 #72
2017-07-11 v3.1.0
- Remap messages "source" property to fix custom formatters support #69
2017-06-12 v3.0.0 [migration guide](MIGRATION_TO_V3.md)
- **Breaking: lint script tags separately** #49 #55 #56
- ESLint 4 support #57
- Support nested settings in a "html" object #58
2017-05-06 v2.0.3
- No change, new version to work around a publish issue
2017-05-06 v2.0.2
- Support self-closing script tags in XHTML #52
- Fix tests for ESLint 4.0.0-alpha.{0-2}
2017-02-16 v2.0.1
- Support for empty filenames #48
- Support for empty files #46
2017-01-25 v2.0.0
- **Breaking: drop `html/xml-mode` setting**
- `eslint --fix` support #23
- Allow configuring HTML and XML extensions via ESLint config
- Allow configuring JS MIME types via ESLint config
- Report correct end locations of error messages
- Report correct fix ranges of error messages
2016-11-18 v1.7.0
- Ignore all warnings for non-script lines #37
2016-11-05 v1.6.0
- Patch all loaded eslint packages #28
2016-10-23 v1.5.5
- Fix typo in handlebars extension #36
2016-10-22 v1.5.4
- Support `.nunjucks` files #35
2016-09-24 v1.5.3
- Fix tests for ESLint 3.6.0 #32
- Support `.we` files #30
2016-08-06 v1.5.2
- Laxer way to retrieve the eslint package #27
- Support `.erb` files #26
- Support `.tag` files #25
2016-05-22 v1.5.1
- Republish v1.5.0 on NPM, files were missing because of npm/npm#5082
2016-05-22 v1.5.0
- Support `.handlebars` files
- Introduce the `html/xml-mode` setting and parse XML files as XML #20
- Support `.twig` files #21
- Support the `text/ecmascript-6` mime type #17
2016-02-16 v1.4.0
- Support `.php` files
2016-01-27 v1.3.0
- Fix crlf newlines support #16
- Introduce the `html/report-bad-indent` setting
- Introduce the `html/indent` setting
- Support more standard JS MIME types #15
2016-01-15 v1.2.0
- Support the `text/babel` mime type
- Support `.mustache` files #11
2015-11-02 v1.1.0
- Stop non-JS lines breaking `no-multiple-empty-lines` #8
2015-08-22 v1.0.4
- Check if there is some lines before striping the last line spaces #7
2015-08-17 v1.0.3
- Support `.hbs` files
2015-06-30 v1.0.2
- Support `.vue` files #4
2015-04-18 v1.0.1
- Fix space eating issue
- Introduce unit tests
2015-04-05 v1.0.0
- Add README
- Initial commit

13
node_modules/eslint-plugin-html/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2016, Benoît Zugmeyer
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

511
node_modules/eslint-plugin-html/README.md generated vendored Normal file
View File

@@ -0,0 +1,511 @@
<div align="center">
<img src="media/logo.svg" width="150" height="150">
<h1>eslint-plugin-html</h1>
<a href="https://www.npmjs.com/package/eslint-plugin-html"><img alt="NPM version" src="https://img.shields.io/npm/v/eslint-plugin-html"></a>
<a href="https://github.com/BenoitZugmeyer/eslint-plugin-html/actions/workflows/tests.yml"><img alt="Tests Status" src="https://img.shields.io/github/actions/workflow/status/BenoitZugmeyer/eslint-plugin-html/tests.yml"></a>
<p>A <a href="http://eslint.org">ESLint</a> plugin to lint and fix inline scripts contained in HTML files.</p>
</div>
- [Usage](#usage)
- [Disabling ESLint](#disabling-eslint)
- [Linting HTML](#linting-html)
- [Multiple scripts tags in a HTML file](#multiple-scripts-tags-in-a-html-file)
- [History](#history)
- [XML support](#xml-support)
- [Settings](#settings)
- [`html/html-extensions`](#htmlhtml-extensions)
- [`html/xml-extensions`](#htmlxml-extensions)
- [`html/indent`](#htmlindent)
- [`html/report-bad-indent`](#htmlreport-bad-indent)
- [`html/javascript-tag-names`](#htmljavascript-tag-names)
- [`html/javascript-mime-types`](#htmljavascript-mime-types)
- [`html/ignore-tags-without-type`](#htmlignore-tags-without-type)
- [Troubleshooting](#troubleshooting)
- [No file linted when running `eslint` on a directory](#no-file-linted-when-running-eslint-on-a-directory)
- [Linting templates (or PHP)](#linting-templates-or-php)
- [Linting VUE files](#linting-vue-files)
- [Migration from older versions](#migration-from-older-versions)
- [To v4](#to-v4)
- [To v3](#to-v3)
- [Credits](#credits)
## Usage
Simply install via `npm install --save-dev eslint-plugin-html` and add the plugin to your ESLint
configuration. See
[ESLint documentation](http://eslint.org/docs/user-guide/configuring#configuring-plugins).
<details open>
<summary>Example with ESLint 9 and above (flat config)</summary>
```javascript
import html from "eslint-plugin-html"
export default [
{
files: ["**/*.html"],
plugins: { html },
},
]
```
</details>
<details>
<summary>Example with ESLint 8 and below</summary>
```json
{
"plugins": ["html"]
}
```
</details>
## Disabling ESLint
To temporarily disable ESLint, use the `<!-- eslint-disable -->` HTML comment. Re-enable it with
`<!-- eslint enable -->`. Example:
```html
<!-- eslint-disable -->
<script>
var foo = 1
</script>
<!-- eslint-enable -->
```
To disable ESLint for the next script tag only, use the `<!-- eslint-disable-next-script -->` HTML
comment. Example:
```html
<!-- eslint-disable-next-script -->
<script>
var foo = 1
</script>
```
Disabled script tags are completely ignored: their content will not be parsed as JavaScript. You can
use this to disable script tags containing template syntax.
## Linting HTML
This plugin focuses on applying ESLint rules on inline scripts contained in HTML. It does not
provide any rule related to HTML. For that, you can use other plugins like
[`@eslint-html`](https://yeonjuan.github.io/html-eslint/) or
[@angular-eslint](https://github.com/angular-eslint/angular-eslint). `eslint-plugin-html` is
compatible with those plugins and can be used along them.
## Multiple scripts tags in a HTML file
When linting a HTML with multiple script tags, this plugin tries to emulate the browser behavior by
sharing the global scope between scripts by default. This behavior doesn't apply to "module"
scripts (ie: `<script type="module">` and most transpiled code), where [each script tag gets its own
top-level scope](http://exploringjs.com/es6/ch_modules.html#_modules).
ESLint has already [an
option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) to tell the parser
if the script are modules. `eslint-plugin-html` will use this option as well to know if the scopes
should be shared (the default) or not. To change this, just set it in your ESLint configuration:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
// ...
languageOptions: {
sourceType: "module",
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"parserOptions": {
"sourceType": "module"
}
}
```
</details>
To illustrate this behavior, consider this HTML extract:
```html
<script>
var foo = 1
</script>
<script>
alert(foo)
</script>
```
This is perfectly valid by default, and the ESLint rules `no-unused-vars` and `no-undef` shouldn't
complain. But if those scripts are considerated as ES modules, `no-unused-vars` should report an
error in the first script, and `no-undef` should report an error in the second script.
### History
In `eslint-plugin-html` v1 and v2, script code were concatenated and linted in a single pass, so
the scope were always shared. This caused [some issues](MIGRATION_TO_V3.md), so in v3 all scripts
were linted separately, and scopes were never shared. In v4, the plugin still lint scripts
separately, but makes sure global variables are declared and used correctly in the non-module case.
## XML support
This plugin parses HTML and XML markup slightly differently, mainly when considering `CDATA`
sections:
- in XML, any data inside a `CDATA` section will be considered as raw text (not XML) and the `CDATA`
delimiter will be droped ;
- in HTML, there is no such thing for `<script>` tags: the `CDATA` delimiter is considered as normal
text and thus, part of the script.
## Settings
> Note: all settings can be written either as `"html/key": value` or in a nested object `"html": { "key": value }`
### `html/html-extensions`
By default, this plugin will only consider files ending with those extensions as HTML: `.erb`,
`.handlebars`, `.hbs`, `.htm`, `.html`, `.mustache`, `.nunjucks`, `.php`, `.tag`, `.twig`, `.we`.
You can set your own list of HTML extensions by using this setting. Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html", "**/*.we"],
plugins: { html },
settings: {
"html/html-extensions": [".html", ".we"], // consider .html and .we files as HTML
},
},
]
```
Note: you need to specify extensions twice, which is not ideal. This should be imporved in the
future.
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/html-extensions": [".html", ".we"] // consider .html and .we files as HTML
}
}
```
</details>
### `html/xml-extensions`
By default, this plugin will only consider files ending with those extensions as XML: `.xhtml`,
`.xml`. You can set your own list of XML extensions by using this setting. Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/xtml-extensions": [".html"], // consider .html files as XML
},
},
]
```
Note: you need to specify extensions twice, which is not ideal. This should be imporved in the
future.
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/xml-extensions": [".html"] // consider .html files as XML
}
}
```
</details>
### `html/indent`
By default, the code between `<script>` tags is dedented according to the first non-empty line. The
setting `html/indent` allows to ensure that every script tags follow an uniform indentation. Like
the `indent` rule, you can pass a number of spaces, or `"tab"` to indent with one tab. Prefix this
value with a `+` to be relative to the `<script>` tag indentation. Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/indent": "0", // code should start at the beginning of the line (no initial indentation).
"html/indent": "+2", // indentation is the <script> indentation plus two spaces.
"html/indent": "tab", // indentation is one tab at the beginning of the line.
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/indent": "0", // code should start at the beginning of the line (no initial indentation).
"html/indent": "+2", // indentation is the <script> indentation plus two spaces.
"html/indent": "tab" // indentation is one tab at the beginning of the line.
}
}
```
</details>
### `html/report-bad-indent`
By default, this plugin won't warn if it encounters a problematic indentation (ex: a line is under
indented). If you want to make sure the indentation is correct, use the `html/report-bad-indent` in
conjunction with the `indent` rule. Pass `"warn"` or `1` to display warnings, `"error"` or `2` to
display errors. Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/report-bad-indent": "error",
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/report-bad-indent": "error"
}
}
```
</details>
### `html/javascript-tag-names`
By default, the code between `<script>` tags is considered as JavaScript. You can customize which
tags should be considered JavaScript by providing one or multiple tag names.
Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/javascript-tag-names": ["script", "customscript"],
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/javascript-tag-names": ["script", "customscript"]
}
}
```
</details>
### `html/javascript-mime-types`
By default, the code between `<script>` tags is considered as JavaScript code only if there is no
`type` attribute or if its value matches the pattern
`(application|text)/(x-)?(javascript|babel|ecmascript-6)` or `module` (case insensitive). You can
customize the types that should be considered as JavaScript by providing one or multiple MIME types.
If a MIME type starts with a `/`, it will be considered as a regular expression. Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/javascript-mime-types": ["text/javascript", "text/jsx"], // also use script tags with a "text/jsx" type attribute
"html/javascript-mime-types": "/^text\\/(javascript|jsx)$/", // same thing
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/javascript-mime-types": ["text/javascript", "text/jsx"], // also use script tags with a "text/jsx" type attribute
"html/javascript-mime-types": "/^text\\/(javascript|jsx)$/" // same thing
}
}
```
</details>
### `html/ignore-tags-without-type`
By default, the code between `<script>` tags is considered JavaScript if there is no `type`
attribute. You can set this setting to `true` to ignore script tags without a `type` attribute.
Example:
<details open>
<summary>ESLint 9 and above (flat config)</summary>
```javascript
export default [
{
files: ["**/*.html"],
plugins: { html },
settings: {
"html/ignore-tags-without-type": true,
},
},
]
```
</details>
<details>
<summary>ESLint 8 and below</summary>
```json
{
"plugins": ["html"],
"settings": {
"html/ignore-tags-without-type": true
}
}
```
</details>
## Troubleshooting
### No file linted when running `eslint` on a directory
By default, when executing the `eslint` command on a directory, only `.js` files will be linted. You
will have to specify extra extensions with the `--ext` option. Example: `eslint --ext .html,.js src`
will lint both `.html` and `.js` files in the `src` directory. See [ESLint
documentation](http://eslint.org/docs/user-guide/command-line-interface#ext).
### Linting templates (or PHP)
`eslint-plugin-html` won't evaluate or remove your template markup. If you have template markup in
your script tags, the resulting script may not be valid JavaScript, so `ESLint` will fail to parse
it. Here are some workarounds:
- You can use [HTML comments to disable ESLint](#disabling-eslint) for specific script tags.
- For PHP, you can use
[`eslint-plugin-php-markup`](https://github.com/tengattack/eslint-plugin-php-markup) to lint php
files, it use a same way to process php markup like `eslint-plugin-html`.
- Another possible hacky workaround to make sure the code is valid JavaScript is to put your
template markup inside a comment. When the template is rendered, the generated JS code must start
with a new line, so it will be written below the comment. PHP example:
```html
<script>
var mydata
// <?= "\n mydata = " . json_encode($var) . ";" ?>
console.log(mydata)
</script>
```
### Linting VUE files
Initially, [`eslint-plugin-vue`](https://github.com/vuejs/eslint-plugin-vue) was using
`eslint-plugin-html` to lint code inside script tags. Since v3, `eslint-plugin-vue` is using its
own parser, so it is _incompatible_ with `eslint-plugin-html`. You should use `eslint-plugin-vue`
exclusively and remove `eslint-plugin-html` from your dependencies if you still have it.
## Migration from older versions
### To v4
`eslint-plugin-html` v4 requires at least ESLint v4.7. This is because a lot of internal changes
occured in ESLint v4.7, including a [new API to support autofixing in
preprocessors](https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins).
If you are still using an older version of ESLint, please consider upgrading, or keep using
`eslint-plugin-html` v3.
The big feature (and breaking change) in `eslint-plugin-html` v4 is the ability to choose how [scopes
are shared between script tags in the same HTML file](#multiple-scripts-tags-in-a-html-file).
### To v3
If you are considering upgrading to v3, please read [this guide](MIGRATION_TO_V3.md).
## Credits
A big thank you to [@kuceb](https://github.com/kuceb) for the logo image!

40
node_modules/eslint-plugin-html/package.json generated vendored Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "eslint-plugin-html",
"version": "8.1.2",
"description": "A ESLint plugin to lint and fix inline scripts contained in HTML files.",
"license": "ISC",
"repository": {
"type": "git",
"url": "https://github.com/BenoitZugmeyer/eslint-plugin-html"
},
"homepage": "https://github.com/BenoitZugmeyer/eslint-plugin-html",
"bugs": "https://github.com/BenoitZugmeyer/eslint-plugin-html/issues",
"keywords": [
"eslint-plugin",
"eslintplugin",
"eslint",
"html"
],
"main": "src/index.js",
"engines": {
"node": ">=16.0.0"
},
"dependencies": {
"htmlparser2": "^9.1.0"
},
"devDependencies": {
"@html-eslint/eslint-plugin": "^0.27.0",
"@html-eslint/parser": "^0.27.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"markdown-link-check": "^3.10.2",
"prettier": "^3.2.4",
"semver": "^7.3.2"
},
"scripts": {
"validate": "npm run lint && npm run test",
"test": "node --test",
"lint": "eslint .",
"format": "prettier --check ."
}
}

View File

@@ -0,0 +1,127 @@
"use strict"
const lineEndingsRe = /\r\n|\r|\n/g
function lineStarts(str) {
const result = [0]
lineEndingsRe.lastIndex = 0
while (true) {
const match = lineEndingsRe.exec(str)
if (!match) break
result.push(lineEndingsRe.lastIndex)
}
return result
}
function locationToIndex(location, lineStarts) {
if (
!location.line ||
location.line < 0 ||
!location.column ||
location.column < 0
) {
throw new Error("Invalid location")
}
return lineStarts[location.line - 1] + location.column - 1
}
function indexToLocation(index, lineStarts) {
if (index < 0) throw new Error("Invalid index")
let line = 0
while (line + 1 < lineStarts.length && lineStarts[line + 1] <= index) {
line += 1
}
return {
line: line + 1,
column: index - lineStarts[line] + 1,
}
}
module.exports = class TransformableString {
constructor(original) {
this._original = original
this._blocks = []
this._lineStarts = lineStarts(original)
this._cache = null
}
_compute() {
if (!this._cache) {
let result = ""
let index = 0
for (const block of this._blocks) {
result += this._original.slice(index, block.from) + block.str
index = block.to
}
result += this._original.slice(index)
this._cache = {
lineStarts: lineStarts(result),
result,
}
}
return this._cache
}
getOriginalLine(n) {
if (n < 1 || n > this._lineStarts.length) {
throw new Error("Invalid line number")
}
return this._original
.slice(this._lineStarts[n - 1], this._lineStarts[n])
.replace(lineEndingsRe, "")
}
toString() {
return this._compute().result
}
replace(from, to, str) {
this._cache = null
if (from > to || from < 0 || to > this._original.length) {
throw new Error("Invalid slice indexes")
}
const newBlock = { from, to, str }
if (
!this._blocks.length ||
this._blocks[this._blocks.length - 1].to <= from
) {
this._blocks.push(newBlock)
} else {
const index = this._blocks.findIndex((other) => other.to > from)
if (this._blocks[index].from < to) throw new Error("Can't replace slice")
this._blocks.splice(index, 0, newBlock)
}
}
originalIndex(index) {
let block
for (block of this._blocks) {
if (index < block.from) break
if (index < block.from + block.str.length) {
return
} else {
index += block.to - block.from - block.str.length
}
}
if (index < 0 || index > this._original.length) {
throw new Error("Invalid index")
}
if (index == this._original.length) {
if (block.to && block.to === this._original.length) {
return block.from + block.str.length
}
return this._original.length
}
return index
}
originalLocation(location) {
const index = locationToIndex(location, this._compute().lineStarts)
const originalIndex = this.originalIndex(index)
if (originalIndex !== undefined) {
return indexToLocation(originalIndex, this._lineStarts)
}
}
}

261
node_modules/eslint-plugin-html/src/extract.js generated vendored Normal file
View File

@@ -0,0 +1,261 @@
"use strict"
const htmlparser = require("htmlparser2")
const TransformableString = require("./TransformableString")
const NO_IGNORE = 0
const IGNORE_NEXT = 1
const IGNORE_UNTIL_ENABLE = 2
function iterateScripts(code, xmlMode, options, onChunk) {
if (!code) return
const isJavaScriptMIMEType = options.isJavaScriptMIMEType || (() => true)
const javaScriptTagNames = options.javaScriptTagNames || ["script"]
const ignoreTagsWithoutType = options.ignoreTagsWithoutType || false
let index = 0
let inScript = false
let cdata = []
let ignoreState = NO_IGNORE
const chunks = []
function pushChunk(type, end) {
chunks.push({ type, start: index, end, cdata })
cdata = []
index = end
}
const parser = new htmlparser.Parser(
{
onopentag(name, attrs) {
// Test if current tag is a valid <script> tag.
if (!javaScriptTagNames.includes(name)) {
return
}
if (attrs.type) {
if (!isJavaScriptMIMEType(attrs.type)) {
return
}
} else if (ignoreTagsWithoutType) {
return
}
if (attrs.src) {
return
}
if (ignoreState === IGNORE_NEXT) {
ignoreState = NO_IGNORE
return
}
if (ignoreState === IGNORE_UNTIL_ENABLE) {
return
}
inScript = true
pushChunk("html", parser.endIndex + 1)
},
oncdatastart() {
cdata.push(
{
start: parser.startIndex,
end: parser.startIndex + 9,
},
{
start: parser.endIndex - 2,
end: parser.endIndex + 1,
}
)
},
onclosetag(name) {
if (!javaScriptTagNames.includes(name) || !inScript) {
return
}
inScript = false
if (parser.startIndex < chunks[chunks.length - 1].end) {
// The parser didn't move its index after the previous chunk emited. It occurs on
// self-closing tags (xml mode). Just ignore this script.
return
}
pushChunk("script", parser.startIndex)
},
ontext() {
if (!inScript) {
return
}
pushChunk("script", parser.endIndex + 1)
},
oncomment(comment) {
comment = comment.trim()
if (comment === "eslint-disable") {
ignoreState = IGNORE_UNTIL_ENABLE
} else if (comment === "eslint-enable") {
ignoreState = NO_IGNORE
} else if (comment === "eslint-disable-next-script") {
ignoreState = IGNORE_NEXT
}
},
},
{
xmlMode: xmlMode === true,
}
)
parser.parseComplete(code)
pushChunk("html", parser.endIndex + 1)
{
const emitChunk = () => {
const cdata = []
for (let i = startChunkIndex; i < index; i += 1) {
cdata.push.apply(cdata, chunks[i].cdata)
}
onChunk({
type: chunks[startChunkIndex].type,
start: chunks[startChunkIndex].start,
end: chunks[index - 1].end,
cdata,
})
}
let startChunkIndex = 0
let index
for (index = 1; index < chunks.length; index += 1) {
if (chunks[startChunkIndex].type === chunks[index].type) continue
emitChunk()
startChunkIndex = index
}
emitChunk()
}
}
function computeIndent(descriptor, previousHTML, slice) {
if (!descriptor) {
const indentMatch = /[\n\r]+([ \t]*)/.exec(slice)
return indentMatch ? indentMatch[1] : ""
}
if (descriptor.relative) {
return previousHTML.match(/([^\n\r]*)<[^<]*$/)[1] + descriptor.spaces
}
return descriptor.spaces
}
function* dedent(indent, slice) {
let hadNonEmptyLine = false
const re = /(\r\n|\n|\r)([ \t]*)(.*)/g
let lastIndex = 0
while (true) {
const match = re.exec(slice)
if (!match) break
const newLine = match[1]
const lineIndent = match[2]
const lineText = match[3]
const isEmptyLine = !lineText
const isFirstNonEmptyLine = !isEmptyLine && !hadNonEmptyLine
const badIndentation =
// Be stricter on the first line
isFirstNonEmptyLine
? indent !== lineIndent
: lineIndent.indexOf(indent) !== 0
if (!badIndentation) {
lastIndex = match.index + newLine.length + indent.length
// Remove the first line if it is empty
const fromIndex = match.index === 0 ? 0 : match.index + newLine.length
yield {
type: "dedent",
from: fromIndex,
to: lastIndex,
}
} else if (isEmptyLine) {
yield {
type: "empty",
}
} else {
yield {
type: "bad-indent",
}
}
if (!isEmptyLine) {
hadNonEmptyLine = true
}
}
const endSpaces = slice.slice(lastIndex).match(/[ \t]*$/)[0].length
if (endSpaces) {
yield {
type: "dedent",
from: slice.length - endSpaces,
to: slice.length,
}
}
}
function extract(code, xmlMode, options) {
const badIndentationLines = []
const codeParts = []
let lineNumber = 1
let previousHTML = ""
iterateScripts(code, xmlMode, options, (chunk) => {
const slice = code.slice(chunk.start, chunk.end)
if (chunk.type === "html") {
const match = slice.match(/\r\n|\n|\r/g)
if (match) lineNumber += match.length
previousHTML = slice
} else if (chunk.type === "script") {
const transformedCode = new TransformableString(code)
let indentSlice = slice
for (const cdata of chunk.cdata) {
transformedCode.replace(cdata.start, cdata.end, "")
if (cdata.end === chunk.end) {
indentSlice = code.slice(chunk.start, cdata.start)
}
}
transformedCode.replace(0, chunk.start, "")
transformedCode.replace(chunk.end, code.length, "")
for (const action of dedent(
computeIndent(options.indent, previousHTML, indentSlice),
indentSlice
)) {
lineNumber += 1
if (action.type === "dedent") {
transformedCode.replace(
chunk.start + action.from,
chunk.start + action.to,
""
)
} else if (action.type === "bad-indent") {
badIndentationLines.push(lineNumber)
}
}
codeParts.push(transformedCode)
}
})
return {
code: codeParts,
badIndentationLines,
hasBOM: code.startsWith("\uFEFF"),
}
}
module.exports = extract

25
node_modules/eslint-plugin-html/src/getFileMode.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
"use strict"
module.exports = function getMode(pluginSettings, filenameOrOptions) {
const filename =
typeof filenameOrOptions === "object"
? filenameOrOptions.filename
: filenameOrOptions
if (!filename) {
return
}
if (pluginSettings.htmlExtensions.some(hasExtension)) {
return "html"
}
if (pluginSettings.xmlExtensions.some(hasExtension)) {
return "xml"
}
function hasExtension(extension) {
if (!extension.startsWith(".")) {
extension = `.${extension}`
}
return filename.endsWith(extension)
}
}

82
node_modules/eslint-plugin-html/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,82 @@
"use strict"
const path = require("path")
const { createVerifyPatch } = require("./verifyPatch")
const {
createVerifyWithFlatConfigPatch,
} = require("./verifyWithFlatConfigPatch")
const pluginReference = require("./pluginReference")
module.exports = pluginReference
const LINTER_ISPATCHED_PROPERTY_NAME =
"__eslint-plugin-html-verify-function-is-patched"
// Disclaimer:
//
// This is not a long term viable solution. ESLint needs to improve its processor API to
// provide access to the configuration before actually preprocess files, but it's not
// planed yet. This solution is quite ugly but shouldn't alter eslint process.
//
// Related github issues:
// https://github.com/eslint/eslint/issues/3422
// https://github.com/eslint/eslint/issues/4153
const needles = [
path.join("lib", "linter", "linter.js"), // ESLint 6+
path.join("lib", "linter.js"), // ESLint 5-
]
iterateESLintModules(patch)
function iterateESLintModules(fn) {
let found = false
for (const key in require.cache) {
if (!needles.some((needle) => key.endsWith(needle))) continue
const module = require.cache[key]
if (module && module.exports) {
fn(module)
found = true
}
}
if (!found) {
console.warn(
`⚠ eslint-plugin-html warning: ESLint is not loaded, HTML files will fail to lint. If you don't intend to lint HTML files, you can safely ignore this warning. If you think this is a bug, please file a report at https://github.com/BenoitZugmeyer/eslint-plugin-html/issues`
)
}
}
function patch(module) {
const Linter = getLinterFromModule(module)
// ignore if verify function is already been patched sometime before
if (Linter[LINTER_ISPATCHED_PROPERTY_NAME] === true) {
return
}
Linter[LINTER_ISPATCHED_PROPERTY_NAME] = true
const verifyMethodName = Linter.prototype._verifyWithoutProcessors
? "_verifyWithoutProcessors" // ESLint 6+
: "verify" // ESLint 5-
const verify = Linter.prototype[verifyMethodName]
Linter.prototype[verifyMethodName] = createVerifyPatch(verify)
const verifyWithFlatConfig =
Linter.prototype._verifyWithFlatConfigArrayAndWithoutProcessors
Linter.prototype._verifyWithFlatConfigArrayAndWithoutProcessors =
createVerifyWithFlatConfigPatch(module, verifyWithFlatConfig)
}
function getLinterFromModule(module) {
const Linter = module.exports.Linter
? module.exports.Linter // ESLint 6+
: module.exports // ESLint 5-
if (
typeof Linter === "function" &&
typeof Linter.prototype.verify === "function"
) {
return Linter
}
}

View File

@@ -0,0 +1 @@
module.exports = {}

63
node_modules/eslint-plugin-html/src/remapMessages.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
module.exports = { remapMessages }
function remapMessages(messages, hasBOM, codePart) {
const newMessages = []
for (const message of messages) {
if (remapMessage(message, hasBOM, codePart)) {
newMessages.push(message)
}
}
return newMessages
}
function remapMessage(message, hasBOM, codePart) {
if (!message.line || !message.column) {
// Some messages apply to the whole file instead of a particular code location. In particular:
// * @typescript-eslint/parser may send messages with no line/column
// * eslint-plugin-eslint-comments send messages with column=0 to bypass ESLint ignore comments.
// See https://github.com/BenoitZugmeyer/eslint-plugin-html/issues/70
// For now, just include them in the output. In the future, we should make sure those messages
// are not print twice.
return true
}
const location = codePart.originalLocation({
line: message.line,
column: message.column,
})
// Ignore messages if they were in transformed code
if (!location) {
return false
}
Object.assign(message, location)
message.source = codePart.getOriginalLine(location.line)
// Map fix range
if (message.fix && message.fix.range) {
const bomOffset = hasBOM ? -1 : 0
message.fix.range = [
codePart.originalIndex(message.fix.range[0]) + bomOffset,
// The range end is exclusive, meaning it should replace all characters with indexes from
// start to end - 1. We have to get the original index of the last targeted character.
codePart.originalIndex(message.fix.range[1] - 1) + 1 + bomOffset,
]
}
// Map end location
if (message.endLine && message.endColumn) {
const endLocation = codePart.originalLocation({
line: message.endLine,
column: message.endColumn,
})
if (endLocation) {
message.endLine = endLocation.line
message.endColumn = endLocation.column
}
}
return true
}

122
node_modules/eslint-plugin-html/src/settings.js generated vendored Normal file
View File

@@ -0,0 +1,122 @@
"use strict"
const oneLine = require("./utils").oneLine
const defaultHTMLExtensions = [
".erb",
".handlebars",
".hbs",
".htm",
".html",
".mustache",
".nunjucks",
".php",
".tag",
".riot",
".twig",
".we",
]
const defaultXMLExtensions = [".xhtml", ".xml"]
function filterOut(array, excludeArray) {
if (!excludeArray) return array
return array.filter((item) => excludeArray.indexOf(item) < 0)
}
function compileRegExp(re) {
const tokens = re.split("/")
if (tokens.shift()) {
// Ignore first token
throw new Error(`Invalid regexp: ${re}`)
}
const flags = tokens.pop()
return new RegExp(tokens.join("/"), flags)
}
function getSetting(settings, name) {
if (typeof settings.html === "object" && name in settings.html) {
return settings.html[name]
}
return settings[`html/${name}`]
}
function getSettings(settings) {
const htmlExtensions =
getSetting(settings, "html-extensions") ||
filterOut(defaultHTMLExtensions, getSetting(settings, "xml-extensions"))
const xmlExtensions =
getSetting(settings, "xml-extensions") ||
filterOut(defaultXMLExtensions, getSetting(settings, "html-extensions"))
const javaScriptTagNames = getSetting(settings, "javascript-tag-names") || [
"script",
]
const ignoreTagsWithoutType =
getSetting(settings, "ignore-tags-without-type") || false
let reportBadIndent
switch (getSetting(settings, "report-bad-indent")) {
case undefined:
case false:
case 0:
case "off":
reportBadIndent = 0
break
case true:
case 1:
case "warn":
reportBadIndent = 1
break
case 2:
case "error":
reportBadIndent = 2
break
default:
throw new Error(
oneLine`
Invalid value for html/report-bad-indent,
expected one of 0, 1, 2, "off", "warn" or "error"
`
)
}
const parsedIndent = /^(\+)?(tab|\d+)$/.exec(getSetting(settings, "indent"))
const indent = parsedIndent && {
relative: parsedIndent[1] === "+",
spaces: parsedIndent[2] === "tab" ? "\t" : " ".repeat(parsedIndent[2]),
}
const rawJavaScriptMIMETypes = getSetting(settings, "javascript-mime-types")
const javaScriptMIMETypes = rawJavaScriptMIMETypes
? (Array.isArray(rawJavaScriptMIMETypes)
? rawJavaScriptMIMETypes
: [rawJavaScriptMIMETypes]
).map((s) => (s.startsWith("/") ? compileRegExp(s) : s))
: [
/^(application|text)\/(x-)?(javascript|babel|ecmascript-6)$/i,
/^module$/i,
]
function isJavaScriptMIMEType(type) {
return javaScriptMIMETypes.some((o) =>
typeof o === "string" ? type === o : o.test(type)
)
}
return {
htmlExtensions,
xmlExtensions,
javaScriptTagNames,
indent,
reportBadIndent,
isJavaScriptMIMEType,
ignoreTagsWithoutType,
}
}
module.exports = {
getSettings,
}

32
node_modules/eslint-plugin-html/src/utils.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
"use strict"
function oneLine(parts) {
return parts
.map((part, index) => {
return index > 0 ? arguments[index - 1] + part : part
})
.join("")
.trim()
.split("\n")
.map((line) => line.trim())
.join(" ")
}
function splatSet(items) {
const set = new Set()
splatSetRec(items, set)
return set
}
function splatSetRec(items, set) {
if (items instanceof Array || items instanceof Set) {
for (const item of items) splatSetRec(item, set)
} else {
set.add(items)
}
}
module.exports = {
oneLine,
splatSet,
}

162
node_modules/eslint-plugin-html/src/verifyPatch.js generated vendored Normal file
View File

@@ -0,0 +1,162 @@
const getSettings = require("./settings").getSettings
const getFileMode = require("./getFileMode")
const extract = require("./extract")
const { remapMessages } = require("./remapMessages")
const { verifyWithSharedScopes } = require("./verifyWithSharedScopes")
const PREPARE_RULE_NAME = "__eslint-plugin-html-prepare"
module.exports = { createVerifyPatch }
function createVerifyPatch(verify) {
return function (textOrSourceCode, config, filenameOrOptions, saveState) {
const callOriginalVerify = () =>
verify.call(this, textOrSourceCode, config, filenameOrOptions, saveState)
if (typeof config.extractConfig === "function") {
return callOriginalVerify()
}
const pluginSettings = getSettings(config.settings || {})
const mode = getFileMode(pluginSettings, filenameOrOptions)
if (!mode || typeof textOrSourceCode !== "string") {
return callOriginalVerify()
}
let messages
;[messages, config] = verifyExternalHtmlPlugin(config, callOriginalVerify)
if (config.parser && config.parser.id === "@html-eslint/parser") {
messages.push(...callOriginalVerify())
const rules = {}
for (const name in config.rules) {
if (!name.startsWith("@html-eslint/")) {
rules[name] = config.rules[name]
}
}
config = editConfig(config, {
parser: null,
rules,
})
}
const extractResult = extract(
textOrSourceCode,
mode === "xml",
pluginSettings
)
if (pluginSettings.reportBadIndent) {
messages.push(
...extractResult.badIndentationLines.map((line) => ({
message: "Bad line indentation.",
line,
column: 1,
ruleId: "(html plugin)",
severity: pluginSettings.reportBadIndent,
}))
)
}
// Save code parts parsed source code so we don't have to parse it twice
const sourceCodes = new WeakMap()
const verifyCodePart = (codePart, { prepare, ignoreRules } = {}) => {
this.defineRule(PREPARE_RULE_NAME, (context) => {
sourceCodes.set(codePart, context.getSourceCode())
return {
Program(program) {
if (prepare) {
prepare(context, program)
}
},
}
})
const localMessages = verify.call(
this,
sourceCodes.get(codePart) || String(codePart),
editConfig(config, {
rules: Object.assign(
{ [PREPARE_RULE_NAME]: "error" },
!ignoreRules && config.rules
),
}),
ignoreRules && typeof filenameOrOptions === "object"
? Object.assign({}, filenameOrOptions, {
reportUnusedDisableDirectives: false,
})
: filenameOrOptions,
saveState
)
messages.push(
...remapMessages(localMessages, extractResult.hasBOM, codePart)
)
}
const parserOptions = config.parserOptions || {}
if (parserOptions.sourceType === "module") {
for (const codePart of extractResult.code) {
verifyCodePart(codePart)
}
} else {
verifyWithSharedScopes(extractResult.code, verifyCodePart, parserOptions)
}
messages.sort((ma, mb) => ma.line - mb.line || ma.column - mb.column)
return messages
}
}
function editConfig(config, { parser = config.parser, rules = config.rules }) {
return {
...config,
parser,
rules,
}
}
const externalHtmlPluginPrefixes = [
"@html-eslint/",
"@angular-eslint/template-",
]
function getParserId(config) {
if (!config.parser) {
return
}
if (typeof config.parser === "string") {
// old versions of ESLint (ex: 4.7)
return config.parser
}
return config.parser.id
}
function verifyExternalHtmlPlugin(config, callOriginalVerify) {
const parserId = getParserId(config)
const externalHtmlPluginPrefix =
parserId &&
externalHtmlPluginPrefixes.find((prefix) => parserId.startsWith(prefix))
if (!externalHtmlPluginPrefix) {
return [[], config]
}
const rules = {}
for (const name in config.rules) {
if (!name.startsWith(externalHtmlPluginPrefix)) {
rules[name] = config.rules[name]
}
}
return [
callOriginalVerify(),
editConfig(config, {
parser: null,
rules,
}),
]
}

View File

@@ -0,0 +1,172 @@
const getSettings = require("./settings").getSettings
const getFileMode = require("./getFileMode")
const extract = require("./extract")
const { verifyWithSharedScopes } = require("./verifyWithSharedScopes")
const { remapMessages } = require("./remapMessages")
const pluginReference = require("./pluginReference")
const PREPARE_RULE_NAME = "__eslint-plugin-html-prepare"
const PREPARE_PLUGIN_NAME = "__eslint-plugin-html-prepare"
module.exports = { createVerifyWithFlatConfigPatch }
function createVerifyWithFlatConfigPatch(eslintModule, verifyWithFlatConfig) {
return function (textOrSourceCode, providedConfig, providedOptions) {
const callOriginalVerify = () =>
verifyWithFlatConfig.call(
this,
textOrSourceCode,
providedConfig,
providedOptions
)
if (!Object.values(providedConfig.plugins).includes(pluginReference)) {
return callOriginalVerify()
}
const pluginSettings = getSettings(providedConfig.settings || {})
const mode = getFileMode(pluginSettings, providedOptions.filename)
if (!mode) {
return callOriginalVerify()
}
let messages
;[messages, providedConfig] = verifyExternalHtmlPlugin(
eslintModule,
providedConfig,
callOriginalVerify
)
const extractResult = extract(
textOrSourceCode,
mode === "xml",
pluginSettings
)
if (pluginSettings.reportBadIndent) {
messages.push(
...extractResult.badIndentationLines.map((line) => ({
message: "Bad line indentation.",
line,
column: 1,
ruleId: "(html plugin)",
severity: pluginSettings.reportBadIndent,
}))
)
}
// Save code parts parsed source code so we don't have to parse it twice
const sourceCodes = new WeakMap()
const verifyCodePart = (codePart, { prepare, ignoreRules } = {}) => {
providedConfig.plugins[PREPARE_PLUGIN_NAME] = {
rules: {
[PREPARE_RULE_NAME]: {
create(context) {
sourceCodes.set(codePart, context.getSourceCode())
return {
Program(program) {
if (prepare) {
prepare(context, program)
}
},
}
},
},
},
}
const localMessages = verifyWithFlatConfig.call(
this,
sourceCodes.get(codePart) || String(codePart),
{
...providedConfig,
rules: Object.assign(
{ [`${PREPARE_PLUGIN_NAME}/${PREPARE_RULE_NAME}`]: "error" },
!ignoreRules && providedConfig.rules
),
},
ignoreRules
? {
...providedOptions,
reportUnusedDisableDirectives: false,
}
: providedOptions
)
messages.push(
...remapMessages(localMessages, extractResult.hasBOM, codePart)
)
}
const languageOptions = providedConfig.languageOptions || {}
const parserOptions = languageOptions.parserOptions || {}
const sourceType = languageOptions.sourceType || parserOptions.sourceType
if (sourceType === "module") {
for (const codePart of extractResult.code) {
verifyCodePart(codePart)
}
} else {
verifyWithSharedScopes(extractResult.code, verifyCodePart, parserOptions)
}
messages.sort((ma, mb) => ma.line - mb.line || ma.column - mb.column)
return messages
}
}
const externalHtmlPlugins = [
{ parser: "@html-eslint/parser", plugin: "@html-eslint/eslint-plugin" },
]
function tryRequire(name) {
try {
return require(name)
} catch {
return undefined
}
}
function findExternalHtmlPluginName(config) {
if (!config.languageOptions || !config.languageOptions.parser) {
return
}
for (const { parser, plugin } of externalHtmlPlugins) {
let parserModule = tryRequire(parser)
if (config.languageOptions.parser === parserModule) {
const pluginModule = tryRequire(plugin)
for (const [name, plugin] of Object.entries(config.plugins)) {
if (plugin === pluginModule) {
return name
}
}
}
}
}
function verifyExternalHtmlPlugin(eslintModule, config, callOriginalVerify) {
const htmlPluginName = findExternalHtmlPluginName(config)
if (!htmlPluginName) {
return [[], config]
}
const rules = {}
for (const name in config.rules) {
if (!name.startsWith(htmlPluginName + "/")) {
rules[name] = config.rules[name]
}
}
return [
callOriginalVerify(),
{
...config,
languageOptions: {
...config.languageOptions,
parser: eslintModule.require("espree"),
},
rules,
},
]
}

View File

@@ -0,0 +1,81 @@
const { splatSet } = require("./utils")
module.exports = { verifyWithSharedScopes }
function verifyWithSharedScopes(codeParts, verifyCodePart, parserOptions) {
// First pass: collect needed globals and declared globals for each script tags.
const firstPassValues = []
for (const codePart of codeParts) {
verifyCodePart(codePart, {
prepare(context, program) {
const globalScope = getGlobalScope(context, program)
// See https://github.com/eslint/eslint/blob/4b267a5c8a42477bb2384f33b20083ff17ad578c/lib/rules/no-redeclare.js#L67-L78
let scopeForDeclaredGlobals
if (
parserOptions.ecmaFeatures &&
parserOptions.ecmaFeatures.globalReturn
) {
scopeForDeclaredGlobals = globalScope.childScopes[0]
} else {
scopeForDeclaredGlobals = globalScope
}
firstPassValues.push({
codePart,
exportedGlobals: globalScope.through.map(
(node) => node.identifier.name
),
declaredGlobals: scopeForDeclaredGlobals.variables.map(
(variable) => variable.name
),
})
},
ignoreRules: true,
})
}
// Second pass: declare variables for each script scope, then run eslint.
for (let i = 0; i < firstPassValues.length; i += 1) {
verifyCodePart(firstPassValues[i].codePart, {
prepare(context, program) {
const exportedGlobals = splatSet(
firstPassValues
.slice(i + 1)
.map((nextValues) => nextValues.exportedGlobals)
)
for (const name of exportedGlobals)
markGlobalVariableAsUsed(context, program, name)
const declaredGlobals = splatSet(
firstPassValues
.slice(0, i)
.map((previousValues) => previousValues.declaredGlobals)
)
const scope = getGlobalScope(context, program)
scope.through = scope.through.filter((variable) => {
return !declaredGlobals.has(variable.identifier.name)
})
},
})
}
}
function markGlobalVariableAsUsed(context, program, name) {
const sourceCode = context.getSourceCode()
if (sourceCode.markVariableAsUsed) {
sourceCode.markVariableAsUsed(name, program)
} else {
context.markVariableAsUsed(name)
}
}
function getGlobalScope(context, program) {
const sourceCode = context.getSourceCode()
if (sourceCode.getScope) {
// eslint 9+
return sourceCode.getScope(program)
}
return context.getScope()
}