[Pkg-javascript-commits] [node-is-reference] 01/02: New upstream version 1.0.0
Julien Puydt
julien.puydt at laposte.net
Mon Jul 3 16:55:29 UTC 2017
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to branch master
in repository node-is-reference.
commit 069ae3d9a7f5573a2da8b1841ab8919184ff4159
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Mon Jul 3 18:34:33 2017 +0200
New upstream version 1.0.0
---
.eslintrc.json | 39 ++++++++++++++++++++++++++++
.gitignore | 2 ++
CHANGELOG.md | 5 ++++
README.md | 61 +++++++++++++++++++++++++++++++++++++++++++
index.js | 38 +++++++++++++++++++++++++++
module.js | 28 ++++++++++++++++++++
package.json | 41 +++++++++++++++++++++++++++++
rollup.config.js | 6 +++++
test/test.js | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 299 insertions(+)
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..6b09cd6
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,39 @@
+{
+ "root": true,
+ "rules": {
+ "indent": [ 2, "tab", { "SwitchCase": 1 } ],
+ "semi": [ 2, "always" ],
+ "keyword-spacing": [ 2, { "before": true, "after": true } ],
+ "space-before-blocks": [ 2, "always" ],
+ "space-before-function-paren": [ 2, "always" ],
+ "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ],
+ "no-cond-assign": 0,
+ "no-unused-vars": 2,
+ "object-shorthand": [ 2, "always" ],
+ "no-const-assign": 2,
+ "no-class-assign": 2,
+ "no-this-before-super": 2,
+ "no-var": 2,
+ "no-unreachable": 2,
+ "valid-typeof": 2,
+ "quote-props": [ 2, "as-needed" ],
+ "one-var": [ 2, "never" ],
+ "prefer-arrow-callback": 2,
+ "prefer-const": [ 2, { "destructuring": "all" } ],
+ "arrow-spacing": 2,
+ "no-inner-declarations": 0
+ },
+ "env": {
+ "es6": true,
+ "browser": true,
+ "node": true,
+ "mocha": true
+ },
+ "extends": [
+ "eslint:recommended"
+ ],
+ "parserOptions": {
+ "ecmaVersion": 6,
+ "sourceType": "module"
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9daa824
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7461c07
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# is-reference changelog
+
+## 1.0.0
+
+* First release
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1989fca
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# is-reference
+
+Utility for determining whether an AST node is a reference.
+
+`foo` is a reference in these cases:
+
+```js
+console.log( foo );
+var foo;
+function foo () {}
+function bar ( foo ) {}
+export { foo as x };
+```
+
+`foo` is *not* a reference in these cases:
+
+```js
+var obj = { foo: 1 };
+console.log( obj.foo );
+export { x as foo };
+```
+
+In all cases, `foo` is an `Identifier` node, but the two kinds must be treated differently for the purposes of scope analysis etc. (The examples are non-exhaustive.)
+
+
+## Installation
+
+```bash
+npm install is-reference
+```
+
+
+## Usage
+
+Example using [Acorn](https://github.com/ternjs/acorn) and [estree-walker](https://github.com/Rich-Harris/estree-walker):
+
+```js
+const { parse } = require( 'acorn' );
+const { walk } = require( 'estree-walker' );
+const isReference = require( 'is-reference' );
+
+const identifiers = [];
+const references = [];
+
+const ast = parse( `var a = b.c;` );
+
+walk( ast, {
+ enter ( node, parent ) {
+ if ( node.type === 'Identifier' ) identifiers.push( node );
+ if ( isReference( node, parent ) ) references.push( node );
+ }
+});
+
+identifiers.forEach( node => console.log( node.name ) ); // a, b, c
+references.forEach( node => console.log( node.name ) ); // a, b
+```
+
+
+## License
+
+MIT
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..f143a39
--- /dev/null
+++ b/index.js
@@ -0,0 +1,38 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global.isReference = factory());
+}(this, (function () { 'use strict';
+
+function isReference ( node, parent ) {
+ if ( node.type === 'MemberExpression' ) {
+ return !node.computed && isReference( node.object, node );
+ }
+
+ if ( node.type === 'Identifier' ) {
+ // the only time we could have an identifier node without a parent is
+ // if it's the entire body of a function without a block statement –
+ // i.e. an arrow function expression like `a => a`
+ if ( !parent ) return true;
+
+ // TODO is this right?
+ if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) {
+ return parent.computed || node === parent.object;
+ }
+
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
+ if ( parent.type === 'Property' ) return parent.computed || node === parent.value;
+
+ // disregard the `bar` in `class Foo { bar () {...} }`
+ if ( parent.type === 'MethodDefinition' ) return false;
+
+ // disregard the `bar` in `export { foo as bar }`
+ if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return;
+
+ return true;
+ }
+}
+
+return isReference;
+
+})));
diff --git a/module.js b/module.js
new file mode 100644
index 0000000..c2e6c89
--- /dev/null
+++ b/module.js
@@ -0,0 +1,28 @@
+export default function isReference ( node, parent ) {
+ if ( node.type === 'MemberExpression' ) {
+ return !node.computed && isReference( node.object, node );
+ }
+
+ if ( node.type === 'Identifier' ) {
+ // the only time we could have an identifier node without a parent is
+ // if it's the entire body of a function without a block statement –
+ // i.e. an arrow function expression like `a => a`
+ if ( !parent ) return true;
+
+ // TODO is this right?
+ if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) {
+ return parent.computed || node === parent.object;
+ }
+
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
+ if ( parent.type === 'Property' ) return parent.computed || node === parent.value;
+
+ // disregard the `bar` in `class Foo { bar () {...} }`
+ if ( parent.type === 'MethodDefinition' ) return false;
+
+ // disregard the `bar` in `export { foo as bar }`
+ if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return;
+
+ return true;
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..06b97ee
--- /dev/null
+++ b/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "is-reference",
+ "version": "1.0.0",
+ "description": "Determine whether an AST node is a reference",
+ "main": "index.js",
+ "module": "module.js",
+ "files": [
+ "index.js",
+ "module.js"
+ ],
+ "scripts": {
+ "test": "mocha",
+ "build": "rollup -c",
+ "pretest": "npm run build",
+ "lint": "eslint module.js",
+ "prepublish": "npm run lint && npm test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/Rich-Harris/is-reference.git"
+ },
+ "keywords": [
+ "ast",
+ "javascript",
+ "estree",
+ "acorn"
+ ],
+ "author": "Rich Harris",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/Rich-Harris/is-reference/issues"
+ },
+ "homepage": "https://github.com/Rich-Harris/is-reference#readme",
+ "devDependencies": {
+ "acorn": "^4.0.4",
+ "eslint": "^3.12.2",
+ "estree-walker": "^0.3.0",
+ "mocha": "^3.2.0",
+ "rollup": "^0.37.2"
+ }
+}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..0171586
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,6 @@
+export default {
+ entry: 'module.js',
+ dest: 'index.js',
+ format: 'umd',
+ moduleName: 'isReference'
+};
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..56f749d
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,79 @@
+const assert = require( 'assert' );
+const { parse } = require( 'acorn' );
+const { walk } = require( 'estree-walker' );
+
+const isReference = require( '../' );
+
+describe( 'is-reference', () => {
+ const positive = {
+ 'simple identifier': `
+ foo;`,
+
+ 'variable declaration': `
+ var foo;`,
+
+ 'function name': `
+ function foo () {}`,
+
+ 'function parameter': `
+ function x ( foo ) {}`,
+
+ 'object pattern': `
+ function x ({ foo }) {}`,
+
+ 'array pattern': `
+ function x ([ foo ]) {}`,
+
+ 'assignment pattern': `
+ function x ( foo = 1 ) {}`,
+
+ 'assignment pattern in object pattern': `
+ function x ({ foo = 42 }) {}`
+ };
+
+ const negative = {
+ 'object literal property': `
+ var obj = { foo: 1 };`,
+
+ 'member expression property': `
+ obj.foo;`
+ };
+
+ describe( 'positive', () => {
+ Object.keys( positive ).forEach( name => {
+ it( name, () => {
+ const code = positive[ name ];
+ const matches = findFooReferences( code );
+
+ assert.equal( matches.size, 1 );
+ });
+ });
+ });
+
+ describe( 'negative', () => {
+ Object.keys( negative ).forEach( name => {
+ it( name, () => {
+ const code = negative[ name ];
+ const matches = findFooReferences( code );
+
+ assert.equal( matches.size, 0 );
+ });
+ });
+ });
+
+ function findFooReferences ( code ) {
+ const ast = parse( code );
+
+ const matches = new Set;
+
+ walk( ast, {
+ enter ( node, parent ) {
+ if ( isReference( node, parent ) && node.name === 'foo' ) {
+ matches.add( node );
+ }
+ }
+ });
+
+ return matches;
+ }
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-is-reference.git
More information about the Pkg-javascript-commits
mailing list