Skip to content

Commit

Permalink
feat: Add calculation of delta index (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
buehler authored Jul 7, 2017
1 parent fae23f2 commit ec96b70
Show file tree
Hide file tree
Showing 8 changed files with 1,838 additions and 16 deletions.
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

0 comments on commit ec96b70

Please sign in to comment.