Skip to content

Commit

Permalink
Merge pull request #53 from buehler/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
buehler authored Mar 5, 2018
2 parents ec573e6 + 7d35a16 commit 57a14a5
Show file tree
Hide file tree
Showing 24 changed files with 556 additions and 152 deletions.
8 changes: 6 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ version: "{build} - {branch}"
skip_tags: true
skip_branch_with_pr: true

matrix:
fast_finish: true

environment:
matrix:
- nodejs_version: "9"
- nodejs_version: "8"
- nodejs_version: "7"
- nodejs_version: "6"

install:
- ps: Install-Product node $env:nodejs_version
- npm install

test_script:
- npm test
- npm install -g codecov
- codecov

build: off
55 changes: 32 additions & 23 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
sudo: false
language: node_js

cache:
directories:
- node_modules
stages:
- name: test
if: tag IS blank
- name: deploy
if: branch = master AND type != pull_request

matrix:
fast_finish: true

notifications:
email: false

node_js:
- '8'
- '7'
- '6'

before_script:
- npm prune

after_success:
- npm install coveralls@^2.11.9 && cat ./coverage/lcov.info | coveralls

after_script:
- npm install
- npm run build
- npm run semantic-release

branches:
except:
- /^v\d+\.\d+\.\d+$/
jobs:
include:
- stage: test
node_js: '9'
after_success:
- npm i -g codecov
- codecov
- stage: test
node_js: '8'
after_success:
- npm i -g codecov
- codecov
- stage: deploy
node_js: '9'
script: npm run typedoc
deploy:
provider: pages
skip_cleanup: true
github_token: $GH_TOKEN
local_dir: ./docs
- stage: deploy
node_js: '9'
before_script: npm run build
script: npm run semantic-release
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ a more or less human readable AST out of .js or .ts files.
[![Build Status](https://travis-ci.org/buehler/node-typescript-parser.svg)](https://travis-ci.org/buehler/node-typescript-parser)
[![Build Status Windows](https://ci.appveyor.com/api/projects/status/j06bqjc4tkdt7sej?svg=true)](https://ci.appveyor.com/project/buehler/node-typescript-parser)
[![npm](https://img.shields.io/npm/v/typescript-parser.svg?maxAge=3600)](https://www.npmjs.com/package/typescript-parser)
[![Coverage status](https://img.shields.io/coveralls/buehler/node-typescript-parser.svg?maxAge=3600)](https://coveralls.io/github/buehler/node-typescript-parser)
[![codecov](https://codecov.io/gh/buehler/node-typescript-parser/branch/master/graph/badge.svg)](https://codecov.io/gh/buehler/node-typescript-parser)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![Greenkeeper badge](https://badges.greenkeeper.io/buehler/node-typescript-parser.svg)](https://greenkeeper.io/)
[![Gitter](https://img.shields.io/gitter/room/node-typescript-parser/Lobby.svg)](https://gitter.im/node-typescript-parser/Lobby)

## How to use

Expand All @@ -25,7 +26,7 @@ const parser = new TypescriptParser();
const parsed = await parser.parseSource(/* typescript source code as string */);

// or a filepath
const parsed = await parser.parseSource('/user/myfile.ts', 'workspace root');
const parsed = await parser.parseFile('/user/myfile.ts', 'workspace root');
```

You can also parse multiple files at ones.
Expand All @@ -37,10 +38,10 @@ After the parsing is done, you'll get an index with resolved
exports and declarations.

Keep in mind, that the index'll only contain exported declarations.

## Changelog

The changelog is generated by [semantic release](https://github.com/semantic-release/semantic-release) and is located under the
The changelog is generated by [semantic release](https://github.com/semantic-release/semantic-release) and is located under the
[release section](https://github.com/buehler/node-typescript-parser/releases).

## Licence
Expand Down
1 change: 0 additions & 1 deletion jest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"collectCoverage": true,
"mapCoverage": true,
"transform": {
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
Expand Down
28 changes: 15 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,24 @@
},
"homepage": "https://github.com/TypeScript-Heroes/node-typescript-parser#readme",
"devDependencies": {
"@types/jest": "^21.1.0",
"@smartive/tslint-config": "^2.0.0",
"@types/jest": "^22.1.4",
"@types/lodash-es": "^4.17.0",
"@types/mock-fs": "^3.6.30",
"@types/node": "^8.0.31",
"@types/node": "^9.4.6",
"del-cli": "^1.1.0",
"jest": "^21.2.0",
"mock-fs": "^4.4.1",
"semantic-release": "^9.0.0",
"ts-jest": "^21.0.0",
"tslint": "^5.5.0",
"tslint-config-airbnb": "^5.2.1",
"tsutils": "^2.9.0",
"typedoc": "^0.8.0"
"jest": "^22.4.2",
"mock-fs": "^4.4.2",
"semantic-release": "^15.0.0",
"ts-jest": "^22.4.0",
"tslint": "^5.9.1",
"tsutils": "^2.22.0",
"typedoc": "^0.10.0"
},
"dependencies": {
"lodash": "^4.17.4",
"tslib": "^1.7.1",
"typescript": "^2.5.3"
"lodash": "^4.17.5",
"lodash-es": "^4.17.5",
"tslib": "^1.9.0",
"typescript": "^2.7.2"
}
}
38 changes: 23 additions & 15 deletions src/TypescriptParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,46 +151,54 @@ export class TypescriptParser {
*
* @memberof TsResourceParser
*/
private parse(resource: Resource, node: Node): void {
for (const child of node.getChildren()) {
switch (child.kind) {
private parse(rootResource: Resource, rootNode: Node): void {
let [resource, ...resourceQueue]: Resource[] = Array(rootNode.getChildren().length).fill(rootResource);
let [node, ...nodeQueue]: Node[] = [...rootNode.getChildren()];
while (node) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
parseImport(resource, <ImportDeclaration | ImportEqualsDeclaration>child);
parseImport(resource, <ImportDeclaration | ImportEqualsDeclaration>node);
break;
case SyntaxKind.ExportDeclaration:
case SyntaxKind.ExportAssignment:
parseExport(resource, <ExportAssignment | ExportDeclaration>child);
parseExport(resource, <ExportAssignment | ExportDeclaration>node);
break;
case SyntaxKind.EnumDeclaration:
parseEnum(resource, <EnumDeclaration>child);
parseEnum(resource, <EnumDeclaration>node);
break;
case SyntaxKind.TypeAliasDeclaration:
parseTypeAlias(resource, <TypeAliasDeclaration>child);
parseTypeAlias(resource, <TypeAliasDeclaration>node);
break;
case SyntaxKind.FunctionDeclaration:
parseFunction(resource, <FunctionDeclaration>child);
parseFunction(resource, <FunctionDeclaration>node);
[resource, ...resourceQueue] = resourceQueue;
[node, ...nodeQueue] = nodeQueue;
continue;
case SyntaxKind.VariableStatement:
parseVariable(resource, <VariableStatement>child);
parseVariable(resource, <VariableStatement>node);
break;
case SyntaxKind.InterfaceDeclaration:
parseInterface(resource, <InterfaceDeclaration>child);
parseInterface(resource, <InterfaceDeclaration>node);
break;
case SyntaxKind.ClassDeclaration:
parseClass(resource, <ClassDeclaration>child);
parseClass(resource, <ClassDeclaration>node);
[resource, ...resourceQueue] = resourceQueue;
[node, ...nodeQueue] = nodeQueue;
continue;
case SyntaxKind.Identifier:
parseIdentifier(resource, <Identifier>child);
parseIdentifier(resource, <Identifier>node);
break;
case SyntaxKind.ModuleDeclaration:
const newResource = parseModule(resource, <ModuleDeclaration>child);
this.parse(newResource, child);
const newResource = parseModule(resource, <ModuleDeclaration>node);
[resource, ...resourceQueue] = [...Array(node.getChildren().length).fill(newResource), ...resourceQueue];
[node, ...nodeQueue] = [...node.getChildren(), ...nodeQueue];
continue;
default:
break;
}
this.parse(resource, child);
[resource, ...resourceQueue] = [...Array(node.getChildren().length).fill(resource), ...resourceQueue];
[node, ...nodeQueue] = [...node.getChildren(), ...nodeQueue];
}
}
}
22 changes: 22 additions & 0 deletions src/code-generators/TypescriptGenerationOptions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export enum MultiLineImportRule {
strictlyOneImportPerLine = 'strictlyOneImportPerLine',
oneImportPerLineOnlyAfterThreshold = 'oneImportPerLineOnlyAfterThreshold',
multipleImportsPerLine = 'multipleImportsPerLine',
}

/**
* Typescript generation options type. Contains all information needed to stringify some objects to typescript.
*
Expand Down Expand Up @@ -29,6 +35,14 @@ export interface TypescriptGenerationOptions {
*/
spaceBraces: boolean;

/**
* The wrapping methodology to be used for imports.
*
* @type {MultiLineImportRule}
* @memberof TypescriptGenerationOptions
*/
wrapMethod: MultiLineImportRule;

/**
* The threshold where an import is written as multiline.
*
Expand All @@ -52,4 +66,12 @@ export interface TypescriptGenerationOptions {
* @memberof TypescriptGenerationOptions
*/
tabSize: number;

/**
* Insert spaces instead of tabs (default: true)
*
* @type {boolean}
* @memberof TypescriptGenerationOptions
*/
insertSpaces: boolean;
}
77 changes: 54 additions & 23 deletions src/code-generators/typescript-generators/namedImport.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { NamedImport } from '../../imports/NamedImport';
import { SymbolSpecifier } from '../../SymbolSpecifier';
import { stringTemplate } from '../../utilities/StringTemplate';
import { TypescriptGenerationOptions } from '../TypescriptGenerationOptions';
import { MultiLineImportRule, TypescriptGenerationOptions } from '../TypescriptGenerationOptions';
import { generateSymbolSpecifier } from './symbolSpecifier';

const importTemplate = stringTemplate`import ${0} from ${1}`;
const oneLinerImportTemplate = stringTemplate`import ${0} from ${1}`;

const multiLineImport = stringTemplate`import ${3}{
const multiLineImportTemplate = stringTemplate`import ${3}{
${0}${1}
} from ${2}`;

const defaultAliasOnlyMultiLineImportTemplate = stringTemplate`import ${0}
from ${1}`;

/**
* Sort function for symbol specifiers. Does sort after the specifiers name (to lowercase).
*
Expand All @@ -23,7 +26,8 @@ function specifierSort(i1: SymbolSpecifier, i2: SymbolSpecifier): number {

if (strA < strB) {
return -1;
} else if (strA > strB) {
}
if (strA > strB) {
return 1;
}
return 0;
Expand All @@ -44,34 +48,61 @@ export function generateNamedImport(
stringQuoteStyle,
spaceBraces,
tabSize,
wrapMethod,
multiLineWrapThreshold,
multiLineTrailingComma,
insertSpaces = true,
}: TypescriptGenerationOptions,
): string {
const space = spaceBraces ? ' ' : '';
const lib = `${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`;

const specifiers = imp.specifiers.sort(specifierSort).map(o => generateSymbolSpecifier(o)).join(', ');
let importSpecifiers = `${space}${specifiers}${space}`;
if (importSpecifiers.trim().length === 0) {
importSpecifiers = ' ';
// const specifiers = imp.specifiers.sort(specifierSort).map(o => generateSymbolSpecifier(o)).join(', ');
const oneLinerImportStatement = oneLinerImportTemplate(getImportSpecifiers(imp, spaceBraces), lib);
if (oneLinerImportStatement.length <= multiLineWrapThreshold &&
(wrapMethod !== MultiLineImportRule.strictlyOneImportPerLine ||
imp.specifiers.length <= 1)) {
return oneLinerImportStatement;
}

const importString = importTemplate(
getImportSpecifiers(imp, spaceBraces),
lib,
);

if (importString.length > multiLineWrapThreshold) {
const spacings = Array(tabSize + 1).join(' ');
return multiLineImport(
imp.specifiers.sort(specifierSort).map(o => `${spacings}${generateSymbolSpecifier(o)}`).join(',\n'),
multiLineTrailingComma ? ',' : '',
`${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`,
const defaultAliasOnly: boolean = imp.specifiers.length === 0;
if (defaultAliasOnly) {
return defaultAliasOnlyMultiLineImportTemplate(
imp.defaultAlias ? `${imp.defaultAlias}, ` : '',
`${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`,
);
}
return importString;

const sortedImportSpecifiers: SymbolSpecifier[] = imp.specifiers.sort(specifierSort);
let importSpecifierStrings: string = '';
const indent = insertSpaces ? Array(tabSize + 1).join(' ') : '\t';
if (wrapMethod === MultiLineImportRule.strictlyOneImportPerLine ||
wrapMethod === MultiLineImportRule.oneImportPerLineOnlyAfterThreshold) {
importSpecifierStrings = sortedImportSpecifiers.map(o => `${indent}${generateSymbolSpecifier(o)}`).join(',\n');
} else if (wrapMethod === MultiLineImportRule.multipleImportsPerLine) {
importSpecifierStrings = sortedImportSpecifiers.reduce(
(acc, curr) => {
const symbolSpecifier: string = generateSymbolSpecifier(curr);
// const dist: number = acc.out.length - acc.lastWrapOffset + symbolSpecifier.length;
const importLines = acc.out.split('\n');
const lastImportLine = importLines[importLines.length - 1];
const dist: number = lastImportLine.length + `, `.length + symbolSpecifier.length;
const needsWrap: boolean = dist >= multiLineWrapThreshold;
return {
out: acc.out + (needsWrap ? `,\n${indent}` : (acc.out.length ? `, ` : `${indent}`)) +
symbolSpecifier,
lastWrapOffset: acc.lastWrapOffset + (needsWrap ? dist : 0),
};
},
{
out: '',
lastWrapOffset: 0,
},
).out;
}
return multiLineImportTemplate(
importSpecifierStrings,
multiLineTrailingComma ? ',' : '',
`${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`,
imp.defaultAlias ? `${imp.defaultAlias}, ` : '',
);
}

function getImportSpecifiers(namedImport: NamedImport, spaceBraces: boolean): string {
Expand Down
2 changes: 1 addition & 1 deletion src/node-parser/class-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import { Resource } from '../resources/Resource';
import {
isArrayBindingPattern,
isConstructorDeclaration,
isGetAccessorDeclaration,
isIdentifier,
isMethodDeclaration,
isObjectBindingPattern,
isPropertyDeclaration,
isGetAccessorDeclaration,
isSetAccessorDeclaration,
} from '../type-guards/TypescriptGuards';
import { parseFunctionParts, parseMethodParams } from './function-parser';
Expand Down
Loading

0 comments on commit 57a14a5

Please sign in to comment.