@fullstackio/cq
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -8,6 +8,8 @@ Object.defineProperty(exports, "__esModule", { | ||
var _babelTraverse = require("babel-traverse"); | ||
var _babelTraverse = require('babel-traverse'); | ||
var _babelTraverse2 = _interopRequireDefault(_babelTraverse); | ||
var _util = require('./util'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -29,2 +31,23 @@ | ||
function nodeToRange(node) { | ||
if (node.start && node.end) { | ||
return { start: node.start, end: node.end }; | ||
} | ||
if (node.body && node.body.start && node.body.end) { | ||
return { start: node.body.start, end: node.body.end }; | ||
} | ||
switch (node.type) { | ||
case 'ObjectProperty': | ||
return { | ||
start: nodeToRange(node.key).start, | ||
end: nodeToRange(node.value).end | ||
}; | ||
default: | ||
console.log("unknown", node); | ||
throw new Error('nodeToRange of unknown type: ' + node.type); | ||
break; | ||
} | ||
} | ||
function babylonEngine() { | ||
@@ -50,32 +73,21 @@ var engineOpts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
}, | ||
nodeToRange: function (_nodeToRange) { | ||
function nodeToRange(_x3) { | ||
return _nodeToRange.apply(this, arguments); | ||
} | ||
nodeToRange.toString = function () { | ||
return _nodeToRange.toString(); | ||
}; | ||
return nodeToRange; | ||
}(function (node) { | ||
if (node.start && node.end) { | ||
return { start: node.start, end: node.end }; | ||
nodeToRange: nodeToRange, | ||
commentRange: function commentRange(node, code, getLeading, getTrailing) { | ||
var start = node.start; | ||
var end = node.end; | ||
if (getLeading && node.leadingComments) { | ||
var commentRange = (0, _util.rangeExtents)(node.leadingComments.map(function (n) { | ||
return nodeToRange(n); | ||
})); | ||
start = Math.min(start, commentRange.start); | ||
} | ||
if (node.body && node.body.start && node.body.end) { | ||
return { start: node.body.start, end: node.body.end }; | ||
if (getTrailing && node.trailingComments) { | ||
var _commentRange = (0, _util.rangeExtents)(node.trailingComments.map(function (n) { | ||
return nodeToRange(n); | ||
})); | ||
end = Math.max(end, _commentRange.end); | ||
} | ||
switch (node.type) { | ||
case 'ObjectProperty': | ||
return { | ||
start: nodeToRange(node.key).start, | ||
end: nodeToRange(node.value).end | ||
}; | ||
default: | ||
console.log("unknown", node); | ||
throw new Error('nodeToRange of unknown type: ' + node.type); | ||
break; | ||
} | ||
}), | ||
return { nodes: [node], start: start, end: end }; | ||
}, | ||
findNodeWithIdentifier: function findNodeWithIdentifier(ast, root, query) { | ||
@@ -139,2 +151,2 @@ var nextRoot = void 0; | ||
} | ||
module.exports = exports["default"]; | ||
module.exports = exports['default']; |
@@ -14,16 +14,16 @@ 'use strict'; | ||
var _util = require('./util'); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
/** | ||
* cq TypeScript Engine | ||
* | ||
* Parse files with TypeScript | ||
* | ||
* Thanks to astexplorer for some of this code | ||
* see: https://github.com/fkling/astexplorer/tree/master/src/parsers/js/typescript.js#L128 | ||
*/ | ||
var ignoredProperties = new Set(['constructor', 'parent']); /** | ||
* cq TypeScript Engine | ||
* | ||
* Parse files with TypeScript | ||
* | ||
* Thanks to astexplorer for some of this code | ||
* see: https://github.com/fkling/astexplorer/tree/master/src/parsers/js/typescript.js#L128 | ||
*/ | ||
var ignoredProperties = new Set(['constructor', 'parent']); | ||
function getNodeName(node) { | ||
@@ -64,2 +64,10 @@ if (node.kind) { | ||
function nodeToRange(node) { | ||
if (typeof node.getStart === 'function' && typeof node.getEnd === 'function') { | ||
return { start: node.getStart(), end: node.getEnd() }; | ||
} else if (typeof node.pos !== 'undefined' && typeof node.end !== 'undefined') { | ||
return { start: node.pos, end: node.end }; | ||
} | ||
} | ||
function typescriptEngine() { | ||
@@ -77,8 +85,24 @@ var engineOpts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
}, | ||
nodeToRange: function nodeToRange(node) { | ||
if (typeof node.getStart === 'function' && typeof node.getEnd === 'function') { | ||
return { start: node.getStart(), end: node.getEnd() }; | ||
} else if (typeof node.pos !== 'undefined' && typeof node.end !== 'undefined') { | ||
return { start: node.pos, end: node.end }; | ||
nodeToRange: nodeToRange, | ||
commentRange: function commentRange(node, code, getLeading, getTrailing) { | ||
var _nodeToRange = nodeToRange(node); | ||
var start = _nodeToRange.start; | ||
var end = _nodeToRange.end; | ||
if (getLeading) { | ||
var nodePos = node.pos; | ||
var parentPos = node.parent.pos; | ||
var comments = ts.getLeadingCommentRanges(code, nodePos); | ||
var commentRanges = comments.map(function (c) { | ||
return { start: c.pos, end: c.end }; | ||
}); | ||
var commentRange = (0, _util.rangeExtents)(commentRanges); | ||
start = Math.min(start, commentRange.start); | ||
} | ||
// TODO trailing | ||
return { nodes: [node], start: start, end: end }; | ||
}, | ||
@@ -85,0 +109,0 @@ findNodeWithIdentifier: function findNodeWithIdentifier(ast, root, query) { |
@@ -94,6 +94,23 @@ 'use strict'; | ||
function modifyAnswerWithCall(code, callee, args, _ref2) { | ||
function adjustRangeForComments(ast, code, leading, trailing, engine, _ref2) { | ||
var start = _ref2.start; | ||
var end = _ref2.end; | ||
var nodes = _ref2.nodes; | ||
// this is going to be part of the engine | ||
nodes.map(function (node) { | ||
var commentRange = engine.commentRange(node, code, leading, trailing); | ||
start = commentRange.start ? Math.min(commentRange.start, start) : start; | ||
end = commentRange.end ? Math.max(commentRange.end, end) : end; | ||
}); | ||
return { start: start, end: end, nodes: nodes }; | ||
} | ||
function modifyAnswerWithCall(ast, code, callee, args, engine, _ref3) { | ||
var start = _ref3.start; | ||
var end = _ref3.end; | ||
var nodes = _ref3.nodes; | ||
switch (callee) { | ||
@@ -117,2 +134,7 @@ case 'upto': | ||
break; | ||
case 'comments': | ||
var leading = true, | ||
trailing = false; | ||
return adjustRangeForComments(ast, code, leading, trailing, engine, { start: start, end: end, nodes: nodes }); | ||
break; | ||
default: | ||
@@ -139,5 +161,6 @@ throw new Error('Unknown function call: ' + callee); | ||
// whatever the child answer is, now we modify it given our callee | ||
answer = modifyAnswerWithCall(code, callee, args, answer); | ||
// TODO - modifying the asnwer needs to be given not only the answer start and end range, but the child node which returned that start and end | ||
answer = modifyAnswerWithCall(ast, code, callee, args, engine, answer); | ||
// hmm, maybe do this later | ||
// hmm, maybe do this later in the pipeline? | ||
answer.code = code.substring(answer.start, answer.end); | ||
@@ -183,3 +206,3 @@ | ||
} else { | ||
return { code: codeSlice, start: start, end: end }; | ||
return { code: codeSlice, nodes: [nextRoot], start: start, end: end }; | ||
} | ||
@@ -194,3 +217,4 @@ } | ||
var _codeSlice = code.substring(_start, _end); | ||
return { code: _codeSlice, start: _start, end: _end }; | ||
var nodes = [].concat(_toConsumableArray(rangeStart.nodes || []), _toConsumableArray(rangeEnd.nodes || [])); | ||
return { code: _codeSlice, nodes: nodes, start: _start, end: _end }; | ||
} | ||
@@ -230,3 +254,4 @@ case NodeTypes.LINE_NUMBER: | ||
var _codeSlice2 = code.substring(_start2, _end2); | ||
return { code: _codeSlice2, start: _start2, end: _end2 }; | ||
var _nodes = []; // TODO - find the node that applies to this line number | ||
return { code: _codeSlice2, nodes: _nodes, start: _start2, end: _end2 }; | ||
} | ||
@@ -233,0 +258,0 @@ } |
@@ -107,21 +107,32 @@ "use strict"; | ||
}, | ||
peg$c19 = ".", | ||
peg$c20 = { type: "literal", value: ".", description: "\".\"" }, | ||
peg$c21 = "-", | ||
peg$c22 = { type: "literal", value: "-", description: "\"-\"" }, | ||
peg$c23 = "+", | ||
peg$c24 = { type: "literal", value: "+", description: "\"+\"" }, | ||
peg$c25 = ":", | ||
peg$c26 = { type: "literal", value: ":", description: "\":\"" }, | ||
peg$c27 = "EOF", | ||
peg$c28 = { type: "literal", value: "EOF", description: "\"EOF\"" }, | ||
peg$c29 = { type: "other", description: "whitespace" }, | ||
peg$c30 = /^[ \t\n\r]/, | ||
peg$c31 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, | ||
peg$c32 = "'", | ||
peg$c33 = { type: "literal", value: "'", description: "\"'\"" }, | ||
peg$c34 = /^[A-Za-z0-9_$]/, | ||
peg$c35 = { type: "class", value: "[A-Za-z0-9_$]", description: "[A-Za-z0-9_$]" }, | ||
peg$c36 = /^[^\n']/, | ||
peg$c37 = { type: "class", value: "[^\\n\\']", description: "[^\\n\\']" }, | ||
peg$c19 = { type: "other", description: "boolean" }, | ||
peg$c20 = ".", | ||
peg$c21 = { type: "literal", value: ".", description: "\".\"" }, | ||
peg$c22 = "-", | ||
peg$c23 = { type: "literal", value: "-", description: "\"-\"" }, | ||
peg$c24 = "+", | ||
peg$c25 = { type: "literal", value: "+", description: "\"+\"" }, | ||
peg$c26 = ":", | ||
peg$c27 = { type: "literal", value: ":", description: "\":\"" }, | ||
peg$c28 = "EOF", | ||
peg$c29 = { type: "literal", value: "EOF", description: "\"EOF\"" }, | ||
peg$c30 = "true", | ||
peg$c31 = { type: "literal", value: "true", description: "\"true\"" }, | ||
peg$c32 = function peg$c32() { | ||
return true; | ||
}, | ||
peg$c33 = "false", | ||
peg$c34 = { type: "literal", value: "false", description: "\"false\"" }, | ||
peg$c35 = function peg$c35() { | ||
return false; | ||
}, | ||
peg$c36 = { type: "other", description: "whitespace" }, | ||
peg$c37 = /^[ \t\n\r]/, | ||
peg$c38 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, | ||
peg$c39 = "'", | ||
peg$c40 = { type: "literal", value: "'", description: "\"'\"" }, | ||
peg$c41 = /^[A-Za-z0-9_$]/, | ||
peg$c42 = { type: "class", value: "[A-Za-z0-9_$]", description: "[A-Za-z0-9_$]" }, | ||
peg$c43 = /^[^\n']/, | ||
peg$c44 = { type: "class", value: "[^\\n\\']", description: "[^\\n\\']" }, | ||
peg$currPos = 0, | ||
@@ -688,2 +699,5 @@ peg$savedPos = 0, | ||
s0 = peg$parseCallExpression(); | ||
if (s0 === peg$FAILED) { | ||
s0 = peg$parseBoolean(); | ||
} | ||
} | ||
@@ -784,2 +798,21 @@ | ||
function peg$parseBoolean() { | ||
var s0, s1; | ||
peg$silentFails++; | ||
s0 = peg$parsetrue(); | ||
if (s0 === peg$FAILED) { | ||
s0 = peg$parsefalse(); | ||
} | ||
peg$silentFails--; | ||
if (s0 === peg$FAILED) { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c19); | ||
} | ||
} | ||
return s0; | ||
} | ||
function peg$parsedot() { | ||
@@ -789,3 +822,3 @@ var s0; | ||
if (input.charCodeAt(peg$currPos) === 46) { | ||
s0 = peg$c19; | ||
s0 = peg$c20; | ||
peg$currPos++; | ||
@@ -795,3 +828,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c20); | ||
peg$fail(peg$c21); | ||
} | ||
@@ -807,3 +840,3 @@ } | ||
if (input.charCodeAt(peg$currPos) === 45) { | ||
s0 = peg$c21; | ||
s0 = peg$c22; | ||
peg$currPos++; | ||
@@ -813,3 +846,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c22); | ||
peg$fail(peg$c23); | ||
} | ||
@@ -825,3 +858,3 @@ } | ||
if (input.charCodeAt(peg$currPos) === 43) { | ||
s0 = peg$c23; | ||
s0 = peg$c24; | ||
peg$currPos++; | ||
@@ -831,3 +864,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c24); | ||
peg$fail(peg$c25); | ||
} | ||
@@ -843,3 +876,3 @@ } | ||
if (input.charCodeAt(peg$currPos) === 45) { | ||
s0 = peg$c21; | ||
s0 = peg$c22; | ||
peg$currPos++; | ||
@@ -849,3 +882,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c22); | ||
peg$fail(peg$c23); | ||
} | ||
@@ -861,3 +894,3 @@ } | ||
if (input.charCodeAt(peg$currPos) === 58) { | ||
s0 = peg$c25; | ||
s0 = peg$c26; | ||
peg$currPos++; | ||
@@ -867,3 +900,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c26); | ||
peg$fail(peg$c27); | ||
} | ||
@@ -926,4 +959,4 @@ } | ||
if (input.substr(peg$currPos, 3) === peg$c27) { | ||
s0 = peg$c27; | ||
if (input.substr(peg$currPos, 3) === peg$c28) { | ||
s0 = peg$c28; | ||
peg$currPos += 3; | ||
@@ -933,3 +966,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c28); | ||
peg$fail(peg$c29); | ||
} | ||
@@ -941,2 +974,46 @@ } | ||
function peg$parsetrue() { | ||
var s0, s1; | ||
s0 = peg$currPos; | ||
if (input.substr(peg$currPos, 4) === peg$c30) { | ||
s1 = peg$c30; | ||
peg$currPos += 4; | ||
} else { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c31); | ||
} | ||
} | ||
if (s1 !== peg$FAILED) { | ||
peg$savedPos = s0; | ||
s1 = peg$c32(); | ||
} | ||
s0 = s1; | ||
return s0; | ||
} | ||
function peg$parsefalse() { | ||
var s0, s1; | ||
s0 = peg$currPos; | ||
if (input.substr(peg$currPos, 5) === peg$c33) { | ||
s1 = peg$c33; | ||
peg$currPos += 5; | ||
} else { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c34); | ||
} | ||
} | ||
if (s1 !== peg$FAILED) { | ||
peg$savedPos = s0; | ||
s1 = peg$c35(); | ||
} | ||
s0 = s1; | ||
return s0; | ||
} | ||
function peg$parsews() { | ||
@@ -947,3 +1024,3 @@ var s0, s1; | ||
s0 = []; | ||
if (peg$c30.test(input.charAt(peg$currPos))) { | ||
if (peg$c37.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -954,3 +1031,3 @@ peg$currPos++; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c31); | ||
peg$fail(peg$c38); | ||
} | ||
@@ -960,3 +1037,3 @@ } | ||
s0.push(s1); | ||
if (peg$c30.test(input.charAt(peg$currPos))) { | ||
if (peg$c37.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -967,3 +1044,3 @@ peg$currPos++; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c31); | ||
peg$fail(peg$c38); | ||
} | ||
@@ -976,3 +1053,3 @@ } | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c29); | ||
peg$fail(peg$c36); | ||
} | ||
@@ -988,3 +1065,3 @@ } | ||
if (input.charCodeAt(peg$currPos) === 39) { | ||
s0 = peg$c32; | ||
s0 = peg$c39; | ||
peg$currPos++; | ||
@@ -994,3 +1071,3 @@ } else { | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c33); | ||
peg$fail(peg$c40); | ||
} | ||
@@ -1005,3 +1082,3 @@ } | ||
if (peg$c34.test(input.charAt(peg$currPos))) { | ||
if (peg$c41.test(input.charAt(peg$currPos))) { | ||
s0 = input.charAt(peg$currPos); | ||
@@ -1012,3 +1089,3 @@ peg$currPos++; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c35); | ||
peg$fail(peg$c42); | ||
} | ||
@@ -1024,3 +1101,3 @@ } | ||
s0 = []; | ||
if (peg$c36.test(input.charAt(peg$currPos))) { | ||
if (peg$c43.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -1031,3 +1108,3 @@ peg$currPos++; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c37); | ||
peg$fail(peg$c44); | ||
} | ||
@@ -1037,3 +1114,3 @@ } | ||
s0.push(s1); | ||
if (peg$c36.test(input.charAt(peg$currPos))) { | ||
if (peg$c43.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -1044,3 +1121,3 @@ peg$currPos++; | ||
if (peg$silentFails === 0) { | ||
peg$fail(peg$c37); | ||
peg$fail(peg$c44); | ||
} | ||
@@ -1047,0 +1124,0 @@ } |
{ | ||
"name": "@fullstackio/cq", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "query code with selectors", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -204,2 +204,34 @@ <p align="center"> | ||
Sometimes we want to pull the comments before a selection. `cq` supports this using the `comments()` operator: | ||
```javascript | ||
// comments.js | ||
function hello() { | ||
return 'hi'; | ||
} | ||
/* | ||
* @function bye | ||
*/ | ||
function bye() { | ||
return 'see ya'; | ||
} | ||
``` | ||
Get the `bye()` function with comments: | ||
```javascript | ||
$ cq 'comments(.bye)' comments.js | ||
/* | ||
* @function bye | ||
*/ | ||
const bye = function() { | ||
return 'bye'; | ||
} | ||
``` | ||
> See _many_ more examples in the [`/examples`](./examples) directory | ||
@@ -311,2 +343,3 @@ | ||
- `upto(.bye)` | ||
- `comments(.bye)` | ||
@@ -316,7 +349,7 @@ Given: | ||
```javascript | ||
// here is the bye function (emitted with -1) | ||
// here is the bye function | ||
const bye = function() { | ||
return 'bye'; | ||
} | ||
bye(); // -> 'bye' (emitted with +1) | ||
bye(); // -> 'bye' | ||
``` | ||
@@ -326,10 +359,14 @@ | ||
#### `context` | ||
#### `context()` | ||
The `context()` operation allows you to take line numbers before and after the selection. The signature is `context(selection, numLinesBefore, numLinesAfter)`. | ||
#### `upto` | ||
#### `upto()` | ||
The `upto()` operation will return the code up-to, but not including, the selection. A convenient (but potentially confusing) default is that **the `upto()` operation trims whitespace**. This is normally what you want, but you have to be careful when using `upto()` and `context()` together (because `upto()` may trim lines). | ||
#### `comments()` | ||
The `comments()` operation will return the selection plus the leading comments before the selection. | ||
### _'String'_ | ||
@@ -336,0 +373,0 @@ |
@@ -9,2 +9,3 @@ /** | ||
import traverse from 'babel-traverse'; | ||
import { rangeExtents } from './util'; | ||
@@ -31,2 +32,24 @@ const defaultBabylonConfig = { | ||
function nodeToRange(node) { | ||
if(node.start && node.end) { | ||
return { start: node.start, end: node.end }; | ||
} | ||
if(node.body && node.body.start && node.body.end) { | ||
return { start: node.body.start, end: node.body.end }; | ||
} | ||
switch(node.type) { | ||
case 'ObjectProperty': | ||
return { | ||
start: nodeToRange(node.key).start, | ||
end: nodeToRange(node.value).end | ||
}; | ||
default: | ||
console.log("unknown", node); | ||
throw new Error('nodeToRange of unknown type: ' + node.type); | ||
break; | ||
} | ||
} | ||
export default function babylonEngine(engineOpts={}) { | ||
@@ -48,21 +71,15 @@ return { | ||
}, | ||
nodeToRange(node) { | ||
if(node.start && node.end) { | ||
return { start: node.start, end: node.end }; | ||
} | ||
if(node.body && node.body.start && node.body.end) { | ||
return { start: node.body.start, end: node.body.end }; | ||
} | ||
switch(node.type) { | ||
case 'ObjectProperty': | ||
return { | ||
start: nodeToRange(node.key).start, | ||
end: nodeToRange(node.value).end | ||
}; | ||
default: | ||
console.log("unknown", node); | ||
throw new Error('nodeToRange of unknown type: ' + node.type); | ||
break; | ||
} | ||
nodeToRange, | ||
commentRange(node, code, getLeading, getTrailing) { | ||
let start = node.start; | ||
let end = node.end; | ||
if (getLeading && node.leadingComments) { | ||
let commentRange = rangeExtents(node.leadingComments.map(n => nodeToRange(n))); | ||
start = Math.min(start, commentRange.start); | ||
} | ||
if (getTrailing && node.trailingComments) { | ||
let commentRange = rangeExtents(node.trailingComments.map(n => nodeToRange(n))); | ||
end = Math.max(end, commentRange.end); | ||
} | ||
return {nodes: [node], start, end}; | ||
}, | ||
@@ -69,0 +86,0 @@ findNodeWithIdentifier(ast, root, query) { |
@@ -11,2 +11,3 @@ /** | ||
import * as ts from "typescript"; | ||
import { rangeExtents } from './util'; | ||
@@ -50,2 +51,12 @@ const ignoredProperties = new Set([ | ||
function nodeToRange(node) { | ||
if (typeof node.getStart === 'function' && | ||
typeof node.getEnd === 'function') { | ||
return {start: node.getStart(), end: node.getEnd()}; | ||
} else if (typeof node.pos !== 'undefined' && | ||
typeof node.end !== 'undefined') { | ||
return {start: node.pos, end: node.end}; | ||
} | ||
} | ||
export default function typescriptEngine(engineOpts={}) { | ||
@@ -59,10 +70,17 @@ return { | ||
}, | ||
nodeToRange(node) { | ||
if (typeof node.getStart === 'function' && | ||
typeof node.getEnd === 'function') { | ||
return {start: node.getStart(), end: node.getEnd()}; | ||
} else if (typeof node.pos !== 'undefined' && | ||
typeof node.end !== 'undefined') { | ||
return {start: node.pos, end: node.end}; | ||
nodeToRange, | ||
commentRange(node, code, getLeading, getTrailing) { | ||
let {start,end} = nodeToRange(node); | ||
if(getLeading) { | ||
let nodePos = node.pos; | ||
let parentPos = node.parent.pos; | ||
let comments = ts.getLeadingCommentRanges(code, nodePos); | ||
let commentRanges = comments.map(c => ({start: c.pos, end: c.end})) | ||
let commentRange = rangeExtents(commentRanges); | ||
start = Math.min(start, commentRange.start); | ||
} | ||
// TODO trailing | ||
return {nodes: [node], start, end}; | ||
}, | ||
@@ -69,0 +87,0 @@ findNodeWithIdentifier(ast, root, query) { |
@@ -64,3 +64,15 @@ /** | ||
function modifyAnswerWithCall(code, callee, args, {start, end}) { | ||
function adjustRangeForComments(ast, code, leading, trailing, engine, {start, end, nodes}) { | ||
// this is going to be part of the engine | ||
nodes.map((node) => { | ||
let commentRange = engine.commentRange(node, code, leading, trailing); | ||
start = commentRange.start ? Math.min(commentRange.start, start) : start; | ||
end = commentRange.end ? Math.max(commentRange.end, end) : end; | ||
}); | ||
return {start, end, nodes}; | ||
} | ||
function modifyAnswerWithCall(ast, code, callee, args, engine, {start, end, nodes}) { | ||
switch(callee) { | ||
@@ -80,2 +92,6 @@ case 'upto': | ||
break; | ||
case 'comments': | ||
let leading = true, trailing = false; | ||
return adjustRangeForComments(ast, code, leading, trailing, engine, {start, end, nodes}) | ||
break; | ||
default: | ||
@@ -86,3 +102,2 @@ throw new Error(`Unknown function call: ${callee}`); | ||
function resolveIndividualQuery(ast, root, code, query, engine, opts) { | ||
@@ -97,5 +112,6 @@ switch(query.type) { | ||
// whatever the child answer is, now we modify it given our callee | ||
answer = modifyAnswerWithCall(code, callee, args, answer); | ||
// TODO - modifying the asnwer needs to be given not only the answer start and end range, but the child node which returned that start and end | ||
answer = modifyAnswerWithCall(ast, code, callee, args, engine, answer); | ||
// hmm, maybe do this later | ||
// hmm, maybe do this later in the pipeline? | ||
answer.code = code.substring(answer.start, answer.end); | ||
@@ -140,3 +156,3 @@ | ||
} else { | ||
return { code: codeSlice, start, end }; | ||
return { code: codeSlice, nodes: [ nextRoot ], start, end }; | ||
} | ||
@@ -150,3 +166,4 @@ } | ||
let codeSlice = code.substring(start, end); | ||
return { code: codeSlice, start, end }; | ||
let nodes = [...(rangeStart.nodes || []), ...(rangeEnd.nodes || [])] | ||
return { code: codeSlice, nodes, start, end }; | ||
} | ||
@@ -183,3 +200,4 @@ case NodeTypes.LINE_NUMBER: { | ||
let codeSlice = code.substring(start, end); | ||
return { code: codeSlice, start, end }; | ||
let nodes = []; // TODO - find the node that applies to this line number | ||
return { code: codeSlice, nodes, start, end }; | ||
} | ||
@@ -186,0 +204,0 @@ |
@@ -104,21 +104,28 @@ module.exports = (function() { | ||
peg$c18 = function() { return parseInt(text(), 10); }, | ||
peg$c19 = ".", | ||
peg$c20 = { type: "literal", value: ".", description: "\".\"" }, | ||
peg$c21 = "-", | ||
peg$c22 = { type: "literal", value: "-", description: "\"-\"" }, | ||
peg$c23 = "+", | ||
peg$c24 = { type: "literal", value: "+", description: "\"+\"" }, | ||
peg$c25 = ":", | ||
peg$c26 = { type: "literal", value: ":", description: "\":\"" }, | ||
peg$c27 = "EOF", | ||
peg$c28 = { type: "literal", value: "EOF", description: "\"EOF\"" }, | ||
peg$c29 = { type: "other", description: "whitespace" }, | ||
peg$c30 = /^[ \t\n\r]/, | ||
peg$c31 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, | ||
peg$c32 = "'", | ||
peg$c33 = { type: "literal", value: "'", description: "\"'\"" }, | ||
peg$c34 = /^[A-Za-z0-9_$]/, | ||
peg$c35 = { type: "class", value: "[A-Za-z0-9_$]", description: "[A-Za-z0-9_$]" }, | ||
peg$c36 = /^[^\n']/, | ||
peg$c37 = { type: "class", value: "[^\\n\\']", description: "[^\\n\\']" }, | ||
peg$c19 = { type: "other", description: "boolean" }, | ||
peg$c20 = ".", | ||
peg$c21 = { type: "literal", value: ".", description: "\".\"" }, | ||
peg$c22 = "-", | ||
peg$c23 = { type: "literal", value: "-", description: "\"-\"" }, | ||
peg$c24 = "+", | ||
peg$c25 = { type: "literal", value: "+", description: "\"+\"" }, | ||
peg$c26 = ":", | ||
peg$c27 = { type: "literal", value: ":", description: "\":\"" }, | ||
peg$c28 = "EOF", | ||
peg$c29 = { type: "literal", value: "EOF", description: "\"EOF\"" }, | ||
peg$c30 = "true", | ||
peg$c31 = { type: "literal", value: "true", description: "\"true\"" }, | ||
peg$c32 = function() { return true; }, | ||
peg$c33 = "false", | ||
peg$c34 = { type: "literal", value: "false", description: "\"false\"" }, | ||
peg$c35 = function() { return false; }, | ||
peg$c36 = { type: "other", description: "whitespace" }, | ||
peg$c37 = /^[ \t\n\r]/, | ||
peg$c38 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, | ||
peg$c39 = "'", | ||
peg$c40 = { type: "literal", value: "'", description: "\"'\"" }, | ||
peg$c41 = /^[A-Za-z0-9_$]/, | ||
peg$c42 = { type: "class", value: "[A-Za-z0-9_$]", description: "[A-Za-z0-9_$]" }, | ||
peg$c43 = /^[^\n']/, | ||
peg$c44 = { type: "class", value: "[^\\n\\']", description: "[^\\n\\']" }, | ||
@@ -692,2 +699,5 @@ peg$currPos = 0, | ||
s0 = peg$parseCallExpression(); | ||
if (s0 === peg$FAILED) { | ||
s0 = peg$parseBoolean(); | ||
} | ||
} | ||
@@ -782,2 +792,19 @@ | ||
function peg$parseBoolean() { | ||
var s0, s1; | ||
peg$silentFails++; | ||
s0 = peg$parsetrue(); | ||
if (s0 === peg$FAILED) { | ||
s0 = peg$parsefalse(); | ||
} | ||
peg$silentFails--; | ||
if (s0 === peg$FAILED) { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c19); } | ||
} | ||
return s0; | ||
} | ||
function peg$parsedot() { | ||
@@ -787,7 +814,7 @@ var s0; | ||
if (input.charCodeAt(peg$currPos) === 46) { | ||
s0 = peg$c19; | ||
s0 = peg$c20; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c20); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c21); } | ||
} | ||
@@ -802,7 +829,7 @@ | ||
if (input.charCodeAt(peg$currPos) === 45) { | ||
s0 = peg$c21; | ||
s0 = peg$c22; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c22); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c23); } | ||
} | ||
@@ -817,7 +844,7 @@ | ||
if (input.charCodeAt(peg$currPos) === 43) { | ||
s0 = peg$c23; | ||
s0 = peg$c24; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c24); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c25); } | ||
} | ||
@@ -832,7 +859,7 @@ | ||
if (input.charCodeAt(peg$currPos) === 45) { | ||
s0 = peg$c21; | ||
s0 = peg$c22; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c22); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c23); } | ||
} | ||
@@ -847,7 +874,7 @@ | ||
if (input.charCodeAt(peg$currPos) === 58) { | ||
s0 = peg$c25; | ||
s0 = peg$c26; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c26); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c27); } | ||
} | ||
@@ -903,8 +930,8 @@ | ||
if (input.substr(peg$currPos, 3) === peg$c27) { | ||
s0 = peg$c27; | ||
if (input.substr(peg$currPos, 3) === peg$c28) { | ||
s0 = peg$c28; | ||
peg$currPos += 3; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c28); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c29); } | ||
} | ||
@@ -915,2 +942,42 @@ | ||
function peg$parsetrue() { | ||
var s0, s1; | ||
s0 = peg$currPos; | ||
if (input.substr(peg$currPos, 4) === peg$c30) { | ||
s1 = peg$c30; | ||
peg$currPos += 4; | ||
} else { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c31); } | ||
} | ||
if (s1 !== peg$FAILED) { | ||
peg$savedPos = s0; | ||
s1 = peg$c32(); | ||
} | ||
s0 = s1; | ||
return s0; | ||
} | ||
function peg$parsefalse() { | ||
var s0, s1; | ||
s0 = peg$currPos; | ||
if (input.substr(peg$currPos, 5) === peg$c33) { | ||
s1 = peg$c33; | ||
peg$currPos += 5; | ||
} else { | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c34); } | ||
} | ||
if (s1 !== peg$FAILED) { | ||
peg$savedPos = s0; | ||
s1 = peg$c35(); | ||
} | ||
s0 = s1; | ||
return s0; | ||
} | ||
function peg$parsews() { | ||
@@ -921,3 +988,3 @@ var s0, s1; | ||
s0 = []; | ||
if (peg$c30.test(input.charAt(peg$currPos))) { | ||
if (peg$c37.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -927,7 +994,7 @@ peg$currPos++; | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c31); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c38); } | ||
} | ||
while (s1 !== peg$FAILED) { | ||
s0.push(s1); | ||
if (peg$c30.test(input.charAt(peg$currPos))) { | ||
if (peg$c37.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -937,3 +1004,3 @@ peg$currPos++; | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c31); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c38); } | ||
} | ||
@@ -944,3 +1011,3 @@ } | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c29); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c36); } | ||
} | ||
@@ -955,7 +1022,7 @@ | ||
if (input.charCodeAt(peg$currPos) === 39) { | ||
s0 = peg$c32; | ||
s0 = peg$c39; | ||
peg$currPos++; | ||
} else { | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c33); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c40); } | ||
} | ||
@@ -969,3 +1036,3 @@ | ||
if (peg$c34.test(input.charAt(peg$currPos))) { | ||
if (peg$c41.test(input.charAt(peg$currPos))) { | ||
s0 = input.charAt(peg$currPos); | ||
@@ -975,3 +1042,3 @@ peg$currPos++; | ||
s0 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c35); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c42); } | ||
} | ||
@@ -986,3 +1053,3 @@ | ||
s0 = []; | ||
if (peg$c36.test(input.charAt(peg$currPos))) { | ||
if (peg$c43.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -992,7 +1059,7 @@ peg$currPos++; | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c37); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c44); } | ||
} | ||
while (s1 !== peg$FAILED) { | ||
s0.push(s1); | ||
if (peg$c36.test(input.charAt(peg$currPos))) { | ||
if (peg$c43.test(input.charAt(peg$currPos))) { | ||
s1 = input.charAt(peg$currPos); | ||
@@ -1002,3 +1069,3 @@ peg$currPos++; | ||
s1 = peg$FAILED; | ||
if (peg$silentFails === 0) { peg$fail(peg$c37); } | ||
if (peg$silentFails === 0) { peg$fail(peg$c44); } | ||
} | ||
@@ -1005,0 +1072,0 @@ } |
@@ -348,2 +348,43 @@ import 'babel-polyfill' | ||
describe('getting comments', () => { | ||
const src = ` | ||
// hello says hello | ||
// it's the best | ||
function hello() { | ||
return 'hi'; | ||
} | ||
/* | ||
* @function bye | ||
*/ | ||
function bye() { | ||
return 'see ya'; | ||
} | ||
function noComments() { | ||
return 'nothing to see here'; | ||
} | ||
`; | ||
it('find a group of single-line comments preceeding', () => { | ||
let { code } = cq(src, "comments(.hello)"); | ||
const wanted = lines(src, 1, 5); | ||
assert.equal(code, wanted); | ||
}) | ||
it('find a block comment preceeding', () => { | ||
let { code } = cq(src, "comments(.bye)"); | ||
const wanted = lines(src, 7, 12); | ||
assert.equal(code, wanted); | ||
}) | ||
it('shouldnt fail if you try to get comments where there are none', () => { | ||
let { code } = cq(src, "comments(.noComments)"); | ||
const wanted = lines(src, 14, 16); | ||
assert.equal(code, wanted); | ||
}) | ||
}); | ||
}); |
@@ -145,2 +145,42 @@ import 'babel-polyfill' | ||
describe('getting comments', () => { | ||
const src = ` | ||
// hello says hello | ||
// it's the best | ||
function hello() { | ||
return 'hi'; | ||
} | ||
/* | ||
* @function bye | ||
*/ | ||
function bye() { | ||
return 'see ya'; | ||
} | ||
function noComments() { | ||
return 'nothing to see here'; | ||
} | ||
`; | ||
it('find a group of single-line comments preceeding', () => { | ||
let { code } = cq(src, "comments(.hello)", {engine: 'typescript'}); | ||
const wanted = lines(src, 1, 5); | ||
assert.equal(code, wanted); | ||
}) | ||
it('find a block comment preceeding', () => { | ||
let { code } = cq(src, "comments(.bye)"); | ||
const wanted = lines(src, 7, 12); | ||
assert.equal(code, wanted); | ||
}) | ||
it('shouldnt fail if you try to get comments where there are none', () => { | ||
let { code } = cq(src, "comments(.noComments)"); | ||
const wanted = lines(src, 14, 16); | ||
assert.equal(code, wanted); | ||
}) | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
594377
33
4016
443