Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,13 @@ namespace ts {
return sortAndDeduplicateDiagnostics(diagnostics);
}

export function formatDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): string {
export interface FormatDiagnosticsHost {
Copy link
Copy Markdown
Contributor

@mihailik mihailik Jul 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please clarify this interface? Thanks a lot!

  • It's a contract between which part of the system and which other part?
  • Who is meant to provide the implementation?
  • Do existing host scenarios need to do anything?
  • Maybe a use case please?

Sorry for being inquisitive, but there are a few other *Host interfaces at various levels of abstraction, it becomes harder to follow. Please give us a picture why FormatDiagnosticsHost is there, beyond self-evident 'to deal with diagnostic formatting'. I am sure others will benefit from the same, especially where TS is an embedded library.

Many thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a subset of CompilerHost/sys functionality - specifically the minimal subset needed to properly format diagnostics. Like how use use ModuleResolutionHost to indicate where we need the minimal functionality for resolving modules. Grouping the methods needed into a "host" like this is simply cleaner than passing in a collection of arguments or closures directly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @weswigham!

Although that sort of rephrases "Format Diagnostics Host" rather than answers any of the questions above ;-)

getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
getNewLine(): string;
}

export function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
let output = "";

for (const diagnostic of diagnostics) {
Expand Down
38 changes: 24 additions & 14 deletions src/compiler/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@ namespace ts {
fileWatcher?: FileWatcher;
}

let reportDiagnostic = reportDiagnosticSimply;
const defaultFormatDiagnosticsHost: FormatDiagnosticsHost = {
getCurrentDirectory: () => sys.getCurrentDirectory(),
getNewLine: () => sys.newLine,
getCanonicalFileName: createGetCanonicalFileName(sys.useCaseSensitiveFileNames)
};

let reportDiagnosticWorker = reportDiagnosticSimply;
Copy link
Copy Markdown
Contributor

@yuit yuit Jul 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: why you are doing this instead of just call reportDiagnosticSimply directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because reportDiagnosticWorker can be either reportDiagnosticSimply or reportDiagnosticWithColorAndContext if pretty option is set


function reportDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost) {
reportDiagnosticWorker(diagnostic, host || defaultFormatDiagnosticsHost);
}

function reportDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): void {
function reportDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): void {
for (const diagnostic of diagnostics) {
reportDiagnostic(diagnostic, host);
}
Expand Down Expand Up @@ -101,7 +111,7 @@ namespace ts {
return <string>diagnostic.messageText;
}

function reportDiagnosticSimply(diagnostic: Diagnostic, host: CompilerHost): void {
function reportDiagnosticSimply(diagnostic: Diagnostic, host: FormatDiagnosticsHost): void {
sys.write(ts.formatDiagnostics([diagnostic], host));
}

Expand All @@ -122,7 +132,7 @@ namespace ts {
return formatStyle + text + resetEscapeSequence;
}

function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: CompilerHost): void {
function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: FormatDiagnosticsHost): void {
let output = "";

if (diagnostic.file) {
Expand Down Expand Up @@ -257,7 +267,7 @@ namespace ts {

if (commandLine.options.locale) {
if (!isJSONSupported()) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale"), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale"), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
validateLocaleAndSetLanguage(commandLine.options.locale, commandLine.errors);
Expand Down Expand Up @@ -288,26 +298,26 @@ namespace ts {

if (commandLine.options.project) {
if (!isJSONSupported()) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"), /* host */ undefined);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think use /formatDiagnosticsHost/ will be more clear

return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
if (commandLine.fileNames.length !== 0) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}

const fileOrDirectory = normalizePath(commandLine.options.project);
if (!fileOrDirectory /* current directory "." */ || sys.directoryExists(fileOrDirectory)) {
configFileName = combinePaths(fileOrDirectory, "tsconfig.json");
if (!sys.fileExists(configFileName)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
}
else {
configFileName = fileOrDirectory;
if (!sys.fileExists(configFileName)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
}
Expand All @@ -325,7 +335,7 @@ namespace ts {

if (isWatchSet(commandLine.options)) {
if (!sys.watchFile) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
if (configFileName) {
Expand Down Expand Up @@ -378,7 +388,7 @@ namespace ts {
}
if (isWatchSet(configParseResult.options)) {
if (!sys.watchFile) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* host */ undefined);
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}

Expand Down Expand Up @@ -417,7 +427,7 @@ namespace ts {
}

if (compilerOptions.pretty) {
reportDiagnostic = reportDiagnosticWithColorAndContext;
reportDiagnosticWorker = reportDiagnosticWithColorAndContext;
}

// reset the cache of existing files
Expand Down Expand Up @@ -742,7 +752,7 @@ namespace ts {
const currentDirectory = sys.getCurrentDirectory();
const file = normalizePath(combinePaths(currentDirectory, "tsconfig.json"));
if (sys.fileExists(file)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* host */ undefined);
}
else {
const compilerOptions = extend(options, defaultInitCompilerOptions);
Expand All @@ -762,7 +772,7 @@ namespace ts {
}

sys.writeFile(file, JSON.stringify(configurations, undefined, 4));
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* compilerHost */ undefined);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined);
}

return;
Expand Down