Skip to content

Commit 1a3e6ea

Browse files
authored
Merge pull request #1980 from paulvanbrenk/tsbuildfix
Fix issue when tsconfig.json has no outfile specified
2 parents 017dd05 + f611307 commit 1a3e6ea

File tree

4 files changed

+49
-32
lines changed

4 files changed

+49
-32
lines changed

Nodejs/Product/Nodejs/Workspace/TsConfigScannerFactory.cs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ protected override async Task<List<FileReferenceInfo>> ComputeFileReferencesAsyn
4242

4343
var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath);
4444

45-
Debug.Assert(!string.IsNullOrEmpty(tsconfig?.OutFile), "Should have an outfile specified.");
45+
if (string.IsNullOrEmpty(tsconfig.OutFile))
46+
{
47+
return new List<FileReferenceInfo>();
48+
}
4649

4750
var tsconfigFolder = Path.GetDirectoryName(filePath);
4851
var outFile = Path.Combine(tsconfigFolder, tsconfig.OutFile);
@@ -64,7 +67,15 @@ protected override async Task<List<FileDataValue>> ComputeFileDataValuesAsync(st
6467

6568
var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath);
6669

67-
Debug.Assert(!string.IsNullOrEmpty(tsconfig?.OutFile), "Should have an outfile specified.");
70+
// Only use the tsconfig.json determine the debug target when there is an outfile specified,
71+
// otherwise each .ts file can (in theory) be the entry point.
72+
if (string.IsNullOrEmpty(tsconfig.OutFile))
73+
{
74+
return new List<FileDataValue> {
75+
new FileDataValue(BuildConfigurationContext.ContextTypeGuid, filePath, null,
76+
context: "Debug", target: null)
77+
};
78+
}
6879

6980
var tsconfigFolder = Path.GetDirectoryName(filePath);
7081
var outFile = Path.Combine(tsconfigFolder, tsconfig.OutFile);
@@ -80,8 +91,8 @@ protected override async Task<List<FileDataValue>> ComputeFileDataValuesAsync(st
8091
new FileDataValue(
8192
DebugLaunchActionContext.ContextTypeGuid,
8293
DebugLaunchActionContext.IsDefaultStartupProjectEntry,
83-
launchSettings,
84-
target: outFile),
94+
launchSettings,
95+
target: outFile),
8596

8697
new FileDataValue(BuildConfigurationContext.ContextTypeGuid, outFile, null,
8798
context: "Debug", target: outFile),
@@ -93,17 +104,9 @@ protected override async Task<List<FileDataValue>> ComputeFileDataValuesAsync(st
93104
return fileDataValues;
94105
}
95106

96-
protected override async Task<bool> IsValidFileAsync(string filePath)
107+
protected override Task<bool> IsValidFileAsync(string filePath)
97108
{
98-
// Only use the tsconfig.json determine the debug target when there is an outfile specified,
99-
// otherwise each .ts file can (in theory) be the entry point.
100-
if (TypeScriptHelpers.IsTsJsConfigJsonFile(filePath))
101-
{
102-
var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath);
103-
return !string.IsNullOrEmpty(tsconfig?.OutFile);
104-
}
105-
106-
return false;
109+
return Task.FromResult(TypeScriptHelpers.IsTsJsConfigJsonFile(filePath));
107110
}
108111
}
109112
}

Nodejs/Product/Nodejs/Workspace/TypeScriptActionProviderFactory.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public override async Task<IFileContextActionResult> ExecuteAsync(IProgress<IFil
9696
}
9797
}
9898

99-
10099
private sealed class BuildTsConfigContextAction : BuildFileContextAction, IFileContextAction, IVsCommandItem
101100
{
102101
public BuildTsConfigContextAction(string filePath, FileContext fileContext, OutputPaneWrapper outputPane)

Nodejs/Product/Nodejs/Workspace/TypeScriptContextProviderFactory.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
using System;
44
using System.Collections.Generic;
5-
using System.IO;
65
using System.Threading;
76
using System.Threading.Tasks;
87
using Microsoft.NodejsTools.TypeScript;
@@ -47,19 +46,12 @@ public Task<IReadOnlyCollection<FileContext>> GetContextsForFileAsync(string fil
4746

4847
public async Task<IReadOnlyCollection<FileContext>> GetContextsForFileAsync(string filePath, CancellationToken cancellationToken)
4948
{
50-
if (string.IsNullOrEmpty(filePath) || !IsSupportedFile(filePath))
49+
if (string.IsNullOrEmpty(filePath) || !(await IsSupportedFileAsync(filePath)))
5150
{
5251
return FileContext.EmptyFileContexts;
5352
}
5453

55-
var tsconfigJson = await this.workspace.IsContainedByTsConfig(filePath);
56-
57-
if (tsconfigJson != null)
58-
{
59-
return FileContext.EmptyFileContexts;
60-
}
61-
62-
var list = new List<FileContext>
54+
return new List<FileContext>
6355
{
6456
new FileContext(
6557
ProviderTypeGuid,
@@ -68,13 +60,26 @@ public async Task<IReadOnlyCollection<FileContext>> GetContextsForFileAsync(stri
6860
new[]{ filePath },
6961
displayName: "TypeScript Build")
7062
};
71-
72-
return list;
7363
}
7464

75-
private static bool IsSupportedFile(string filePath)
65+
private async Task<bool> IsSupportedFileAsync(string filePath)
7666
{
77-
return TypeScriptHelpers.IsTypeScriptFile(filePath) || TypeScriptHelpers.IsTsJsConfigJsonFile(filePath);
67+
// config files are always good
68+
if (TypeScriptHelpers.IsTsJsConfigJsonFile(filePath))
69+
{
70+
return true;
71+
}
72+
73+
// TypeScript files should only build when there is no containing config file
74+
if (TypeScriptHelpers.IsTypeScriptFile(filePath))
75+
{
76+
if (await this.workspace.IsContainedByTsConfig(filePath) == null)
77+
{
78+
return true;
79+
}
80+
}
81+
82+
return false;
7883
}
7984
}
8085
}

Nodejs/Product/Nodejs/Workspace/TypeScriptScannerFactory.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Microsoft.NodejsTools.Workspace
1616
{
1717
[ExportFileScanner(
1818
ProviderType, "TypeScriptFile",
19-
new string[] { "*.ts" },
19+
new string[] { "*.ts", "*.tsx" },
2020
new Type[] { typeof(IReadOnlyCollection<FileDataValue>), typeof(IReadOnlyCollection<FileReferenceInfo>) },
2121
ProviderPriority.Normal)]
2222
public sealed class TypeScriptScannerFactory : IWorkspaceProviderFactory<IFileScanner>
@@ -113,13 +113,23 @@ private async Task<string> DetermineOutFileAsync(string filePath)
113113
var rootDir = Path.GetDirectoryName(tsConfig.FilePath);
114114
var relativeTsFile = filePath.Substring(rootDir.Length).TrimStart('\\'); // save since we already know they have the same root
115115

116-
return this.workspace.MakeRelative(Path.Combine(rootDir, tsConfig.OutDir, Path.ChangeExtension(relativeTsFile, "js"))); // this works if outdir is null
116+
return this.workspace.MakeRelative(Path.Combine(rootDir, tsConfig.OutDir, ChangeExtension(relativeTsFile))); // this works if outdir is null
117117
}
118118
else
119119
{
120-
return this.workspace.MakeRelative(Path.ChangeExtension(filePath, "js"));
120+
return this.workspace.MakeRelative(ChangeExtension(filePath));
121121
}
122122
}
123+
124+
private static string ChangeExtension(string filePath)
125+
{
126+
if(filePath.EndsWith("tsx", StringComparison.OrdinalIgnoreCase))
127+
{
128+
return Path.ChangeExtension(filePath, "jsx");
129+
}
130+
131+
return Path.ChangeExtension(filePath, "js");
132+
}
123133
}
124134
}
125135
}

0 commit comments

Comments
 (0)