Skip to content

Commit

Permalink
we now have better cache invalidation. We can also query the parent f…
Browse files Browse the repository at this point in the history
…or non file system changes

closes #130
  • Loading branch information
basarat committed Feb 27, 2015
1 parent 33a8f2a commit 8dec173
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 23 deletions.
8 changes: 6 additions & 2 deletions lib/main/atom/atomUtils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
var path = require('path');
var fs = require('fs');
var tsconfig = require('../tsconfig/tsconfig');
var _atom = require('atom');
function getEditorPosition(editor) {
var bufferPos = editor.getCursorBufferPosition();
return getEditorPositionForBufferPosition(editor, bufferPos);
Expand Down Expand Up @@ -53,7 +52,12 @@ function getRangeForTextSpan(editor, ts) {
var buffer = editor.buffer;
var start = editor.buffer.positionForCharacterIndex(ts.start);
var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length);
var range = new _atom.Range(start, end);
var atom = require('atom');
var range = new atom.Range(start, end);
return range;
}
exports.getRangeForTextSpan = getRangeForTextSpan;
function getTypeScriptEditorsWithPaths() {
return atom.workspace.getEditors().filter(function (editor) { return !!editor.getPath(); }).filter(function (editor) { return (path.extname(editor.getPath()) === '.ts'); });
}
exports.getTypeScriptEditorsWithPaths = getTypeScriptEditorsWithPaths;
13 changes: 9 additions & 4 deletions lib/main/atom/atomUtils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
///ts:ref=globals
/// <reference path="../../globals.ts"/> ///ts:ref:generated

///ts:import=languageServiceHost
import languageServiceHost = require('../lang/languageServiceHost'); ///ts:import:generated
import path = require('path');
import fs = require('fs');
import tsconfig = require('../tsconfig/tsconfig');
import _atom = require('atom');

// Optimized version where we do not ask this of the languageServiceHost
export function getEditorPosition(editor: AtomCore.IEditor): number {
Expand Down Expand Up @@ -67,6 +64,14 @@ export function getRangeForTextSpan(editor: AtomCore.IEditor, ts: { start: numbe
var buffer = editor.buffer;
var start = editor.buffer.positionForCharacterIndex(ts.start);
var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length);
var range = new _atom.Range(start, end);
var atom = require('atom');
var range = new atom.Range(start, end);
return range;
}

/** only the editors that are persisted to disk. And are of type TypeScript */
export function getTypeScriptEditorsWithPaths() {
return atom.workspace.getEditors()
.filter(editor=> !!editor.getPath())
.filter(editor=> (path.extname(editor.getPath()) === '.ts'));
}
2 changes: 1 addition & 1 deletion lib/main/atomts.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function activate(state) {
atom.workspace.onDidChangeActivePaneItem(function (editor) {
if (atomUtils.onDiskAndTs(editor)) {
var filePath = editor.getPath();
parent.updateText({ text: editor.getText(), filePath: filePath }).then(function () { return parent.errorsForFile({ filePath: filePath }); }).then(function (resp) { return errorView.setErrors(filePath, resp.errors); });
parent.errorsForFile({ filePath: filePath }).then(function (resp) { return errorView.setErrors(filePath, resp.errors); });
}
});
editorWatch = atom.workspace.observeTextEditors(function (editor) {
Expand Down
11 changes: 5 additions & 6 deletions lib/main/atomts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,11 @@ export function activate(state: PackageState) {
atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => {
if (atomUtils.onDiskAndTs(editor)) {
var filePath = editor.getPath();
// We have an update text here as we are highly aggressive about
// * loading file system changes and invalidating our project cache
// * crashes in the worker
// best to reload stuff on change active tab
parent.updateText({ text: editor.getText(), filePath: filePath })
.then(() => parent.errorsForFile({ filePath: filePath }))

// Refresh errors stuff on change active tab.
// Because the fix might be in the other file
// or the other file might have made this file have an error
parent.errorsForFile({ filePath: filePath })
.then((resp) => errorView.setErrors(filePath, resp.errors));
}
});
Expand Down
14 changes: 11 additions & 3 deletions lib/main/lang/projectService.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@ var project = require('./project');
var Project = project.Project;
var resolve = Promise.resolve.bind(Promise);
var queryParent = require('../../worker/queryParent');
exports.child;
if (exports.child) {
queryParent.echoNumWithModification = exports.child.sendToIpc(queryParent.echoNumWithModification);
var child;
function fixChild(childInjected) {
child = childInjected;
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification);
queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors);
}
exports.fixChild = fixChild;
var projectByProjectPath = {};
var projectByFilePath = {};
function cacheAndCreateProject(projectFile) {
var project = projectByProjectPath[projectFile.projectFileDirectory] = new Project(projectFile);
projectFile.project.files.forEach(function (file) { return projectByFilePath[file] = project; });
queryParent.getUpdatedTextForUnsavedEditors({}).then(function (resp) {
resp.editors.forEach(function (e) {
project.languageServiceHost.updateScript(e.filePath, e.text);
});
});
return project;
}
function getOrCreateProjectFile(filePath) {
Expand Down
22 changes: 17 additions & 5 deletions lib/main/lang/projectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import queryParent = require('../../worker/queryParent');
// pushed in by child.ts
// If we are in a child context we patch the functions to execute via IPC.
// Otherwise we would call them directly.
export var child: workerLib.Child;
if (child) {
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification)
var child: workerLib.Child;
export function fixChild(childInjected: typeof child) {
child = childInjected;
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification);
queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors);
}

////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -39,12 +41,22 @@ var projectByProjectPath: { [projectDir: string]: Project } = {}
/** the project file path or any source ts file path */
var projectByFilePath: { [filePath: string]: Project } = {}

/** Warning: we are loading the project from file system. This might not match what we have in the editor memory
This is the reason why we aggresively send text to the worker on *Tab Change* and other places
/** We are loading the project from file system.
This might not match what we have in the editor memory, so query those as well
*/
function cacheAndCreateProject(projectFile: tsconfig.TypeScriptProjectFileDetails) {
var project = projectByProjectPath[projectFile.projectFileDirectory] = new Project(projectFile);
projectFile.project.files.forEach((file) => projectByFilePath[file] = project);

// query the parent for unsaved changes
// We do this lazily
queryParent.getUpdatedTextForUnsavedEditors({})
.then(resp=> {
resp.editors.forEach(e=> {
project.languageServiceHost.updateScript(e.filePath, e.text);
});
});

return project;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/worker/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ var workerLib = require('./lib/workerLib');
var child = new workerLib.Child();
var projectService = require('../main/lang/projectService');
child.registerAllFunctionsExportedFromAsResponders(projectService);
projectService.child = child;
projectService.fixChild(child);
2 changes: 1 addition & 1 deletion lib/worker/child.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ import projectService = require('../main/lang/projectService');
child.registerAllFunctionsExportedFromAsResponders(projectService);

// push in child
projectService.child = child;
projectService.fixChild(child);
11 changes: 11 additions & 0 deletions lib/worker/queryParent.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
var resolve = Promise.resolve.bind(Promise);
var atomUtils = require('../main/atom/atomUtils');
function echoNumWithModification(query) {
return Promise.resolve({ num: query.num + 10 });
}
exports.echoNumWithModification = echoNumWithModification;
function getUpdatedTextForUnsavedEditors(query) {
var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(function (editor) { return editor.isModified(); });
return resolve({
editors: editors.map(function (e) {
return { filePath: e.getPath(), text: e.getText() };
})
});
}
exports.getUpdatedTextForUnsavedEditors = getUpdatedTextForUnsavedEditors;
14 changes: 14 additions & 0 deletions lib/worker/queryParent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
/// Functions that the parent allows the child to query

var resolve: typeof Promise.resolve = Promise.resolve.bind(Promise);

///ts:import=atomUtils
import atomUtils = require('../main/atom/atomUtils'); ///ts:import:generated

export function echoNumWithModification(query: { num: number }): Promise<{ num: number }> {
return Promise.resolve({ num: query.num + 10 });
}

export function getUpdatedTextForUnsavedEditors(query: {}): Promise<{ editors: { filePath: string; text: string }[] }> {
var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(editor => editor.isModified());
return resolve({
editors: editors.map(e=> {
return { filePath: e.getPath(), text: e.getText() }
})
});
}

0 comments on commit 8dec173

Please sign in to comment.