Skip to content

Commit 8dec173

Browse files
committed
we now have better cache invalidation. We can also query the parent for non file system changes
closes #130
1 parent 33a8f2a commit 8dec173

10 files changed

+76
-23
lines changed

lib/main/atom/atomUtils.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var path = require('path');
22
var fs = require('fs');
33
var tsconfig = require('../tsconfig/tsconfig');
4-
var _atom = require('atom');
54
function getEditorPosition(editor) {
65
var bufferPos = editor.getCursorBufferPosition();
76
return getEditorPositionForBufferPosition(editor, bufferPos);
@@ -53,7 +52,12 @@ function getRangeForTextSpan(editor, ts) {
5352
var buffer = editor.buffer;
5453
var start = editor.buffer.positionForCharacterIndex(ts.start);
5554
var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length);
56-
var range = new _atom.Range(start, end);
55+
var atom = require('atom');
56+
var range = new atom.Range(start, end);
5757
return range;
5858
}
5959
exports.getRangeForTextSpan = getRangeForTextSpan;
60+
function getTypeScriptEditorsWithPaths() {
61+
return atom.workspace.getEditors().filter(function (editor) { return !!editor.getPath(); }).filter(function (editor) { return (path.extname(editor.getPath()) === '.ts'); });
62+
}
63+
exports.getTypeScriptEditorsWithPaths = getTypeScriptEditorsWithPaths;

lib/main/atom/atomUtils.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
///ts:ref=globals
22
/// <reference path="../../globals.ts"/> ///ts:ref:generated
33

4-
///ts:import=languageServiceHost
5-
import languageServiceHost = require('../lang/languageServiceHost'); ///ts:import:generated
64
import path = require('path');
75
import fs = require('fs');
86
import tsconfig = require('../tsconfig/tsconfig');
9-
import _atom = require('atom');
107

118
// Optimized version where we do not ask this of the languageServiceHost
129
export function getEditorPosition(editor: AtomCore.IEditor): number {
@@ -67,6 +64,14 @@ export function getRangeForTextSpan(editor: AtomCore.IEditor, ts: { start: numbe
6764
var buffer = editor.buffer;
6865
var start = editor.buffer.positionForCharacterIndex(ts.start);
6966
var end = editor.buffer.positionForCharacterIndex(ts.start + ts.length);
70-
var range = new _atom.Range(start, end);
67+
var atom = require('atom');
68+
var range = new atom.Range(start, end);
7169
return range;
7270
}
71+
72+
/** only the editors that are persisted to disk. And are of type TypeScript */
73+
export function getTypeScriptEditorsWithPaths() {
74+
return atom.workspace.getEditors()
75+
.filter(editor=> !!editor.getPath())
76+
.filter(editor=> (path.extname(editor.getPath()) === '.ts'));
77+
}

lib/main/atomts.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function activate(state) {
3939
atom.workspace.onDidChangeActivePaneItem(function (editor) {
4040
if (atomUtils.onDiskAndTs(editor)) {
4141
var filePath = editor.getPath();
42-
parent.updateText({ text: editor.getText(), filePath: filePath }).then(function () { return parent.errorsForFile({ filePath: filePath }); }).then(function (resp) { return errorView.setErrors(filePath, resp.errors); });
42+
parent.errorsForFile({ filePath: filePath }).then(function (resp) { return errorView.setErrors(filePath, resp.errors); });
4343
}
4444
});
4545
editorWatch = atom.workspace.observeTextEditors(function (editor) {

lib/main/atomts.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,11 @@ export function activate(state: PackageState) {
9696
atom.workspace.onDidChangeActivePaneItem((editor: AtomCore.IEditor) => {
9797
if (atomUtils.onDiskAndTs(editor)) {
9898
var filePath = editor.getPath();
99-
// We have an update text here as we are highly aggressive about
100-
// * loading file system changes and invalidating our project cache
101-
// * crashes in the worker
102-
// best to reload stuff on change active tab
103-
parent.updateText({ text: editor.getText(), filePath: filePath })
104-
.then(() => parent.errorsForFile({ filePath: filePath }))
99+
100+
// Refresh errors stuff on change active tab.
101+
// Because the fix might be in the other file
102+
// or the other file might have made this file have an error
103+
parent.errorsForFile({ filePath: filePath })
105104
.then((resp) => errorView.setErrors(filePath, resp.errors));
106105
}
107106
});

lib/main/lang/projectService.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@ var project = require('./project');
77
var Project = project.Project;
88
var resolve = Promise.resolve.bind(Promise);
99
var queryParent = require('../../worker/queryParent');
10-
exports.child;
11-
if (exports.child) {
12-
queryParent.echoNumWithModification = exports.child.sendToIpc(queryParent.echoNumWithModification);
10+
var child;
11+
function fixChild(childInjected) {
12+
child = childInjected;
13+
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification);
14+
queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors);
1315
}
16+
exports.fixChild = fixChild;
1417
var projectByProjectPath = {};
1518
var projectByFilePath = {};
1619
function cacheAndCreateProject(projectFile) {
1720
var project = projectByProjectPath[projectFile.projectFileDirectory] = new Project(projectFile);
1821
projectFile.project.files.forEach(function (file) { return projectByFilePath[file] = project; });
22+
queryParent.getUpdatedTextForUnsavedEditors({}).then(function (resp) {
23+
resp.editors.forEach(function (e) {
24+
project.languageServiceHost.updateScript(e.filePath, e.text);
25+
});
26+
});
1927
return project;
2028
}
2129
function getOrCreateProjectFile(filePath) {

lib/main/lang/projectService.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ import queryParent = require('../../worker/queryParent');
2626
// pushed in by child.ts
2727
// If we are in a child context we patch the functions to execute via IPC.
2828
// Otherwise we would call them directly.
29-
export var child: workerLib.Child;
30-
if (child) {
31-
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification)
29+
var child: workerLib.Child;
30+
export function fixChild(childInjected: typeof child) {
31+
child = childInjected;
32+
queryParent.echoNumWithModification = child.sendToIpc(queryParent.echoNumWithModification);
33+
queryParent.getUpdatedTextForUnsavedEditors = child.sendToIpc(queryParent.getUpdatedTextForUnsavedEditors);
3234
}
3335

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

42-
/** Warning: we are loading the project from file system. This might not match what we have in the editor memory
43-
This is the reason why we aggresively send text to the worker on *Tab Change* and other places
44+
/** We are loading the project from file system.
45+
This might not match what we have in the editor memory, so query those as well
4446
*/
4547
function cacheAndCreateProject(projectFile: tsconfig.TypeScriptProjectFileDetails) {
4648
var project = projectByProjectPath[projectFile.projectFileDirectory] = new Project(projectFile);
4749
projectFile.project.files.forEach((file) => projectByFilePath[file] = project);
50+
51+
// query the parent for unsaved changes
52+
// We do this lazily
53+
queryParent.getUpdatedTextForUnsavedEditors({})
54+
.then(resp=> {
55+
resp.editors.forEach(e=> {
56+
project.languageServiceHost.updateScript(e.filePath, e.text);
57+
});
58+
});
59+
4860
return project;
4961
}
5062

lib/worker/child.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ var workerLib = require('./lib/workerLib');
22
var child = new workerLib.Child();
33
var projectService = require('../main/lang/projectService');
44
child.registerAllFunctionsExportedFromAsResponders(projectService);
5-
projectService.child = child;
5+
projectService.fixChild(child);

lib/worker/child.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ import projectService = require('../main/lang/projectService');
1414
child.registerAllFunctionsExportedFromAsResponders(projectService);
1515

1616
// push in child
17-
projectService.child = child;
17+
projectService.fixChild(child);

lib/worker/queryParent.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1+
var resolve = Promise.resolve.bind(Promise);
2+
var atomUtils = require('../main/atom/atomUtils');
13
function echoNumWithModification(query) {
24
return Promise.resolve({ num: query.num + 10 });
35
}
46
exports.echoNumWithModification = echoNumWithModification;
7+
function getUpdatedTextForUnsavedEditors(query) {
8+
var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(function (editor) { return editor.isModified(); });
9+
return resolve({
10+
editors: editors.map(function (e) {
11+
return { filePath: e.getPath(), text: e.getText() };
12+
})
13+
});
14+
}
15+
exports.getUpdatedTextForUnsavedEditors = getUpdatedTextForUnsavedEditors;

lib/worker/queryParent.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
/// Functions that the parent allows the child to query
22

3+
var resolve: typeof Promise.resolve = Promise.resolve.bind(Promise);
4+
5+
///ts:import=atomUtils
6+
import atomUtils = require('../main/atom/atomUtils'); ///ts:import:generated
7+
38
export function echoNumWithModification(query: { num: number }): Promise<{ num: number }> {
49
return Promise.resolve({ num: query.num + 10 });
510
}
11+
12+
export function getUpdatedTextForUnsavedEditors(query: {}): Promise<{ editors: { filePath: string; text: string }[] }> {
13+
var editors = atomUtils.getTypeScriptEditorsWithPaths().filter(editor => editor.isModified());
14+
return resolve({
15+
editors: editors.map(e=> {
16+
return { filePath: e.getPath(), text: e.getText() }
17+
})
18+
});
19+
}

0 commit comments

Comments
 (0)