Add listFilesOnly command-line option
Msbuild currently uses a combination of `--listFiles` and `--noEmit` to obtain a list of files to be consumed by tsc. However, these two flags don't suppress type checking, the results of which msbuild will never consume. This new switch gives msbuild a faster way to obtain the file list. Note: like `--noEmit`, doesn't make sense in build mode.
This commit is contained in:
parent
a8dc7af271
commit
caf0041f8a
|
@ -29651,7 +29651,7 @@ namespace ts {
|
|||
|
||||
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
|
||||
// no rest parameters \ declaration context \ overload - no codegen impact
|
||||
if (languageVersion >= ScriptTarget.ES2015 || compilerOptions.noEmit || !hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
|
||||
if (languageVersion >= ScriptTarget.ES2015 || shouldSuppressEmit(compilerOptions) || !hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29726,7 +29726,7 @@ namespace ts {
|
|||
|
||||
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) {
|
||||
// No need to check for require or exports for ES6 modules and later
|
||||
if (moduleKind >= ModuleKind.ES2015 || compilerOptions.noEmit) {
|
||||
if (moduleKind >= ModuleKind.ES2015 || shouldSuppressEmit(compilerOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29749,7 +29749,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
|
||||
if (languageVersion >= ScriptTarget.ES2017 || compilerOptions.noEmit || !needCollisionCheckForIdentifier(node, name, "Promise")) {
|
||||
if (languageVersion >= ScriptTarget.ES2017 || shouldSuppressEmit(compilerOptions) || !needCollisionCheckForIdentifier(node, name, "Promise")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -35639,7 +35639,7 @@ namespace ts {
|
|||
return grammarErrorOnNode(node.exclamationToken, Diagnostics.Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation);
|
||||
}
|
||||
|
||||
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
|
||||
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !shouldSuppressEmit(compilerOptions) &&
|
||||
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
|
||||
checkESModuleMarker(node.name);
|
||||
}
|
||||
|
|
|
@ -216,6 +216,13 @@ namespace ts {
|
|||
isCommandLineOnly: true,
|
||||
description: Diagnostics.Print_the_final_configuration_instead_of_building
|
||||
},
|
||||
{
|
||||
name: "listFilesOnly",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Command_line_Options,
|
||||
isCommandLineOnly: true,
|
||||
description: Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing
|
||||
},
|
||||
|
||||
// Basic
|
||||
{
|
||||
|
|
|
@ -4311,6 +4311,10 @@
|
|||
"category": "Message",
|
||||
"code": 6502
|
||||
},
|
||||
"Print names of files that are part of the compilation and then stop processing.": {
|
||||
"category": "Message",
|
||||
"code": 6503
|
||||
},
|
||||
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
|
|
|
@ -332,7 +332,7 @@ namespace ts {
|
|||
// Write build information if applicable
|
||||
if (!buildInfoPath || targetSourceFile || emitSkipped) return;
|
||||
const program = host.getProgramBuildInfo();
|
||||
if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
|
||||
if (host.isEmitBlocked(buildInfoPath) || shouldSuppressEmit(compilerOptions)) {
|
||||
emitSkipped = true;
|
||||
return;
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
|
||||
if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || shouldSuppressEmit(compilerOptions)) {
|
||||
emitSkipped = true;
|
||||
return;
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ namespace ts {
|
|||
onEmitNode: declarationTransform.emitNodeWithNotification,
|
||||
substituteNode: declarationTransform.substituteNode,
|
||||
});
|
||||
const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
|
||||
const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!shouldSuppressEmit(compilerOptions);
|
||||
emitSkipped = emitSkipped || declBlocked;
|
||||
if (!declBlocked || forceDtsEmit) {
|
||||
Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
|
||||
|
|
|
@ -1560,6 +1560,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
Debug.assert(!options.listFilesOnly || !!options.extendedDiagnostics);
|
||||
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
|
||||
}
|
||||
|
||||
|
@ -1582,11 +1583,11 @@ namespace ts {
|
|||
function emitWorker(program: Program, sourceFile: SourceFile | undefined, writeFileCallback: WriteFileCallback | undefined, cancellationToken: CancellationToken | undefined, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
|
||||
let declarationDiagnostics: readonly Diagnostic[] = [];
|
||||
|
||||
if (!forceDtsEmit) {
|
||||
if (options.noEmit) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
}
|
||||
if (options.listFilesOnly || (!forceDtsEmit && shouldSuppressEmit(options))) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
}
|
||||
|
||||
if (!forceDtsEmit) {
|
||||
// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
|
@ -2036,7 +2037,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getGlobalDiagnostics(): SortedReadonlyArray<Diagnostic> {
|
||||
return rootNames.length ? sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
|
||||
return !options.listFilesOnly && rootNames.length
|
||||
? sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice())
|
||||
: emptyArray as any as SortedReadonlyArray<Diagnostic>;
|
||||
}
|
||||
|
||||
function getConfigFileParsingDiagnostics(): readonly Diagnostic[] {
|
||||
|
@ -3089,7 +3092,7 @@ namespace ts {
|
|||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
if (shouldSuppressEmit(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit");
|
||||
}
|
||||
}
|
||||
|
@ -3112,7 +3115,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
|
||||
if (!options.noEmit && !options.suppressOutputPathCheck) {
|
||||
if (!shouldSuppressEmit(options) && !options.suppressOutputPathCheck) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createMap<true>();
|
||||
forEachEmittedFile(emitHost, (emitFileNames) => {
|
||||
|
@ -3181,7 +3184,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function verifyProjectReferences() {
|
||||
const buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined;
|
||||
const buildInfoPath = !shouldSuppressEmit(options) && !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined;
|
||||
forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
|
||||
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const parentFile = parent && parent.sourceFile as JsonSourceFile;
|
||||
|
@ -3322,7 +3325,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isEmittedFile(file: string): boolean {
|
||||
if (options.noEmit) {
|
||||
if (shouldSuppressEmit(options)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ namespace ts {
|
|||
/*@internal*/ preserveWatchOutput?: boolean;
|
||||
/*@internal*/ listEmittedFiles?: boolean;
|
||||
/*@internal*/ listFiles?: boolean;
|
||||
/*@internal*/ listFilesOnly?: boolean;
|
||||
/*@internal*/ pretty?: boolean;
|
||||
incremental?: boolean;
|
||||
|
||||
|
@ -1923,7 +1924,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isOutputFile(state: SolutionBuilderState, fileName: string, configFile: ParsedCommandLine) {
|
||||
if (configFile.options.noEmit) return false;
|
||||
if (shouldSuppressEmit(configFile.options)) return false;
|
||||
|
||||
// ts or tsx files are not output
|
||||
if (!fileExtensionIs(fileName, Extension.Dts) &&
|
||||
|
|
|
@ -4951,6 +4951,7 @@ namespace ts {
|
|||
lib?: string[];
|
||||
/*@internal*/listEmittedFiles?: boolean;
|
||||
/*@internal*/listFiles?: boolean;
|
||||
/*@internal*/listFilesOnly?: boolean;
|
||||
locale?: string;
|
||||
mapRoot?: string;
|
||||
maxNodeModuleJsDepth?: number;
|
||||
|
|
|
@ -7619,6 +7619,14 @@ namespace ts {
|
|||
return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name];
|
||||
}
|
||||
|
||||
export function shouldSuppressEmit(options: CompilerOptions): boolean {
|
||||
return !!options.noEmit || !!options.listFilesOnly;
|
||||
}
|
||||
|
||||
export function shouldListFiles(options: CompilerOptions): boolean {
|
||||
return !!options.listFiles || !!options.listFilesOnly;
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
|
@ -8339,7 +8347,8 @@ namespace ts {
|
|||
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
|
||||
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
|
||||
// '/// <reference no-default-lib="true"/>' directive.
|
||||
return (options.skipLibCheck && sourceFile.isDeclarationFile ||
|
||||
return options.listFilesOnly ||
|
||||
(options.skipLibCheck && sourceFile.isDeclarationFile ||
|
||||
options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) ||
|
||||
host.isSourceOfProjectReferenceRedirect(sourceFile.fileName);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function listFiles(program: ProgramToEmitFilesAndReportErrors, writeFileName: (s: string) => void) {
|
||||
if (program.getCompilerOptions().listFiles) {
|
||||
if (shouldListFiles(program.getCompilerOptions())) {
|
||||
forEach(program.getSourceFiles(), file => {
|
||||
writeFileName(file.fileName);
|
||||
});
|
||||
|
|
|
@ -446,6 +446,23 @@ namespace ts {
|
|||
});
|
||||
});
|
||||
|
||||
it("parse build with listFilesOnly ", () => {
|
||||
// --lib es6 0.ts
|
||||
assertParseResult(["--listFilesOnly"],
|
||||
{
|
||||
errors: [{
|
||||
messageText:"Unknown build option '--listFilesOnly'.",
|
||||
category: Diagnostics.Unknown_build_option_0.category,
|
||||
code: Diagnostics.Unknown_build_option_0.code,
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
projects: ["."],
|
||||
buildOptions: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse multiple flags with input projects at the end", () => {
|
||||
// --lib es5,es2015.symbol.wellknown --target es5 0.ts
|
||||
assertParseResult(["--force", "--verbose", "src", "tests"],
|
||||
|
|
|
@ -207,6 +207,11 @@ namespace ts {
|
|||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
if (commandLine.options.watch && commandLine.options.listFilesOnly) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "listFilesOnly"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
|
||||
if (commandLine.options.project) {
|
||||
if (commandLine.fileNames.length !== 0) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line));
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"listFilesOnly": true
|
||||
}
|
||||
}
|
10
tests/cases/fourslash/listFilesOnly.ts
Normal file
10
tests/cases/fourslash/listFilesOnly.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @listFilesOnly: true
|
||||
|
||||
// @Filename: a.js
|
||||
////const x = 1;
|
||||
|
||||
// Just want to see that no baseline is emitted
|
||||
|
||||
verify.noErrors();
|
Loading…
Reference in a new issue