Skip to content

feat: Add calculation of delta index #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 7, 2017
Merged
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
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,20 @@
"homepage": "https://github.com/TypeScript-Heroes/node-typescript-parser#readme",
"devDependencies": {
"@types/jest": "^20.0.1",
"@types/mock-fs": "^3.6.30",
"@types/node": "^8.0.1",
"del-cli": "^1.0.0",
"jest": "^20.0.4",
"mock-fs": "^4.4.1",
"semantic-release": "^6.3.6",
"ts-jest": "^20.0.6",
"tslint": "^5.4.3",
"tslint-config-airbnb": "^5.2.0",
"tsutils": "^2.4.0",
"typedoc": "^0.7.1",
"semantic-release": "^6.3.6"
"typedoc": "^0.7.1"
},
"dependencies": {
"lodash": "^4.17.4",
"tslib": "^1.7.1",
"typescript": "^2.4.1"
}
Expand Down
69 changes: 59 additions & 10 deletions src/DeclarationIndex.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { difference, differenceWith, intersection, isEqual } from 'lodash';
import { join, normalize, relative, resolve } from 'path';

import { DeclarationInfo } from './declarations/DeclarationInfo';
Expand Down Expand Up @@ -34,10 +35,16 @@ function getNodeLibraryName(path: string): string {
*/
type Resources = { [name: string]: Resource };

// export type DeltaIndex = {
// deleted: string[];
// updated: { [declaration: string]: DeclarationInfo[] };
// };
/**
* IndexDelta type, is calculated by the declaration index to give an overview, what has changed in the index.
* Returns a list of deleted declarations, newly added declarations (with the corresponding infos) and
* which declarations have been updated (with all declarations under that name).
*/
export type IndexDelta = {
added: { [declaration: string]: DeclarationInfo[] };
updated: { [declaration: string]: DeclarationInfo[] };
deleted: string[];
};

/**
* Interface for file changes. Contains lists of file uri's to the specific action.
Expand Down Expand Up @@ -119,6 +126,48 @@ export class DeclarationIndex {

constructor(private parser: TypescriptParser, private rootPath: string) { }

/**
* Calculates the differences between two indices. Calculates removed, added and updated declarations.
* The updated declarations are calculated and all declarations that the new index contains are inserted in the list.
*
* @static
* @param {{ [declaration: string]: DeclarationInfo[] }} oldIndex
* @param {{ [declaration: string]: DeclarationInfo[] }} newIndex
* @returns {IndexDelta}
* @memberof DeclarationIndex
*/
public static calculateIndexDelta(
oldIndex: { [declaration: string]: DeclarationInfo[] },
newIndex: { [declaration: string]: DeclarationInfo[] },
): IndexDelta {
const oldKeys = Object.keys(oldIndex);
const newKeys = Object.keys(newIndex);

return {
added: difference(newKeys, oldKeys).reduce(
(obj, currentKey) => {
obj[currentKey] = newIndex[currentKey];
return obj;
},
{} as { [declaration: string]: DeclarationInfo[] },
),
updated: intersection(oldKeys, newKeys).reduce(
(obj, currentKey) => {
const old = oldIndex[currentKey];
const neu = newIndex[currentKey];

if (differenceWith(neu, old, isEqual).length > 0 || differenceWith(old, neu, isEqual).length > 0) {
obj[currentKey] = neu;
}

return obj;
},
{} as { [declaration: string]: DeclarationInfo[] },
),
deleted: difference(oldKeys, newKeys),
};
}

/**
* Resets the whole index. Does delete everything. Period.
* Is useful for unit testing or similar things.
Expand Down Expand Up @@ -159,13 +208,14 @@ export class DeclarationIndex {

/**
* Is called when file events happen. Does reindex for the changed files and creates a new index.
* Returns the differences for the new index.
*
* @param {FileEvent[]} changes
* @returns {Promise<void>}
* @returns {Promise<IndexDelta>}
*
* @memberof DeclarationIndex
*/
public async reindexForChanges(changes: FileChanges): Promise<void> {
public async reindexForChanges(changes: FileChanges): Promise<IndexDelta> {
const rebuildResources: string[] = [];
const removeResources: string[] = [];
const rebuildFiles: string[] = [];
Expand Down Expand Up @@ -212,11 +262,10 @@ export class DeclarationIndex {
for (const key of Object.keys(resources)) {
this.parsedResources[key] = resources[key];
}
const old = this._index || {};
this._index = await this.createIndex(this.parsedResources);
// return {
// deleted: removeResources,
// updated: await this.createIndex(resources),
// };

return DeclarationIndex.calculateIndexDelta(old, this._index);
}

/**
Expand Down
10 changes: 10 additions & 0 deletions test/TypescriptParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ describe('TypescriptParser', () => {
parser = new TypescriptParser();
});

describe('Source parsing', () => {

it('should parse a source code string correctly', async () => {
const parsed = await parser.parseSource(`import {foo} from 'bar'; class Foobar {}; const bar = new Foobar();`);

expect(parsed).toMatchSnapshot();
});

});

describe('Import parsing', () => {

const file = getWorkspaceFile('typescript-parser/importsOnly.ts');
Expand Down
46 changes: 46 additions & 0 deletions test/__snapshots__/TypescriptParser.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -890,3 +890,49 @@ StringImport {
"start": 0,
}
`;

exports[`TypescriptParser Source parsing should parse a source code string correctly 1`] = `
File {
"declarations": Array [
ClassDeclaration {
"end": 40,
"isExported": false,
"methods": Array [],
"name": "Foobar",
"properties": Array [],
"start": 25,
},
VariableDeclaration {
"end": 67,
"isConst": true,
"isExported": false,
"name": "bar",
"start": 42,
"type": undefined,
},
],
"end": 67,
"exports": Array [],
"filePath": "inline.ts",
"imports": Array [
NamedImport {
"end": 24,
"libraryName": "bar",
"specifiers": Array [
SymbolSpecifier {
"alias": undefined,
"specifier": "foo",
},
],
"start": 0,
},
],
"resources": Array [],
"rootPath": "/",
"start": 0,
"usages": Array [
"bar",
"Foobar",
],
}
`;
8 changes: 8 additions & 0 deletions test/code-generators/TypescriptCodeGenerator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { TypescriptCodeGenerator } from '../../src/code-generators/TypescriptCodeGenerator';
import { TypescriptGenerationOptions } from '../../src/code-generators/TypescriptGenerationOptions';
import { ClassDeclaration } from '../../src/declarations';
import { DeclarationVisibility } from '../../src/declarations/DeclarationVisibility';
import { MethodDeclaration } from '../../src/declarations/MethodDeclaration';
import { ParameterDeclaration } from '../../src/declarations/ParameterDeclaration';
import { PropertyDeclaration } from '../../src/declarations/PropertyDeclaration';
import { VariableDeclaration } from '../../src/declarations/VariableDeclaration';
import { NotGeneratableYetError } from '../../src/errors/NotGeneratableYetError';
import { DefaultImport } from '../../src/imports/DefaultImport';
import { ExternalModuleImport } from '../../src/imports/ExternalModuleImport';
import { NamedImport } from '../../src/imports/NamedImport';
Expand Down Expand Up @@ -81,4 +83,10 @@ describe('TypescriptCodeGenerator', () => {
});

}

it('should throw on non generatable element', () => {
const generator = new TypescriptCodeGenerator(defaultOptions);

expect(() => generator.generate(new ClassDeclaration('foo', true))).toThrow(NotGeneratableYetError);
});
});
Loading