diff --git a/dxr/plugins/js/__init__.py b/dxr/plugins/js/__init__.py index 2e9af9888..efaae3dcf 100644 --- a/dxr/plugins/js/__init__.py +++ b/dxr/plugins/js/__init__.py @@ -5,7 +5,7 @@ from dxr.plugins import Plugin, filters_from_namespace, refs_from_namespace from dxr.filters import LINE from dxr.indexers import QUALIFIED_LINE_NEEDLE -from dxr.plugins.js.indexers import _TreeToIndex +from dxr.plugins.js.indexers import TreeToIndex from dxr.plugins.js.refs import PLUGIN_NAME from dxr.plugins.js import refs, filters @@ -23,7 +23,7 @@ plugin = Plugin( - tree_to_index=_TreeToIndex, + tree_to_index=TreeToIndex, mappings=mappings, refs=refs_from_namespace(refs.__dict__), filters=filters_from_namespace(filters.__dict__), diff --git a/dxr/plugins/js/analyze_js/analyze_file.js b/dxr/plugins/js/analyze_js/analyze_file.js index 93249a9f8..ba5ff6b7b 100644 --- a/dxr/plugins/js/analyze_js/analyze_file.js +++ b/dxr/plugins/js/analyze_js/analyze_file.js @@ -324,6 +324,10 @@ const Analyzer = { this.expression(stmt.value); break; + case "ExportNamedDeclaration": + this.statement(stmt.declaration) + break; + default: console.log(`In ${fileIndex}, Unexpected statement: ${stmt.type} ${JSON.stringify(stmt)}`); break; @@ -478,7 +482,8 @@ const Analyzer = { this.expression(expr.argument); break; - // Why does this show up as both a pattern and an expression? + // We have to repeat this case expression because it can appear as the + // 'value' of an ObjectPattern which is otherwise an expression. case "AssignmentPattern": this.expression(expr.left); this.expression(expr.right); diff --git a/dxr/plugins/js/analyze_js/package.json b/dxr/plugins/js/analyze_js/package.json index 278c5fa21..6ddfd6633 100644 --- a/dxr/plugins/js/analyze_js/package.json +++ b/dxr/plugins/js/analyze_js/package.json @@ -3,7 +3,7 @@ "description": "esprima-based javascript plugin for DXR", "author": "Mozilla", "version": "1.0.0", - "engine": "node >= 0.8.x", + "engine": "node >= 6.0.0", "license": "MIT", "dependencies": { "eslint": "2.9.0", diff --git a/dxr/plugins/js/filters.py b/dxr/plugins/js/filters.py index aabb43a47..5805618df 100644 --- a/dxr/plugins/js/filters.py +++ b/dxr/plugins/js/filters.py @@ -10,13 +10,13 @@ class _QualifiedNameFilter(QualifiedNameFilterBase): class PropFilter(_QualifiedNameFilter): name = 'prop' is_identifier = True - description = Markup('Property definition filter: prop:foo') + description = Markup('JavaScript property definition filter: prop:foo') class PropRefFilter(_QualifiedNameFilter): name = 'prop-ref' is_reference = True - description = 'Reference to object properties' + description = 'References to JavaScript object properties' class VarFilter(_QualifiedNameFilter): diff --git a/dxr/plugins/js/indexers.py b/dxr/plugins/js/indexers.py index f8d60819a..b740a726a 100644 --- a/dxr/plugins/js/indexers.py +++ b/dxr/plugins/js/indexers.py @@ -1,12 +1,11 @@ -from os.path import basename, dirname, relpath, join, exists +from itertools import imap import json import subprocess - -from funcy import imap +from os.path import basename, dirname, relpath, join, exists from dxr.plugins.js.refs import PLUGIN_NAME, QualifiedRef -from dxr.indexers import (TreeToIndex, FileToIndex, - Extent, Position, iterable_per_line, +import dxr.indexers +from dxr.indexers import (Extent, Position, iterable_per_line, with_start_and_end, split_into_lines) from dxr.utils import cumulative_sum @@ -20,12 +19,11 @@ def __init__(self, tree, lines, contents): for line in lines: row, (start, end) = line['loc'] qref = QualifiedRef(tree, (line['sym'], line['name'], line['type']), qualname=line['sym']) - if line['kind'] == "use": - self.yield_needle(line['type'] + "_ref", row, start, end, line['name'], line['sym']) - self.yield_ref(row, start, end, qref) - elif line['kind'] == "def": - self.yield_needle(line['type'], row, start, end, line['name'], line['sym']) - self.yield_ref(row, start, end, qref) + typ = line['type'] + if line['kind'] == 'use': + typ += '_ref' + self.yield_needle(typ, row, start, end, line['name'], line['sym']) + self.yield_ref(row, start, end, qref) def yield_ref(self, row, start, end, ref): offset = self.row_to_offset(row) @@ -47,35 +45,35 @@ def yield_needle(self, filter_name, line, start, end, name, qualname=None): Extent(Position(row=line, col=start), Position(row=line, col=end)))) -class _TreeToIndex(TreeToIndex): +class TreeToIndex(dxr.indexers.TreeToIndex): """Start up the node scripts to analyze the tree. """ def __init__(self, plugin_name, tree, vcs_cache): - super(_TreeToIndex, self).__init__(plugin_name, tree, vcs_cache) + super(TreeToIndex, self).__init__(plugin_name, tree, vcs_cache) self.plugin_folder = dirname(__file__) def post_build(self): # Execute the esprima to dump metadata, by running node from here and # passing in the tree location - retcode = subprocess.call(["node", "analyze_tree.js", + retcode = subprocess.call(['node', 'analyze_tree.js', self.tree.source_folder, - join(self.tree.temp_folder, "plugins/js")] + + join(self.tree.temp_folder, 'plugins/js')] + self.tree.ignore_filenames, - cwd=join(self.plugin_folder, "analyze_js")) + cwd=join(self.plugin_folder, 'analyze_js')) return retcode def file_to_index(self, path, contents): - return _FileToIndex(path, contents, self.plugin_name, self.tree) + return FileToIndex(path, contents, self.plugin_name, self.tree) -class _FileToIndex(FileToIndex): +class FileToIndex(dxr.indexers.FileToIndex): def __init__(self, path, contents, plugin_name, tree): - super(_FileToIndex, self).__init__(path, contents, plugin_name, tree) - self.analysis_path = join(join(join(tree.temp_folder, "plugins/js"), + super(FileToIndex, self).__init__(path, contents, plugin_name, tree) + self.analysis_path = join(join(join(tree.temp_folder, 'plugins/js'), relpath(dirname(self.absolute_path()), tree.source_folder)), basename(path) + '.data') lines = [] - if exists(self.analysis_path): + if self.is_interesting(): with open(self.analysis_path) as analysis: lines = self.parse_analysis(analysis.readlines()) lines = sorted(lines, key=lambda x: x['loc']) @@ -91,8 +89,8 @@ def parse_loc(line): if '-' in col: col = tuple(map(int, col.split('-', 1))) else: - col = (int(col), int(col)) - line['loc'] = (int(row), col) + col = int(col), int(col) + line['loc'] = int(row), col return line return (parse_loc(json.loads(line)) for line in lines) diff --git a/dxr/plugins/js/tests/test_refs_and_needles/code/somejs.js b/dxr/plugins/js/tests/test_refs_and_needles/code/somejs.js index 6bdda6b09..baa99327c 100644 --- a/dxr/plugins/js/tests/test_refs_and_needles/code/somejs.js +++ b/dxr/plugins/js/tests/test_refs_and_needles/code/somejs.js @@ -45,3 +45,4 @@ class Bob extends Guy { let him = new Bob("Abe"); Guy.greet("Joe"); him.doIt("Jef"); +him.name.toString();