Skip to content

Commit

Permalink
New: eslint-visitor-keys (#1)
Browse files Browse the repository at this point in the history
* New: eslint-visitor-keys

* fix license field of package.json

* update for review

- fix the doc of `getKeys`
- clarify the order of keys for `unionWith`
  • Loading branch information
mysticatea committed Nov 16, 2017
1 parent a1a48b8 commit a5a026b
Show file tree
Hide file tree
Showing 11 changed files with 551 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "eslint",
"env": {
"es6": true,
"node": true
}
}
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.nyc_output
/.vscode
/coverage
/node_modules
/test.*
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sudo: false

language: node_js
node_js:
- "4.0.0"
- "4"
- "6"
- "8"
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# eslint-visitor-keys

[![npm version](https://img.shields.io/npm/v/eslint-visitor-keys.svg)](https://www.npmjs.com/package/eslint-visitor-keys)
[![Downloads/month](https://img.shields.io/npm/dm/eslint-visitor-keys.svg)](http://www.npmtrends.com/eslint-visitor-keys)
[![Build Status](https://travis-ci.org/eslint/eslint-visitor-keys.svg?branch=master)](https://travis-ci.org/eslint/eslint-visitor-keys)
[![Dependency Status](https://david-dm.org/eslint/eslint-visitor-keys.svg)](https://david-dm.org/eslint/eslint-visitor-keys)

Constants and utilities about visitor keys to traverse AST.

## 💿 Installation

Use [npm] to install.

```bash
$ npm install eslint-visitor-keys
```

### Requirements

- [Node.js] 4.0.0 or later.

## 📖 Usage

```js
const evk = require("eslint-visitor-keys")
```

### evk.KEYS

> type: `{ [type: string]: string[] | undefined }`
Visitor keys. This keys are frozen.

This is an object. Keys are the type of [ESTree] nodes. Their values are an array of property names which have child nodes.

For example:

```
console.log(evk.KEYS.AssignmentExpression) // → ["left", "right"]
```

### evk.getKeys(node)

> type: `(node: object) => string[]`
Get the visitor keys of a given AST node.

This is similar to `Object.keys(node)` of ES Standard, but some keys are excluded: `parent`, `leadingComments`, `trailingComments`, and names which start with `_`.

This will be used to traverse unknown nodes.

For example:

```
const node = {
type: "AssignmentExpression",
left: { type: "Identifier", name: "foo" },
right: { type: "Literal", value: 0 }
}
console.log(evk.getKeys(node)) // → ["type", "left", "right"]
```

### evk.unionWith(additionalKeys)

> type: `(additionalKeys: object) => { [type: string]: string[] | undefined }`
Make the union set with `evk.KEYS` and the given keys.

- The order of keys is, `additionalKeys` is at first, then `evk.KEYS` is concatenated after that.
- It removes duplicated keys as keeping the first one.

For example:

```
console.log(evk.unionWith({
MethodDefinition: ["decorators"]
})) // → { ..., MethodDefinition: ["decorators", "key", "value"], ... }
```

## 📰 Change log

See [GitHub releases](https://github.com/eslint/eslint-visitor-keys/releases).

## 🍻 Contributing

Welcome. See [ESLint contribution guidelines](https://eslint.org/docs/developer-guide/contributing/).

### Development commands

- `npm test` runs tests and measures code coverage.
- `npm run lint` checks source codes with ESLint.
- `npm run coverage` opens the code coverage report of the previous test with your default browser.
- `npm run release` publishes this package to [npm] registory.


[npm]: https://www.npmjs.com/
[Node.js]: https://nodejs.org/en/
[ESTree]: https://github.com/estree/estree
81 changes: 81 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* @author Toru Nagashima <https://github.com/mysticatea>
* See LICENSE file in root directory for full license.
*/
"use strict";

const KEYS = require("./visitor-keys.json");

// Types.
const NODE_TYPES = Object.freeze(Object.keys(KEYS));

// Freeze the keys.
for (const type of NODE_TYPES) {
Object.freeze(KEYS[type]);
}
Object.freeze(KEYS);

// List to ignore keys.
const KEY_BLACKLIST = new Set([
"parent",
"leadingComments",
"trailingComments"
]);

/**
* Check whether a given key should be used or not.
* @param {string} key The key to check.
* @returns {boolean} `true` if the key should be used.
*/
function filterKey(key) {
return !KEY_BLACKLIST.has(key) && key[0] !== "_";
}

//------------------------------------------------------------------------------
// Public interfaces
//------------------------------------------------------------------------------

module.exports = Object.freeze({

/**
* Visitor keys.
* @type {{ [type: string]: string[] | undefined }}
*/
KEYS,

/**
* Get visitor keys of a given node.
* @param {Object} node The AST node to get keys.
* @returns {string[]} Visitor keys of the node.
*/
getKeys(node) {
return Object.keys(node).filter(filterKey);
},

// Disable valid-jsdoc rule because it reports syntax error on the type of @returns.
// eslint-disable-next-line valid-jsdoc
/**
* Make the union set with `KEYS` and given keys.
* @param {Object} additionalKeys The additional keys.
* @returns {{ [type: string]: string[] | undefined }} The union set.
*/
unionWith(additionalKeys) {
const retv = Object.assign({}, KEYS);

for (const type of Object.keys(additionalKeys)) {
if (retv.hasOwnProperty(type)) {
const keys = new Set(additionalKeys[type]);

for (const key of retv[type]) {
keys.add(key);
}

retv[type] = Object.freeze(Array.from(keys));
} else {
retv[type] = Object.freeze(Array.from(additionalKeys[type]));
}
}

return Object.freeze(retv);
}
});

0 comments on commit a5a026b

Please sign in to comment.