Skip to content
This repository was archived by the owner on Jan 14, 2019. It is now read-only.

fix: add directive field to ExpressionStatement #63

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,19 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {

/**
* Converts a TypeScript node into an ESTree node.
* @param {ts.Node} child the child ts.Node
* @param {ts.Node} child the child ts.Node
* @returns {ESTreeNode|null} the converted ESTree node
*/
function convertChild(child?: ts.Node): ESTreeNode | null {
if (!child) {
return null;
}
return convert({ node: child, parent: node, ast, additionalOptions });
return convert({
node: child,
parent: node,
ast,
additionalOptions
});
}

/**
Expand All @@ -110,6 +115,34 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
};
}

/**
* Coverts body ExpressionStatements to directives
*/
function convertBodyExpressionsToDirectives() {
if (result.body && nodeUtils.canContainDirective(node)) {
const unique: string[] = [];

// directives has to be unique, if directive is registered twice pick only first one
result.body
.filter(
(child: ESTreeNode) =>
child.type === AST_NODE_TYPES.ExpressionStatement &&
child.expression &&
child.expression.type === AST_NODE_TYPES.Literal &&
(child.expression as any).value &&
typeof (child.expression as any).value === 'string'
)
.forEach(
(child: { directive: string; expression: { raw: string } }) => {
if (!unique.includes((child.expression as any).raw)) {
child.directive = child.expression.raw.slice(1, -1);
unique.push(child.expression.raw);
}
}
);
}
}

/**
* Converts a ts.Node's typeArguments ts.NodeArray to a flow-like typeParameters node
* @param {ts.NodeArray<any>} typeArguments ts.Node typeArguments
Expand Down Expand Up @@ -519,6 +552,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
}
});

convertBodyExpressionsToDirectives();

(result as any).range[1] = node.endOfFileToken.end;
result.loc = nodeUtils.getLocFor(
node.getStart(ast),
Expand All @@ -532,6 +567,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
type: AST_NODE_TYPES.BlockStatement,
body: node.statements.map(convertChild)
});

convertBodyExpressionsToDirectives();
break;

case SyntaxKind.Identifier:
Expand Down Expand Up @@ -774,12 +811,13 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {

// Expressions

case SyntaxKind.ExpressionStatement:
case SyntaxKind.ExpressionStatement: {
Object.assign(result, {
type: AST_NODE_TYPES.ExpressionStatement,
expression: convertChild(node.expression)
});
break;
}

case SyntaxKind.ThisKeyword:
Object.assign(result, {
Expand Down
29 changes: 29 additions & 0 deletions src/node-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export default {
getLocFor,
getLoc,
isToken,
canContainDirective,
isJSXToken,
getDeclarationKind,
getTSNodeAccessibility,
Expand Down Expand Up @@ -292,6 +293,34 @@ function getLocFor(
};
}

/**
* Check whatever node can contain directive
* @param {ts.Node} node
* @returns {boolean} returns true if node can contain directive
*/
function canContainDirective(node: ts.Node): boolean {
switch (node.kind) {
case ts.SyntaxKind.SourceFile:
case ts.SyntaxKind.ModuleBlock:
return true;
case ts.SyntaxKind.Block:
switch (node.parent.kind) {
case ts.SyntaxKind.Constructor:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.MethodDeclaration:
return true;
default:
return false;
}
default:
return false;
}
}

/**
* Returns line and column data for the given ts.Node or ts.Token,
* for the given AST
Expand Down
4 changes: 3 additions & 1 deletion tests/ast-alignment/fixtures-to-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function createFixturePatternConfigFor(
* An array of FixturePatternConfigs
*/
let fixturePatternConfigsToTest = [
createFixturePatternConfigFor('basics'),
createFixturePatternConfigFor('javascript/basics'),

createFixturePatternConfigFor('comments', {
ignore: [
Expand All @@ -123,6 +123,8 @@ let fixturePatternConfigsToTest = [
ignore: ['**/*']
}),

createFixturePatternConfigFor('javascript/directives'),

createFixturePatternConfigFor('javascript/experimentalObjectRestSpread', {
ignore: [
/**
Expand Down
4 changes: 0 additions & 4 deletions tests/ast-alignment/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ export function preprocessBabylonAST(ast: any): any {
key: 'directives',
predicate: always
},
{
key: 'directive',
predicate: always
},
{
key: 'innerComments',
predicate: always
Expand Down
5 changes: 5 additions & 0 deletions tests/fixtures/javascript/directives/block.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function foo() {
"use strict";
var a = 1;
"use strict";
}
19 changes: 19 additions & 0 deletions tests/fixtures/javascript/directives/directive-in-class.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use strict";

class Foo {
constructor () {
"use strict";
}

get foo () {
"use strict";
}

set foo (value) {
"use strict";
}

method () {
"use strict";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function foo () {
"use smth"
1+1;
}
16 changes: 16 additions & 0 deletions tests/fixtures/javascript/directives/non-directive-string.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
if (true) {
"use strict"
}

switch (true) {
case false: {
"use strict"
}
default: {
"use strict"
}
}

while (true) {
"use strict"
}
3 changes: 3 additions & 0 deletions tests/fixtures/javascript/directives/program-order.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";
"use loose";
var a;
3 changes: 3 additions & 0 deletions tests/fixtures/javascript/directives/program.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";
var a = 1;
"use strict";
1 change: 1 addition & 0 deletions tests/fixtures/javascript/directives/raw.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"use\x20strict";
Loading