Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
dfbd4f3
Project References
RyanCavanaugh Mar 8, 2018
f83ad4c
Merge with master
RyanCavanaugh Mar 29, 2018
b0d49f9
Move 'references' up to the 'files' level
RyanCavanaugh Apr 6, 2018
df8df9f
baseline-accept
RyanCavanaugh Apr 6, 2018
4dfe4ee
Remove bad file
RyanCavanaugh Apr 6, 2018
f237834
Remove unuseful error
RyanCavanaugh Apr 6, 2018
d9a354f
Prepend -> UnparsedSource; fix other emitter bugs; bundle_info -> ??
RyanCavanaugh Apr 6, 2018
cdaf625
Proj reference PR cleanup WIP
RyanCavanaugh Apr 7, 2018
a0a3a09
Add undefined check for missing target project
RyanCavanaugh Apr 10, 2018
2e0d200
More fixes
RyanCavanaugh Apr 10, 2018
3990c14
Merge
RyanCavanaugh Apr 10, 2018
ce1082e
Merge updates
RyanCavanaugh Apr 10, 2018
d609921
Switch to using SourceFiles to represent parsed config references
RyanCavanaugh Apr 20, 2018
a5c80aa
Merge branch 'master' into projectReferencesPR
RyanCavanaugh Apr 20, 2018
6ce1285
Merge fixes
RyanCavanaugh Apr 20, 2018
9766ad8
Retain old logic about discarding invalid rootDir settings
RyanCavanaugh Apr 20, 2018
e007de4
Styly
RyanCavanaugh Apr 20, 2018
581a96f
Add JSON ScriptTarget + other fixes
RyanCavanaugh Apr 30, 2018
2f9c51e
Handle JSON files properly in document registry and host cache
RyanCavanaugh Apr 30, 2018
31da17b
Merge branch 'master' into projectReferencesPR
RyanCavanaugh Apr 30, 2018
8bcea60
Properly handle "simplified" results in most places
RyanCavanaugh May 1, 2018
c63de04
Write newlines between prepends; re-order helpers
RyanCavanaugh May 1, 2018
f79c496
Chain through bundling logic in emitter
RyanCavanaugh May 1, 2018
ad3d50e
Move newline
RyanCavanaugh May 1, 2018
431c02d
Lint
RyanCavanaugh May 1, 2018
4bb2e5a
Move file check to verifyCompilerOptions
RyanCavanaugh May 1, 2018
8e76544
PR feedback
RyanCavanaugh May 3, 2018
3346659
Update test
RyanCavanaugh May 3, 2018
6b174af
Merge branch 'master' into projectReferencesPR
RyanCavanaugh May 3, 2018
5c61fb3
Add readDirectory as optional to CompilerHost; update to vfsys
RyanCavanaugh May 3, 2018
8fa80af
lint
RyanCavanaugh May 3, 2018
103bd81
Merge branch 'master' into projectReferencesPR
RyanCavanaugh May 4, 2018
dfbb6a2
PR comments
RyanCavanaugh May 7, 2018
521cff2
Merge
RyanCavanaugh May 7, 2018
784c924
Merge branch 'master' into projectReferencesPR
RyanCavanaugh May 7, 2018
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
17 changes: 16 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2220,7 +2220,22 @@ namespace ts {
}

if (moduleNotFoundError) {
// report errors only if it was requested
// For relative paths, see if this was possibly a projectReference redirect
if (pathIsRelative(moduleReference)) {
const sourceFile = getSourceFileOfNode(location);
const redirects = sourceFile.redirectedReferences;
if (redirects) {
const normalizedTargetPath = getNormalizedAbsolutePath(moduleReference, getDirectoryPath(sourceFile.fileName));
for (const ext of [Extension.Ts, Extension.Tsx]) {
const probePath = normalizedTargetPath + ext;
if (redirects.indexOf(probePath) >= 0) {
error(errorNode, Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, moduleReference, probePath);
return undefined;
}
}
}
}

if (resolutionDiagnostic) {
error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
}
Expand Down
105 changes: 100 additions & 5 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ namespace ts {
category: Diagnostics.Basic_Options,
description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
},
{
name: "composite",
type: "boolean",
isTSConfigOnly: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Enable_project_compilation,
},
{
name: "removeComments",
type: "boolean",
Expand Down Expand Up @@ -814,12 +821,14 @@ namespace ts {
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const projectReferences: ProjectReference[] | undefined = undefined;
const errors: Diagnostic[] = [];

parseStrings(commandLine);
return {
options,
fileNames,
projectReferences,
errors
};

Expand Down Expand Up @@ -933,6 +942,49 @@ namespace ts {
return optionNameMap.get(optionName);
}


export type DiagnosticReporter = (diagnostic: Diagnostic) => void;
/**
* Reports config file diagnostics
*/
export interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}

/**
* Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
*/
export interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
getCurrentDirectory(): string;
}

/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
let configFileText: string;
try {
configFileText = host.readFile(configFileName);
}
catch (e) {
const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}
if (!configFileText) {
const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}

const result = parseJsonText(configFileName, configFileText);
const cwd = host.getCurrentDirectory();
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
}

/**
* Read tsconfig.json file
* @param fileName The path to the config file
Expand Down Expand Up @@ -1008,6 +1060,14 @@ namespace ts {
name: "extends",
type: "string"
},
{
name: "references",
type: "list",
element: {
name: "references",
type: "object"
}
},
{
name: "files",
type: "list",
Expand Down Expand Up @@ -1415,7 +1475,7 @@ namespace ts {
for (let i = 0; i < nameColumn.length; i++) {
const optionName = nameColumn[i];
const description = descriptionColumn[i];
result.push(optionName && `${tab}${tab}${optionName}${ description && (makePadding(marginLength - optionName.length + 2) + description)}`);
result.push(optionName && `${tab}${tab}${optionName}${description && (makePadding(marginLength - optionName.length + 2) + description)}`);
}
if (fileNames.length) {
result.push(`${tab}},`);
Expand Down Expand Up @@ -1499,12 +1559,13 @@ namespace ts {
const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors);
const { raw } = parsedConfig;
const options = extend(existingOptions, parsedConfig.options || {});
options.configFilePath = configFileName;
options.configFilePath = configFileName && normalizeSlashes(configFileName);
setConfigFileInOptions(options, sourceFile);
const { fileNames, wildcardDirectories, spec } = getFileNames();
const { fileNames, wildcardDirectories, spec, projectReferences } = getFileNames();
return {
options,
fileNames,
projectReferences,
typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
raw,
errors,
Expand Down Expand Up @@ -1558,10 +1619,33 @@ namespace ts {
}

const result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0) {
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0 && !hasProperty(raw, "references")) {
errors.push(getErrorForNoInputFiles(result.spec, configFileName));
}

if (hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
if (isArray(raw.references)) {
const references: ProjectReference[] = [];
for (const ref of raw.references) {
if (typeof ref.path !== "string") {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
}
Copy link
Member

Choose a reason for hiding this comment

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

this wont show up error at all in JSON file (with new api) do you have test case to verify this.

Copy link
Member Author

Choose a reason for hiding this comment

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

I wasn't sure how to test this. This call seems to match all the others in the file - what is the new API / what would cause this to not show up?

else {
references.push({
path: getNormalizedAbsolutePath(ref.path, basePath),
originalPath: ref.path,
prepend: ref.prepend,
circular: ref.circular
});
}
}
result.projectReferences = references;
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
}
}

return result;
}

Expand Down Expand Up @@ -1850,6 +1934,9 @@ namespace ts {

const options = getDefaultCompilerOptions(configFileName);
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
if (configFileName) {
options.configFilePath = normalizeSlashes(configFileName);
}
return options;
}

Expand Down Expand Up @@ -2048,7 +2135,7 @@ namespace ts {
// new entries in these paths.
const wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);

const spec: ConfigFileSpecs = { filesSpecs, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
const spec: ConfigFileSpecs = { filesSpecs, referencesSpecs: undefined, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
}

Expand Down Expand Up @@ -2119,8 +2206,16 @@ namespace ts {

const literalFiles = arrayFrom(literalFileMap.values());
const wildcardFiles = arrayFrom(wildcardFileMap.values());
const projectReferences = spec.referencesSpecs && spec.referencesSpecs.map((r): ProjectReference => {
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need this here? This would get updated only when there is update to tsconfig.json. So you shouldnt want this in here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't understand the comment - can you expand on that?

return {
...r,
path: getNormalizedAbsolutePath(r.path, basePath)
};
});

return {
fileNames: literalFiles.concat(wildcardFiles),
projectReferences,
wildcardDirectories,
spec
};
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,10 @@ namespace ts {
: moduleKind === ModuleKind.System;
}

export function getEmitDeclarations(compilerOptions: CompilerOptions): boolean {
return !!(compilerOptions.declaration || compilerOptions.composite);
}

export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";

export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
Expand Down
37 changes: 37 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3552,6 +3552,43 @@
"code": 6197
},

"Projects to reference": {
"category": "Message",
"code": 6300
},
"Enable project compilation": {
"category": "Message",
"code": 6302
},
"Project references may not form a circular graph. Cycle detected: {0}": {
"category": "Error",
"code": 6202
},
"Composite projects may not disable declaration emit.": {
"category": "Error",
"code": 6304
},
"Output file '{0}' has not been built from source file '{1}'.": {
"category": "Error",
"code": 6305
},
"Referenced project '{0}' must have setting \"composite\": true.": {
"category": "Error",
"code": 6306
},
"File '{0}' is not in project file list. Projects must list all files or use an 'include' pattern.": {
"category": "Error",
"code": 6307
},
"Cannot prepend project '{0}' because it does not have 'outFile' set": {
"category": "Error",
"code": 6308
},
"Output file '{0}' from project '{1}' does not exist": {
"category": "Error",
"code": 6309
},

"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down
Loading