From f611307b0c65ccc66fbc046d9ae782ebaba7de87 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Wed, 30 May 2018 15:59:56 -0700 Subject: [PATCH] Fix issue when tsconfig.json has no outfile specified Fix an issues where neither the tsconfig or the ts file would show the build command, when no outfile was specified. --- .../Workspace/TsConfigScannerFactory.cs | 31 +++++++++-------- .../TypeScriptActionProviderFactory.cs | 1 - .../TypeScriptContextProviderFactory.cs | 33 +++++++++++-------- .../Workspace/TypeScriptScannerFactory.cs | 16 +++++++-- 4 files changed, 49 insertions(+), 32 deletions(-) diff --git a/Nodejs/Product/Nodejs/Workspace/TsConfigScannerFactory.cs b/Nodejs/Product/Nodejs/Workspace/TsConfigScannerFactory.cs index 5bc7f4e3b..1e77551d5 100644 --- a/Nodejs/Product/Nodejs/Workspace/TsConfigScannerFactory.cs +++ b/Nodejs/Product/Nodejs/Workspace/TsConfigScannerFactory.cs @@ -42,7 +42,10 @@ protected override async Task> ComputeFileReferencesAsyn var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath); - Debug.Assert(!string.IsNullOrEmpty(tsconfig?.OutFile), "Should have an outfile specified."); + if (string.IsNullOrEmpty(tsconfig.OutFile)) + { + return new List(); + } var tsconfigFolder = Path.GetDirectoryName(filePath); var outFile = Path.Combine(tsconfigFolder, tsconfig.OutFile); @@ -64,7 +67,15 @@ protected override async Task> ComputeFileDataValuesAsync(st var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath); - Debug.Assert(!string.IsNullOrEmpty(tsconfig?.OutFile), "Should have an outfile specified."); + // Only use the tsconfig.json determine the debug target when there is an outfile specified, + // otherwise each .ts file can (in theory) be the entry point. + if (string.IsNullOrEmpty(tsconfig.OutFile)) + { + return new List { + new FileDataValue(BuildConfigurationContext.ContextTypeGuid, filePath, null, + context: "Debug", target: null) + }; + } var tsconfigFolder = Path.GetDirectoryName(filePath); var outFile = Path.Combine(tsconfigFolder, tsconfig.OutFile); @@ -80,8 +91,8 @@ protected override async Task> ComputeFileDataValuesAsync(st new FileDataValue( DebugLaunchActionContext.ContextTypeGuid, DebugLaunchActionContext.IsDefaultStartupProjectEntry, - launchSettings, - target: outFile), + launchSettings, + target: outFile), new FileDataValue(BuildConfigurationContext.ContextTypeGuid, outFile, null, context: "Debug", target: outFile), @@ -93,17 +104,9 @@ protected override async Task> ComputeFileDataValuesAsync(st return fileDataValues; } - protected override async Task IsValidFileAsync(string filePath) + protected override Task IsValidFileAsync(string filePath) { - // Only use the tsconfig.json determine the debug target when there is an outfile specified, - // otherwise each .ts file can (in theory) be the entry point. - if (TypeScriptHelpers.IsTsJsConfigJsonFile(filePath)) - { - var tsconfig = await TsConfigJsonFactory.CreateAsync(filePath); - return !string.IsNullOrEmpty(tsconfig?.OutFile); - } - - return false; + return Task.FromResult(TypeScriptHelpers.IsTsJsConfigJsonFile(filePath)); } } } diff --git a/Nodejs/Product/Nodejs/Workspace/TypeScriptActionProviderFactory.cs b/Nodejs/Product/Nodejs/Workspace/TypeScriptActionProviderFactory.cs index c70cfd05f..5f4506bab 100644 --- a/Nodejs/Product/Nodejs/Workspace/TypeScriptActionProviderFactory.cs +++ b/Nodejs/Product/Nodejs/Workspace/TypeScriptActionProviderFactory.cs @@ -96,7 +96,6 @@ public override async Task ExecuteAsync(IProgress> GetContextsForFileAsync(string fil public async Task> GetContextsForFileAsync(string filePath, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(filePath) || !IsSupportedFile(filePath)) + if (string.IsNullOrEmpty(filePath) || !(await IsSupportedFileAsync(filePath))) { return FileContext.EmptyFileContexts; } - var tsconfigJson = await this.workspace.IsContainedByTsConfig(filePath); - - if (tsconfigJson != null) - { - return FileContext.EmptyFileContexts; - } - - var list = new List + return new List { new FileContext( ProviderTypeGuid, @@ -68,13 +60,26 @@ public async Task> GetContextsForFileAsync(stri new[]{ filePath }, displayName: "TypeScript Build") }; - - return list; } - private static bool IsSupportedFile(string filePath) + private async Task IsSupportedFileAsync(string filePath) { - return TypeScriptHelpers.IsTypeScriptFile(filePath) || TypeScriptHelpers.IsTsJsConfigJsonFile(filePath); + // config files are always good + if (TypeScriptHelpers.IsTsJsConfigJsonFile(filePath)) + { + return true; + } + + // TypeScript files should only build when there is no containing config file + if (TypeScriptHelpers.IsTypeScriptFile(filePath)) + { + if (await this.workspace.IsContainedByTsConfig(filePath) == null) + { + return true; + } + } + + return false; } } } diff --git a/Nodejs/Product/Nodejs/Workspace/TypeScriptScannerFactory.cs b/Nodejs/Product/Nodejs/Workspace/TypeScriptScannerFactory.cs index b8dcfbcf9..c89585a27 100644 --- a/Nodejs/Product/Nodejs/Workspace/TypeScriptScannerFactory.cs +++ b/Nodejs/Product/Nodejs/Workspace/TypeScriptScannerFactory.cs @@ -16,7 +16,7 @@ namespace Microsoft.NodejsTools.Workspace { [ExportFileScanner( ProviderType, "TypeScriptFile", - new string[] { "*.ts" }, + new string[] { "*.ts", "*.tsx" }, new Type[] { typeof(IReadOnlyCollection), typeof(IReadOnlyCollection) }, ProviderPriority.Normal)] public sealed class TypeScriptScannerFactory : IWorkspaceProviderFactory @@ -113,13 +113,23 @@ private async Task DetermineOutFileAsync(string filePath) var rootDir = Path.GetDirectoryName(tsConfig.FilePath); var relativeTsFile = filePath.Substring(rootDir.Length).TrimStart('\\'); // save since we already know they have the same root - return this.workspace.MakeRelative(Path.Combine(rootDir, tsConfig.OutDir, Path.ChangeExtension(relativeTsFile, "js"))); // this works if outdir is null + return this.workspace.MakeRelative(Path.Combine(rootDir, tsConfig.OutDir, ChangeExtension(relativeTsFile))); // this works if outdir is null } else { - return this.workspace.MakeRelative(Path.ChangeExtension(filePath, "js")); + return this.workspace.MakeRelative(ChangeExtension(filePath)); } } + + private static string ChangeExtension(string filePath) + { + if(filePath.EndsWith("tsx", StringComparison.OrdinalIgnoreCase)) + { + return Path.ChangeExtension(filePath, "jsx"); + } + + return Path.ChangeExtension(filePath, "js"); + } } } }