Skip to content

Commit e57a8ae

Browse files
committed
Use SubMonitor + Open TypeScript file if needed when compilation is
done. See #142 (comment)
1 parent 093beff commit e57a8ae

File tree

4 files changed

+88
-43
lines changed

4 files changed

+88
-43
lines changed

eclipse/ts.eclipse.ide.core/src/ts/eclipse/ide/core/builder/TypeScriptBuilder.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ public boolean visit(IResourceDelta delta) throws CoreException {
260260
});
261261

262262
try {
263-
tsProject.compileWithTsserver(updatedTsFiles, removedTsFiles, monitor);
263+
if (updatedTsFiles.size() > 0 || removedTsFiles.size() > 0) {
264+
tsProject.compileWithTsserver(updatedTsFiles, removedTsFiles, monitor);
265+
}
264266
} catch (TypeScriptException e) {
265267
throw new CoreException(new Status(IStatus.ERROR, TypeScriptCorePlugin.PLUGIN_ID,
266268
"Error while compiling with tsserver", e));

eclipse/ts.eclipse.ide.core/src/ts/eclipse/ide/internal/core/TypeScriptCoreMessages.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ public class TypeScriptCoreMessages extends NLS {
3737

3838
// Launch
3939
public static String TypeScriptCompilerLaunchConfigurationDelegate_invalidBuildPath;
40-
40+
41+
// TypeScript Compiler builder
42+
public static String IDETypeScriptProject_compile_task;
43+
public static String IDETypeScriptProject_compile_collecting_step;
44+
public static String IDETypeScriptProject_compile_compiling_step;
45+
4146
public static ResourceBundle getResourceBundle() {
4247
try {
4348
if (fResourceBundle == null)

eclipse/ts.eclipse.ide.core/src/ts/eclipse/ide/internal/core/TypeScriptCoreMessages.properties

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ tsconfig_cannot_use_compileOnSave_with_outFile_error=TypeScript file cannot be c
2020
tsconfig_cannot_use_compileOnSave_with_path_mapping_error=TypeScript file cannot be compiled on save because tsconfig.json uses path mapping features ("paths", "rootDirs"). If this is not intended, please set "buildOnSave" to "true" of your "{0}" file.
2121

2222
# Launch
23-
TypeScriptCompilerLaunchConfigurationDelegate_invalidBuildPath=The tsconfig file {0} does not exist for the compiler launch named {1}.
23+
TypeScriptCompilerLaunchConfigurationDelegate_invalidBuildPath=The tsconfig file {0} does not exist for the compiler launch named {1}.
24+
25+
# TypeScript Compiler builder
26+
IDETypeScriptProject_compile_task=TypeScript compilation
27+
IDETypeScriptProject_compile_collecting_step=Collecting TypeScript files to compile...
28+
IDETypeScriptProject_compile_compiling_step=Compiling collected TypeScript files...

eclipse/ts.eclipse.ide.core/src/ts/eclipse/ide/internal/core/resources/IDETypeScriptProject.java

+73-40
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
import java.util.Map;
1919
import java.util.concurrent.ExecutionException;
2020
import java.util.concurrent.TimeUnit;
21+
import java.util.concurrent.TimeoutException;
2122

2223
import org.eclipse.core.resources.IFile;
2324
import org.eclipse.core.resources.IMarker;
2425
import org.eclipse.core.resources.IProject;
2526
import org.eclipse.core.resources.IResource;
2627
import org.eclipse.core.runtime.CoreException;
2728
import org.eclipse.core.runtime.IProgressMonitor;
29+
import org.eclipse.core.runtime.OperationCanceledException;
30+
import org.eclipse.core.runtime.SubMonitor;
2831
import org.eclipse.jface.text.IDocument;
2932

3033
import ts.TypeScriptException;
@@ -51,6 +54,7 @@
5154
import ts.eclipse.ide.core.utils.TypeScriptResourceUtil;
5255
import ts.eclipse.ide.core.utils.WorkbenchResourceUtil;
5356
import ts.eclipse.ide.internal.core.Trace;
57+
import ts.eclipse.ide.internal.core.TypeScriptCoreMessages;
5458
import ts.eclipse.ide.internal.core.compiler.IDETypeScriptCompiler;
5559
import ts.eclipse.ide.internal.core.console.TypeScriptConsoleConnectorManager;
5660
import ts.eclipse.ide.internal.core.resources.jsonconfig.JsonConfigResourcesManager;
@@ -376,19 +380,19 @@ protected ITypeScriptLint createTslint(File tslintFile, File tslintJsonFile, Fil
376380
@Override
377381
public void compileWithTsserver(List<IFile> updatedTsFiles, List<IFile> removedTsFiles, IProgressMonitor monitor)
378382
throws TypeScriptException {
383+
SubMonitor subMonitor = SubMonitor.convert(monitor);
384+
subMonitor.beginTask(TypeScriptCoreMessages.IDETypeScriptProject_compile_task, 100);
385+
List<IFile> tsFilesToClose = new ArrayList<>();
379386
try {
380387
List<String> tsFilesToCompile = new ArrayList<>();
381388
// Collect ts files to compile by using tsserver to retrieve
382389
// dependencies files.
383390
// It works only if tsconfig.json declares "compileOnSave: true".
384-
if (collectTsFilesToCompile(updatedTsFiles, getClient(), tsFilesToCompile, false, monitor)) {
385-
return;
386-
}
391+
collectTsFilesToCompile(updatedTsFiles, tsFilesToCompile, tsFilesToClose, getClient(), subMonitor);
387392

388393
// Compile ts files with tsserver.
389-
if (compileTsFiles(tsFilesToCompile, getClient(), monitor)) {
390-
return;
391-
}
394+
compileTsFiles(tsFilesToCompile, getClient(), subMonitor);
395+
392396
if (removedTsFiles.size() > 0) {
393397
// ts files was removed, how to get referenced files which must
394398
// be recompiled (with errors)?
@@ -397,54 +401,84 @@ public void compileWithTsserver(List<IFile> updatedTsFiles, List<IFile> removedT
397401
throw e;
398402
} catch (Exception e) {
399403
throw new TypeScriptException(e);
404+
} finally {
405+
for (IFile tsFile : tsFilesToClose) {
406+
closeFile(tsFile);
407+
}
408+
subMonitor.done();
400409
}
401410
}
402411

403412
/**
404413
* Collect ts files to compile from the given ts files list.
405414
*
406-
* @param tsFiles
407-
* @param client
415+
* @param updatedTsFiles
416+
* list of TypeScript files which have changed.
408417
* @param tsFilesToCompile
409-
* @param exclude
410-
* @param monitor
418+
* list of collected ts files to compile.
419+
* @param tsFilesToClose
420+
* list of ts files to close.
421+
* @param client
422+
* @param subMonitor
411423
* @throws Exception
412424
*/
413-
private boolean collectTsFilesToCompile(List<IFile> tsFiles, ITypeScriptServiceClient client,
414-
List<String> tsFilesToCompile, boolean exclude, IProgressMonitor monitor) throws Exception {
415-
for (IFile tsFile : tsFiles) {
416-
if (monitor.isCanceled()) {
417-
return true;
418-
}
425+
private void collectTsFilesToCompile(List<IFile> updatedTsFiles, List<String> tsFilesToCompile,
426+
List<IFile> tsFilesToClose, ITypeScriptServiceClient client, SubMonitor subMonitor) throws Exception {
427+
SubMonitor loopMonitor = subMonitor.newChild(50).setWorkRemaining(updatedTsFiles.size());// subMonitor.split(50).setWorkRemaining(updatedTsFiles.size());
428+
loopMonitor.subTask(TypeScriptCoreMessages.IDETypeScriptProject_compile_collecting_step);
429+
for (IFile tsFile : updatedTsFiles) {
419430
String filename = WorkbenchResourceUtil.getFileName(tsFile);
420431
if (!tsFilesToCompile.contains(filename)) {
421-
collectTsFilesToCompile(filename, client, tsFilesToCompile, exclude);
432+
collectTsFilesToCompile(filename, client, tsFilesToCompile, tsFilesToClose, loopMonitor);
433+
}
434+
if (loopMonitor.isCanceled()) {
435+
throw new OperationCanceledException();
422436
}
437+
loopMonitor.worked(1);
438+
// loopMonitor.split(1);
423439
}
424-
return false;
440+
subMonitor.setWorkRemaining(50);
425441
}
426442

427443
/**
428-
* Collect ts files to compile from the given ts file name.
444+
* Collect ts files to compile from the given TypeScript file.
429445
*
430446
* @param filename
431447
* @param client
432448
* @param tsFilesToCompile
433-
* @param exclude
449+
* @param tsFilesToClose
450+
* @param monitor
434451
* @throws Exception
435452
*/
436453
private void collectTsFilesToCompile(String filename, ITypeScriptServiceClient client,
437-
List<String> tsFilesToCompile, boolean exclude) throws Exception {
438-
// call tsserver compileOnSaveAffectedFileList to retrieve file
439-
// dependencies of the given filename
440-
List<CompileOnSaveAffectedFileListSingleProject> affectedProjects = client
441-
.compileOnSaveAffectedFileList(filename).get(5000, TimeUnit.MILLISECONDS);
442-
for (CompileOnSaveAffectedFileListSingleProject affectedProject : affectedProjects) {
443-
List<String> affectedTsFilenames = affectedProject.getFileNames();
444-
for (String affectedFilename : affectedTsFilenames) {
445-
if (!tsFilesToCompile.contains(affectedFilename) && !(exclude && filename.equals(affectedFilename))) {
446-
tsFilesToCompile.add(affectedFilename);
454+
List<String> tsFilesToCompile, List<IFile> tsFilesToClose, IProgressMonitor monitor) throws Exception {
455+
while (!monitor.isCanceled()) {
456+
try {
457+
// When tsserver is not started, it takes time, we try to collect TypeScript
458+
// files every time and stop the search if user stops the builder.
459+
List<CompileOnSaveAffectedFileListSingleProject> affectedProjects = client
460+
.compileOnSaveAffectedFileList(filename).get(2000, TimeUnit.MILLISECONDS);
461+
if (affectedProjects.size() == 0 && getOpenedFile(filename) == null) {
462+
// Case when none TypeScript files are opened.
463+
// In this case, compileOnSaveAffectedFileList returns null, the tsserver needs
464+
// having just one opened TypeScript file
465+
// in order to compileOnSaveAffectedFileList returns the well list.
466+
IFile tsFile = WorkbenchResourceUtil.findFileFromWorkspace(filename);
467+
openFile(tsFile, null);
468+
tsFilesToClose.add(tsFile);
469+
affectedProjects = client.compileOnSaveAffectedFileList(filename).get(2000, TimeUnit.MILLISECONDS);
470+
}
471+
for (CompileOnSaveAffectedFileListSingleProject affectedProject : affectedProjects) {
472+
List<String> affectedTsFilenames = affectedProject.getFileNames();
473+
for (String affectedFilename : affectedTsFilenames) {
474+
if (!tsFilesToCompile.contains(affectedFilename)) {
475+
tsFilesToCompile.add(affectedFilename);
476+
}
477+
}
447478
}
479+
return;
480+
} catch (TimeoutException e) {
481+
448482
}
449483
}
450484
}
@@ -454,28 +488,27 @@ private void collectTsFilesToCompile(String filename, ITypeScriptServiceClient c
454488
*
455489
* @param tsFilesToCompile
456490
* @param client
457-
* @param monitor
458-
* @return true if process must be stopped and false otherwise.
491+
* @param subMonitor
459492
* @throws Exception
460493
*/
461-
private boolean compileTsFiles(List<String> tsFilesToCompile, ITypeScriptServiceClient client,
462-
IProgressMonitor monitor) throws Exception {
494+
private void compileTsFiles(List<String> tsFilesToCompile, ITypeScriptServiceClient client, SubMonitor subMonitor)
495+
throws Exception {
496+
SubMonitor loopMonitor = subMonitor.newChild(50).setWorkRemaining(tsFilesToCompile.size());// subMonitor.split(50).setWorkRemaining(tsFilesToCompile.size());
497+
loopMonitor.subTask(TypeScriptCoreMessages.IDETypeScriptProject_compile_compiling_step);
463498
for (String filename : tsFilesToCompile) {
464-
if (monitor.isCanceled()) {
465-
return true;
466-
}
467499
try {
468500
compileTsFile(filename, client);
501+
loopMonitor.worked(1);
502+
// loopMonitor.split(1);
469503
} catch (ExecutionException e) {
470504
if (e.getCause() instanceof TypeScriptNoContentAvailableException) {
471505
// Ignore "No content available" error.
472-
}
473-
else {
506+
} else {
474507
throw e;
475508
}
476509
}
477510
}
478-
return false;
511+
subMonitor.setWorkRemaining(100);
479512
}
480513

481514
/**

0 commit comments

Comments
 (0)