mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #12336 from Microsoft/ownJsonParsing
Use parser to parse tsconfig json instead of using Json.parse
This commit is contained in:
@@ -27,6 +27,12 @@ namespace ts {
|
||||
return symbol.id;
|
||||
}
|
||||
|
||||
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
|
||||
const moduleState = getModuleInstanceState(node);
|
||||
return moduleState === ModuleInstanceState.Instantiated ||
|
||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||
}
|
||||
|
||||
export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker {
|
||||
// Cancellation that controls whether or not we can cancel in the middle of type checking.
|
||||
// In general cancelling is *not* safe for the type checker. We might be in the middle of
|
||||
|
||||
+629
-161
File diff suppressed because it is too large
Load Diff
@@ -2139,6 +2139,8 @@ namespace ts {
|
||||
return ScriptKind.TS;
|
||||
case Extension.Tsx:
|
||||
return ScriptKind.TSX;
|
||||
case ".json":
|
||||
return ScriptKind.JSON;
|
||||
default:
|
||||
return ScriptKind.Unknown;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"Unterminated string literal.": {
|
||||
"category": "Error",
|
||||
"code": 1002
|
||||
@@ -899,6 +899,14 @@
|
||||
"category": "Error",
|
||||
"code": 1326
|
||||
},
|
||||
"String literal with double quotes expected.": {
|
||||
"category": "Error",
|
||||
"code": 1327
|
||||
},
|
||||
"Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": {
|
||||
"category": "Error",
|
||||
"code": 1328
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -8,6 +8,70 @@ namespace ts {
|
||||
const delimiters = createDelimiterMap();
|
||||
const brackets = createBracketsMap();
|
||||
|
||||
/*@internal*/
|
||||
/**
|
||||
* Iterates over the source files that are expected to have an emit output.
|
||||
*
|
||||
* @param host An EmitHost.
|
||||
* @param action The action to execute.
|
||||
* @param sourceFilesOrTargetSourceFile
|
||||
* If an array, the full list of source files to emit.
|
||||
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
|
||||
*/
|
||||
export function forEachEmittedFile(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
|
||||
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
|
||||
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
|
||||
const options = host.getCompilerOptions();
|
||||
if (options.outFile || options.out) {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : "";
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
||||
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
||||
}
|
||||
|
||||
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
||||
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
||||
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
||||
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension {
|
||||
if (options.jsx === JsxEmit.Preserve) {
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
||||
// TypeScript source file preserving JSX syntax
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
return Extension.Js;
|
||||
}
|
||||
|
||||
function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
|
||||
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
|
||||
}
|
||||
return getOriginalSourceFile(sourceFileOrBundle);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
|
||||
|
||||
@@ -2287,14 +2287,6 @@ namespace ts {
|
||||
return range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets flags that control emit behavior of a node.
|
||||
*/
|
||||
export function getEmitFlags(node: Node): EmitFlags | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets flags that control emit behavior of a node.
|
||||
*/
|
||||
@@ -3809,16 +3801,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function skipPartiallyEmittedExpressions(node: Expression): Expression;
|
||||
export function skipPartiallyEmittedExpressions(node: Node): Node;
|
||||
export function skipPartiallyEmittedExpressions(node: Node) {
|
||||
while (node.kind === SyntaxKind.PartiallyEmittedExpression) {
|
||||
node = (<PartiallyEmittedExpression>node).expression;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) {
|
||||
switch (outerExpression.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression: return updateParen(outerExpression, expression);
|
||||
@@ -4239,177 +4221,4 @@ namespace ts {
|
||||
Debug.assertNode(node, isExpression);
|
||||
return <Expression>node;
|
||||
}
|
||||
|
||||
export interface ExternalModuleInfo {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Identifier[][]; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMultiMap<ExportSpecifier>();
|
||||
const exportedBindings: Identifier[][] = [];
|
||||
const uniqueExports = createMap<boolean>();
|
||||
let exportedNames: Identifier[];
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
|
||||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// import "mod"
|
||||
// import x from "mod"
|
||||
// import * as x from "mod"
|
||||
// import { x, y } from "mod"
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (!(<ExportDeclaration>node).exportClause) {
|
||||
// export * from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else {
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports.get(specifier.name.text)) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(name.text, specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports.set(specifier.name.text, true);
|
||||
exportedNames = append(exportedNames, specifier.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals && !exportEquals) {
|
||||
// export = x
|
||||
exportEquals = <ExportAssignment>node;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
for (const decl of (<VariableStatement>node).declarationList.declarations) {
|
||||
exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
|
||||
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText));
|
||||
|
||||
if (externalHelpersImportDeclaration) {
|
||||
externalImports.unshift(externalHelpersImportDeclaration);
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<boolean>, exportedNames: Identifier[]) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports.get(decl.name.text)) {
|
||||
uniqueExports.set(decl.name.text, true);
|
||||
exportedNames = append(exportedNames, decl.name);
|
||||
}
|
||||
}
|
||||
return exportedNames;
|
||||
}
|
||||
|
||||
/** Use a sparse array as a multi-map. */
|
||||
function multiMapSparseArrayAdd<V>(map: V[][], key: number, value: V): V[] {
|
||||
let values = map[key];
|
||||
if (values) {
|
||||
values.push(value);
|
||||
}
|
||||
else {
|
||||
map[key] = values = [value];
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-3
@@ -1,6 +1,5 @@
|
||||
/// <reference path="utilities.ts"/>
|
||||
/// <reference path="scanner.ts"/>
|
||||
/// <reference path="factory.ts"/>
|
||||
|
||||
namespace ts {
|
||||
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
|
||||
@@ -466,6 +465,15 @@ namespace ts {
|
||||
return Parser.parseIsolatedEntityName(text, languageVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json text into SyntaxTree and return node and parse errors if any
|
||||
* @param fileName
|
||||
* @param sourceText
|
||||
*/
|
||||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
return Parser.parseJsonText(fileName, sourceText);
|
||||
}
|
||||
|
||||
// See also `isExternalOrCommonJsModule` in utilities.ts
|
||||
export function isExternalModule(file: SourceFile): boolean {
|
||||
return file.externalModuleIndicator !== undefined;
|
||||
@@ -632,9 +640,34 @@ namespace ts {
|
||||
return isInvalid ? entityName : undefined;
|
||||
}
|
||||
|
||||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON);
|
||||
// Set source file so that errors will be reported with this file name
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON);
|
||||
const result = <JsonSourceFile>sourceFile;
|
||||
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
if (token() === SyntaxKind.EndOfFileToken) {
|
||||
sourceFile.endOfFileToken = <EndOfFileToken>parseTokenNode();
|
||||
}
|
||||
else if (token() === SyntaxKind.OpenBraceToken ||
|
||||
lookAhead(() => token() === SyntaxKind.StringLiteral)) {
|
||||
result.jsonObject = parseObjectLiteralExpression();
|
||||
sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, /*reportAtCurrentPosition*/ false, Diagnostics.Unexpected_token);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
}
|
||||
|
||||
sourceFile.parseDiagnostics = parseDiagnostics;
|
||||
clearState();
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageVariant(scriptKind: ScriptKind) {
|
||||
// .tsx and .jsx files are treated as jsx language variant.
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
}
|
||||
|
||||
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
@@ -652,7 +685,7 @@ namespace ts {
|
||||
identifierCount = 0;
|
||||
nodeCount = 0;
|
||||
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
// Initialize and prime the scanner before parsing the source elements.
|
||||
|
||||
+123
-31
@@ -442,6 +442,7 @@ namespace ts {
|
||||
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[];
|
||||
@@ -1328,7 +1329,11 @@ namespace ts {
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
return sortAndDeduplicateDiagnostics(concatenate(
|
||||
fileProcessingDiagnostics.getGlobalDiagnostics(),
|
||||
programDiagnostics.getGlobalDiagnostics()));
|
||||
concatenate(
|
||||
programDiagnostics.getGlobalDiagnostics(),
|
||||
options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : []
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
@@ -1773,33 +1778,33 @@ namespace ts {
|
||||
function verifyCompilerOptions() {
|
||||
if (options.isolatedModules) {
|
||||
if (options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.noEmitOnError) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.out) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.inlineSourceMap) {
|
||||
if (options.sourceMap) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
|
||||
}
|
||||
if (options.mapRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.paths && options.baseUrl === undefined) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
|
||||
}
|
||||
|
||||
if (options.paths) {
|
||||
@@ -1808,63 +1813,65 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
if (!hasZeroOrOneAsteriskCharacter(key)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key));
|
||||
createDiagnosticForOptionPaths(/*onKey*/ true, key, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
|
||||
}
|
||||
if (isArray(options.paths[key])) {
|
||||
if (options.paths[key].length === 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key));
|
||||
const len = options.paths[key].length;
|
||||
if (len === 0) {
|
||||
createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
|
||||
}
|
||||
for (const subst of options.paths[key]) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const subst = options.paths[key][i];
|
||||
const typeOfSubst = typeof subst;
|
||||
if (typeOfSubst === "string") {
|
||||
if (!hasZeroOrOneAsteriskCharacter(subst)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key));
|
||||
createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst));
|
||||
createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key));
|
||||
createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.sourceMap && !options.inlineSourceMap) {
|
||||
if (options.inlineSources) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.out && options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
|
||||
}
|
||||
|
||||
if (options.mapRoot && !options.sourceMap) {
|
||||
// Error to specify --mapRoot without --sourcemap
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap");
|
||||
}
|
||||
|
||||
if (options.declarationDir) {
|
||||
if (!options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
|
||||
}
|
||||
if (options.out || options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.lib && options.noLib) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
|
||||
}
|
||||
|
||||
const languageVersion = options.target || ScriptTarget.ES3;
|
||||
@@ -1873,7 +1880,7 @@ namespace ts {
|
||||
const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
if (options.isolatedModules) {
|
||||
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
|
||||
}
|
||||
|
||||
const firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
@@ -1891,7 +1898,7 @@ namespace ts {
|
||||
// Cannot specify module gen that isn't amd or system with --out
|
||||
if (outFile) {
|
||||
if (options.module && !(options.module === ModuleKind.AMD || options.module === ModuleKind.System)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
|
||||
}
|
||||
else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
|
||||
@@ -1910,12 +1917,12 @@ namespace ts {
|
||||
|
||||
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
|
||||
if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
createDiagnosticForOptionName(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.noEmit && options.allowJs && options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration");
|
||||
}
|
||||
|
||||
if (options.checkJs && !options.allowJs) {
|
||||
@@ -1924,19 +1931,19 @@ namespace ts {
|
||||
|
||||
if (options.emitDecoratorMetadata &&
|
||||
!options.experimentalDecorators) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
|
||||
}
|
||||
|
||||
if (options.jsxFactory) {
|
||||
if (options.reactNamespace) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
|
||||
}
|
||||
if (!parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory));
|
||||
createOptionValueDiagnostic("jsxFactory", Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
|
||||
}
|
||||
}
|
||||
else if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace));
|
||||
createOptionValueDiagnostic("reactNamespace", Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
|
||||
}
|
||||
|
||||
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
|
||||
@@ -1976,6 +1983,91 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0: string | number, arg1: string | number, arg2?: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
for (const pathProp of pathsSyntax) {
|
||||
if (isObjectLiteralExpression(pathProp.initializer)) {
|
||||
for (const keyProps of getPropertyAssignment(pathProp.initializer, key)) {
|
||||
if (isArrayLiteralExpression(keyProps.initializer) &&
|
||||
keyProps.initializer.elements.length > valueIndex) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2));
|
||||
needCompilerDiagnostic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2));
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, arg0: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
for (const pathProp of pathsSyntax) {
|
||||
if (isObjectLiteralExpression(pathProp.initializer) &&
|
||||
createOptionDiagnosticInObjectLiteralSyntax(
|
||||
pathProp.initializer, onKey, key, /*key2*/ undefined,
|
||||
message, arg0)) {
|
||||
needCompilerDiagnostic = false;
|
||||
}
|
||||
}
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0));
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionPathsSyntax() {
|
||||
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
|
||||
if (compilerOptionsObjectLiteralSyntax) {
|
||||
return getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths");
|
||||
}
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionName(message: DiagnosticMessage, option1: string, option2?: string) {
|
||||
createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2);
|
||||
}
|
||||
|
||||
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) {
|
||||
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
|
||||
}
|
||||
|
||||
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number) {
|
||||
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
|
||||
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
|
||||
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1);
|
||||
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsObjectLiteralSyntax() {
|
||||
if (_compilerOptionsObjectLiteralSyntax === undefined) {
|
||||
_compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
|
||||
if (options.configFile && options.configFile.jsonObject) {
|
||||
for (const prop of getPropertyAssignment(options.configFile.jsonObject, "compilerOptions")) {
|
||||
if (isObjectLiteralExpression(prop.initializer)) {
|
||||
_compilerOptionsObjectLiteralSyntax = prop.initializer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _compilerOptionsObjectLiteralSyntax;
|
||||
}
|
||||
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number): boolean {
|
||||
const props = getPropertyAssignment(objectLiteral, key1, key2);
|
||||
for (const prop of props) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1));
|
||||
}
|
||||
return !!props.length;
|
||||
}
|
||||
|
||||
function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(diag);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/utilities.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function getOriginalNodeId(node: Node) {
|
||||
node = getOriginalNode(node);
|
||||
return node ? getNodeId(node) : 0;
|
||||
}
|
||||
|
||||
export interface ExternalModuleInfo {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Identifier[][]; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMultiMap<ExportSpecifier>();
|
||||
const exportedBindings: Identifier[][] = [];
|
||||
const uniqueExports = createMap<boolean>();
|
||||
let exportedNames: Identifier[];
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
|
||||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// import "mod"
|
||||
// import x from "mod"
|
||||
// import * as x from "mod"
|
||||
// import { x, y } from "mod"
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (!(<ExportDeclaration>node).exportClause) {
|
||||
// export * from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else {
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports.get(specifier.name.text)) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(name.text, specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports.set(specifier.name.text, true);
|
||||
exportedNames = append(exportedNames, specifier.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals && !exportEquals) {
|
||||
// export = x
|
||||
exportEquals = <ExportAssignment>node;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
for (const decl of (<VariableStatement>node).declarationList.declarations) {
|
||||
exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
|
||||
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText));
|
||||
|
||||
if (externalHelpersImportDeclaration) {
|
||||
externalImports.unshift(externalHelpersImportDeclaration);
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<boolean>, exportedNames: Identifier[]) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports.get(decl.name.text)) {
|
||||
uniqueExports.set(decl.name.text, true);
|
||||
exportedNames = append(exportedNames, decl.name);
|
||||
}
|
||||
}
|
||||
return exportedNames;
|
||||
}
|
||||
|
||||
/** Use a sparse array as a multi-map. */
|
||||
function multiMapSparseArrayAdd<V>(map: V[][], key: number, value: V): V[] {
|
||||
let values = map[key];
|
||||
if (values) {
|
||||
values.push(value);
|
||||
}
|
||||
else {
|
||||
map[key] = values = [value];
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
+6
-13
@@ -223,20 +223,13 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = parseConfigFileTextToJson(configFileName, cachedConfigFileText);
|
||||
const configObject = result.config;
|
||||
if (!configObject) {
|
||||
reportDiagnostics([result.error], /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const result = parseJsonText(configFileName, cachedConfigFileText);
|
||||
reportDiagnostics(result.parseDiagnostics, /* compilerHost */ undefined);
|
||||
|
||||
const cwd = sys.getCurrentDirectory();
|
||||
const configParseResult = parseJsonConfigFileContent(configObject, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
if (configParseResult.errors.length > 0) {
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const configParseResult = parseJsonSourceFileConfigFileContent(result, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
|
||||
if (isWatchSet(configParseResult.options)) {
|
||||
if (!sys.watchFile) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* host */ undefined);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"transformers/utilities.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
|
||||
+11
-2
@@ -2375,6 +2375,11 @@ namespace ts {
|
||||
sourceFiles: SourceFile[];
|
||||
}
|
||||
|
||||
export interface JsonSourceFile extends SourceFile {
|
||||
jsonObject?: ObjectLiteralExpression;
|
||||
extendedSourceFiles?: string[];
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
@@ -3488,6 +3493,7 @@ namespace ts {
|
||||
charset?: string;
|
||||
checkJs?: boolean;
|
||||
/* @internal */ configFilePath?: string;
|
||||
/* @internal */ readonly configFile?: JsonSourceFile;
|
||||
declaration?: boolean;
|
||||
declarationDir?: string;
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
@@ -3560,7 +3566,7 @@ namespace ts {
|
||||
/*@internal*/ version?: boolean;
|
||||
/*@internal*/ watch?: boolean;
|
||||
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
[option: string]: CompilerOptionsValue | JsonSourceFile | undefined;
|
||||
}
|
||||
|
||||
export interface TypeAcquisition {
|
||||
@@ -3620,7 +3626,8 @@ namespace ts {
|
||||
JSX = 2,
|
||||
TS = 3,
|
||||
TSX = 4,
|
||||
External = 5
|
||||
External = 5,
|
||||
JSON = 6
|
||||
}
|
||||
|
||||
export const enum ScriptTarget {
|
||||
@@ -3692,6 +3699,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface TsConfigOnlyOption extends CommandLineOptionBase {
|
||||
type: "object";
|
||||
elementOptions?: Map<CommandLineOption>;
|
||||
extraKeyDiagnosticMessage?: DiagnosticMessage;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
+28
-75
@@ -309,6 +309,14 @@ namespace ts {
|
||||
return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets flags that control emit behavior of a node.
|
||||
*/
|
||||
export function getEmitFlags(node: Node): EmitFlags | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.flags;
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
@@ -882,6 +890,15 @@ namespace ts {
|
||||
return predicate && predicate.kind === TypePredicateKind.This;
|
||||
}
|
||||
|
||||
export function getPropertyAssignment(objectLiteral: ObjectLiteralExpression, key: string, key2?: string) {
|
||||
return <PropertyAssignment[]>filter(objectLiteral.properties, property => {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment) {
|
||||
const propName = getTextOfPropertyName(property.name);
|
||||
return key === propName || (key2 && key2 === propName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getContainingFunction(node: Node): FunctionLikeDeclaration {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
@@ -1242,12 +1259,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
|
||||
const moduleState = getModuleInstanceState(node);
|
||||
return moduleState === ModuleInstanceState.Instantiated ||
|
||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||
}
|
||||
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node) {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
|
||||
}
|
||||
@@ -2013,14 +2024,7 @@ namespace ts {
|
||||
|| positionIsSynthesized(node.end);
|
||||
}
|
||||
|
||||
export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
|
||||
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
|
||||
}
|
||||
return getOriginalSourceFile(sourceFileOrBundle);
|
||||
}
|
||||
|
||||
function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
export function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
|
||||
}
|
||||
|
||||
@@ -2028,11 +2032,6 @@ namespace ts {
|
||||
return sameMap(sourceFiles, getOriginalSourceFile);
|
||||
}
|
||||
|
||||
export function getOriginalNodeId(node: Node) {
|
||||
node = getOriginalNode(node);
|
||||
return node ? getNodeId(node) : 0;
|
||||
}
|
||||
|
||||
export const enum Associativity {
|
||||
Left,
|
||||
Right
|
||||
@@ -2540,62 +2539,6 @@ namespace ts {
|
||||
return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the source files that are expected to have an emit output.
|
||||
*
|
||||
* @param host An EmitHost.
|
||||
* @param action The action to execute.
|
||||
* @param sourceFilesOrTargetSourceFile
|
||||
* If an array, the full list of source files to emit.
|
||||
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
|
||||
*/
|
||||
export function forEachEmittedFile(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
|
||||
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
|
||||
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
|
||||
const options = host.getCompilerOptions();
|
||||
if (options.outFile || options.out) {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : "";
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
||||
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
||||
}
|
||||
|
||||
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
||||
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
||||
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
||||
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension {
|
||||
if (options.jsx === JsxEmit.Preserve) {
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
||||
// TypeScript source file preserving JSX syntax
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
return Extension.Js;
|
||||
}
|
||||
|
||||
export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {
|
||||
let sourceFilePath = getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
|
||||
const commonSourceDirectory = host.getCommonSourceDirectory();
|
||||
@@ -4284,6 +4227,16 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.ParenthesizedExpression;
|
||||
}
|
||||
|
||||
export function skipPartiallyEmittedExpressions(node: Expression): Expression;
|
||||
export function skipPartiallyEmittedExpressions(node: Node): Node;
|
||||
export function skipPartiallyEmittedExpressions(node: Node) {
|
||||
while (node.kind === SyntaxKind.PartiallyEmittedExpression) {
|
||||
node = (<PartiallyEmittedExpression>node).expression;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export function isFunctionExpression(node: Node): node is FunctionExpression {
|
||||
return node.kind === SyntaxKind.FunctionExpression;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
let result: Harness.Compiler.CompilerResult;
|
||||
let options: ts.CompilerOptions;
|
||||
let tsConfigFiles: Harness.Compiler.TestFile[];
|
||||
// equivalent to the files that will be passed on the command line
|
||||
let toBeCompiled: Harness.Compiler.TestFile[];
|
||||
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
|
||||
@@ -77,10 +78,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
const units = testCaseContent.testUnitData;
|
||||
harnessSettings = testCaseContent.settings;
|
||||
let tsConfigOptions: ts.CompilerOptions;
|
||||
tsConfigFiles = [];
|
||||
if (testCaseContent.tsConfig) {
|
||||
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
|
||||
|
||||
tsConfigOptions = ts.clone(testCaseContent.tsConfig.options);
|
||||
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
|
||||
tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));
|
||||
}
|
||||
else {
|
||||
const baseUrl = harnessSettings["baseUrl"];
|
||||
@@ -98,21 +101,22 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
otherFiles = [];
|
||||
|
||||
if (testCaseContent.settings["noImplicitReferences"] || /require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
|
||||
toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content, fileOptions: lastUnit.fileOptions });
|
||||
toBeCompiled.push(this.createHarnessTestFile(lastUnit, rootDir));
|
||||
units.forEach(unit => {
|
||||
if (unit.name !== lastUnit.name) {
|
||||
otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content, fileOptions: unit.fileOptions });
|
||||
otherFiles.push(this.createHarnessTestFile(unit, rootDir));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
toBeCompiled = units.map(unit => {
|
||||
return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content, fileOptions: unit.fileOptions };
|
||||
return this.createHarnessTestFile(unit, rootDir);
|
||||
});
|
||||
}
|
||||
|
||||
if (tsConfigOptions && tsConfigOptions.configFilePath !== undefined) {
|
||||
tsConfigOptions.configFilePath = ts.combinePaths(rootDir, tsConfigOptions.configFilePath);
|
||||
tsConfigOptions.configFile.fileName = tsConfigOptions.configFilePath;
|
||||
}
|
||||
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
@@ -132,11 +136,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
options = undefined;
|
||||
toBeCompiled = undefined;
|
||||
otherFiles = undefined;
|
||||
tsConfigFiles = undefined;
|
||||
});
|
||||
|
||||
// check errors
|
||||
it("Correct errors for " + fileName, () => {
|
||||
Harness.Compiler.doErrorBaseline(justName, toBeCompiled.concat(otherFiles), result.errors);
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors);
|
||||
});
|
||||
|
||||
it (`Correct module resolution tracing for ${fileName}`, () => {
|
||||
@@ -165,7 +170,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
it("Correct JS output for " + fileName, () => {
|
||||
if (hasNonDtsFiles && this.emit) {
|
||||
Harness.Compiler.doJsEmitBaseline(justName, fileName, options, result, toBeCompiled, otherFiles, harnessSettings);
|
||||
Harness.Compiler.doJsEmitBaseline(justName, fileName, options, result, tsConfigFiles, toBeCompiled, otherFiles, harnessSettings);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,6 +188,10 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
});
|
||||
}
|
||||
|
||||
private createHarnessTestFile(lastUnit: Harness.TestCaseParser.TestUnitData, rootDir: string, unitName?: string): Harness.Compiler.TestFile {
|
||||
return { unitName: unitName || this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content, fileOptions: lastUnit.fileOptions };
|
||||
}
|
||||
|
||||
public initializeTests() {
|
||||
describe(this.testSuiteName + " tests", () => {
|
||||
describe("Setup compiler for compiler baselines", () => {
|
||||
|
||||
+15
-8
@@ -1125,7 +1125,7 @@ namespace Harness {
|
||||
compilerOptions: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): CompilationOutput {
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
options.noErrorTruncation = true;
|
||||
@@ -1557,7 +1557,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, tsConfigFiles: Harness.Compiler.TestFile[], toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
@@ -1593,7 +1593,7 @@ namespace Harness {
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
jsCode += Harness.Compiler.getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
@@ -1744,7 +1744,12 @@ namespace Harness {
|
||||
}
|
||||
|
||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||
export function makeUnitsFromTest(code: string, fileName: string, rootDir?: string): { settings: CompilerSettings; testUnitData: TestUnitData[]; tsConfig: ts.ParsedCommandLine } {
|
||||
export function makeUnitsFromTest(code: string, fileName: string, rootDir?: string): {
|
||||
settings: CompilerSettings;
|
||||
testUnitData: TestUnitData[];
|
||||
tsConfig: ts.ParsedCommandLine;
|
||||
tsConfigFileUnitData: TestUnitData;
|
||||
} {
|
||||
const settings = extractCompilerSettings(code);
|
||||
|
||||
// List of all the subfiles we've parsed out
|
||||
@@ -1830,17 +1835,19 @@ namespace Harness {
|
||||
|
||||
// check if project has tsconfig.json in the list of files
|
||||
let tsConfig: ts.ParsedCommandLine;
|
||||
let tsConfigFileUnitData: TestUnitData;
|
||||
for (let i = 0; i < testUnitData.length; i++) {
|
||||
const data = testUnitData[i];
|
||||
if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseConfigFileTextToJson(data.name, data.content);
|
||||
assert.isTrue(configJson.config !== undefined);
|
||||
const configJson = ts.parseJsonText(data.name, data.content);
|
||||
assert.isTrue(configJson.endOfFileToken !== undefined);
|
||||
let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name));
|
||||
if (rootDir) {
|
||||
baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir);
|
||||
}
|
||||
tsConfig = ts.parseJsonConfigFileContent(configJson.config, parseConfigHost, baseDir);
|
||||
tsConfig = ts.parseJsonSourceFileConfigFileContent(configJson, parseConfigHost, baseDir);
|
||||
tsConfig.options.configFilePath = data.name;
|
||||
tsConfigFileUnitData = data;
|
||||
|
||||
// delete entry from the list
|
||||
ts.orderedRemoveItemAt(testUnitData, i);
|
||||
@@ -1848,7 +1855,7 @@ namespace Harness {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { settings, testUnitData, tsConfig };
|
||||
return { settings, testUnitData, tsConfig, tsConfigFileUnitData };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
|
||||
}
|
||||
|
||||
interface CompileProjectFilesResult {
|
||||
configFileSourceFiles: ts.SourceFile[];
|
||||
moduleKind: ts.ModuleKind;
|
||||
program?: ts.Program;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
@@ -124,7 +125,8 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.IO.resolvePath(testCase.projectRoot);
|
||||
}
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ts.SourceFile[],
|
||||
getInputFiles: () => string[],
|
||||
getSourceFileTextImpl: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
|
||||
@@ -148,6 +150,7 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
return {
|
||||
configFileSourceFiles,
|
||||
moduleKind,
|
||||
program,
|
||||
errors,
|
||||
@@ -196,6 +199,7 @@ class ProjectRunner extends RunnerBase {
|
||||
const outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
let inputFiles = testCase.inputFiles;
|
||||
let compilerOptions = createCompilerOptions();
|
||||
const configFileSourceFiles: ts.SourceFile[] = [];
|
||||
|
||||
let configFileName: string;
|
||||
if (compilerOptions.project) {
|
||||
@@ -207,41 +211,31 @@ class ProjectRunner extends RunnerBase {
|
||||
configFileName = ts.findConfigFile("", fileExists);
|
||||
}
|
||||
|
||||
let errors: ts.Diagnostic[];
|
||||
if (configFileName) {
|
||||
const result = ts.readConfigFile(configFileName, getSourceFileText);
|
||||
if (result.error) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: [result.error]
|
||||
};
|
||||
}
|
||||
|
||||
const configObject = result.config;
|
||||
const result = ts.readJsonConfigFile(configFileName, getSourceFileText);
|
||||
configFileSourceFiles.push(result);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists,
|
||||
readDirectory,
|
||||
readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonConfigFileContent(configObject, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
if (configParseResult.errors.length > 0) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: configParseResult.errors
|
||||
};
|
||||
}
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
inputFiles = configParseResult.fileNames;
|
||||
compilerOptions = configParseResult.options;
|
||||
errors = result.parseDiagnostics.concat(configParseResult.errors);
|
||||
}
|
||||
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, configFileSourceFiles, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
return {
|
||||
configFileSourceFiles,
|
||||
moduleKind,
|
||||
program: projectCompilerResult.program,
|
||||
compilerOptions,
|
||||
sourceMapData: projectCompilerResult.sourceMapData,
|
||||
outputFiles,
|
||||
errors: projectCompilerResult.errors,
|
||||
errors: errors ? errors.concat(projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
};
|
||||
|
||||
function createCompilerOptions() {
|
||||
@@ -402,7 +396,7 @@ class ProjectRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
// Dont allow config files since we are compiling existing source options
|
||||
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
|
||||
return compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
|
||||
|
||||
function findOutputDtsFile(fileName: string) {
|
||||
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
|
||||
@@ -428,16 +422,16 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
const inputFiles = compilerResult.program ? ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)),
|
||||
sourceFile => {
|
||||
return {
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
};
|
||||
}) : [];
|
||||
const inputFiles = ts.map(compilerResult.configFileSourceFiles.concat(
|
||||
compilerResult.program ?
|
||||
ts.filter(compilerResult.program.getSourceFiles(), sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)) :
|
||||
[]),
|
||||
sourceFile => <Harness.Compiler.TestFile>{
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
});
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace RWC {
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let tsconfigFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
const baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
@@ -44,6 +45,7 @@ namespace RWC {
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
inputFiles = [];
|
||||
otherFiles = [];
|
||||
tsconfigFiles = [];
|
||||
compilerResult = undefined;
|
||||
compilerOptions = undefined;
|
||||
currentDirectory = undefined;
|
||||
@@ -74,16 +76,18 @@ namespace RWC {
|
||||
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
|
||||
if (tsconfigFile) {
|
||||
const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
|
||||
const parsedTsconfigFileContents = ts.parseConfigFileTextToJson(tsconfigFile.path, tsconfigFileContents.content);
|
||||
tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content });
|
||||
const parsedTsconfigFileContents = ts.parseJsonText(tsconfigFile.path, tsconfigFileContents.content);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists: Harness.IO.fileExists,
|
||||
readDirectory: Harness.IO.readDirectory,
|
||||
readFile: Harness.IO.readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonConfigFileContent(parsedTsconfigFileContents.config, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(parsedTsconfigFileContents, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
fileNames = configParseResult.fileNames;
|
||||
opts.options = ts.extend(opts.options, configParseResult.options);
|
||||
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
|
||||
}
|
||||
|
||||
// Load the files
|
||||
@@ -198,8 +202,8 @@ namespace RWC {
|
||||
return null;
|
||||
}
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.errors.filter(e => e.file && !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
const baselineFiles = tsconfigFiles.concat(inputFiles, otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.errors.filter(e => !e.file || !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, errors);
|
||||
}, baselineOpts);
|
||||
});
|
||||
@@ -218,7 +222,7 @@ namespace RWC {
|
||||
|
||||
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() +
|
||||
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
Harness.Compiler.getErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}, baselineOpts);
|
||||
}
|
||||
});
|
||||
@@ -259,4 +263,4 @@ class RWCRunner extends RunnerBase {
|
||||
private runTest(jsonFileName: string) {
|
||||
RWC.runRWCTest(jsonFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"../compiler/checker.ts",
|
||||
"../compiler/factory.ts",
|
||||
"../compiler/visitor.ts",
|
||||
"../compiler/transformers/utilities.ts",
|
||||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/esnext.ts",
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace ts {
|
||||
// setting compiler options discards module resolution cache
|
||||
fileExistsCalled = false;
|
||||
|
||||
const compilerOptions = ts.clone(project.getCompilerOptions());
|
||||
const compilerOptions = ts.cloneCompilerOptions(project.getCompilerOptions());
|
||||
compilerOptions.target = ts.ScriptTarget.ES5;
|
||||
project.setCompilerOptions(compilerOptions);
|
||||
|
||||
|
||||
@@ -111,23 +111,47 @@ namespace ts {
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
], ([testName, basePath, host]) => {
|
||||
function getParseCommandLine(entry: string) {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
return ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
}
|
||||
|
||||
function getParseCommandLineJsonSourceFile(entry: string) {
|
||||
const jsonSourceFile = ts.readJsonConfigFile(entry, name => host.readFile(name));
|
||||
assert(jsonSourceFile.endOfFileToken && !jsonSourceFile.parseDiagnostics.length, flattenDiagnosticMessageText(jsonSourceFile.parseDiagnostics[0] && jsonSourceFile.parseDiagnostics[0].messageText, "\n"));
|
||||
return {
|
||||
jsonSourceFile,
|
||||
parsed: ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, basePath, {}, entry)
|
||||
};
|
||||
}
|
||||
|
||||
function testSuccess(name: string, entry: string, expected: CompilerOptions, expectedFiles: string[]) {
|
||||
expected.configFilePath = entry;
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
expected.configFilePath = entry;
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
assert.deepEqual(parsed.fileNames, expectedFiles);
|
||||
});
|
||||
|
||||
it(name + " with jsonSourceFile", () => {
|
||||
const { parsed, jsonSourceFile } = getParseCommandLineJsonSourceFile(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
assert.equal(parsed.options.configFile, jsonSourceFile);
|
||||
assert.deepEqual(parsed.fileNames, expectedFiles);
|
||||
});
|
||||
}
|
||||
|
||||
function testFailure(name: string, entry: string, expectedDiagnostics: {code: number, category: DiagnosticCategory, messageText: string}[]) {
|
||||
function testFailure(name: string, entry: string, expectedDiagnostics: { code: number, category: DiagnosticCategory, messageText: string }[]) {
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
|
||||
it(name + " with jsonSourceFile", () => {
|
||||
const { parsed } = getParseCommandLineJsonSourceFile(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
}
|
||||
@@ -185,4 +209,4 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
namespace ts {
|
||||
describe("convertCompilerOptionsFromJson", () => {
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
assertCompilerOptionsWithJson(json, configFileName, expectedResult);
|
||||
assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json["compilerOptions"], "/apath/", configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
@@ -21,6 +26,34 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions["configFilePath"] = configFileName;
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
assert.equal(actualCompilerOptions.configFile, result);
|
||||
|
||||
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig.json tests
|
||||
it("Convert correctly format tsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
type ExpectedResult = { typeAcquisition: TypeAcquisition, errors: Diagnostic[] };
|
||||
describe("convertTypeAcquisitionFromJson", () => {
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: { typeAcquisition: TypeAcquisition, errors: Diagnostic[] }) {
|
||||
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
|
||||
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
assertTypeAcquisitionWithJson(json, configFileName, expectedResult);
|
||||
assertTypeAcquisitionWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function verifyAcquisition(actualTypeAcquisition: TypeAcquisition, expectedResult: ExpectedResult) {
|
||||
const parsedTypeAcquisition = JSON.stringify(actualTypeAcquisition);
|
||||
const expectedTypeAcquisition = JSON.stringify(expectedResult.typeAcquisition);
|
||||
assert.equal(parsedTypeAcquisition, expectedTypeAcquisition);
|
||||
}
|
||||
|
||||
function verifyErrors(actualErrors: Diagnostic[], expectedResult: ExpectedResult, hasLocation?: boolean) {
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
@@ -17,9 +23,34 @@ namespace ts {
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
if (hasLocation) {
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertTypeAcquisitionWithJson(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
|
||||
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
verifyErrors(actualErrors, expectedResult);
|
||||
}
|
||||
|
||||
function assertTypeAcquisitionWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
|
||||
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
verifyErrors(actualErrors, expectedResult, /*hasLocation*/ true);
|
||||
}
|
||||
|
||||
// tsconfig.json
|
||||
it("Convert deprecated typingOptions.enableAutoDiscovery format tsconfig.json to typeAcquisition ", () => {
|
||||
assertTypeAcquisition(
|
||||
@@ -177,7 +208,7 @@ namespace ts {
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
category: Diagnostics.Unknown_compiler_option_0.category,
|
||||
category: Diagnostics.Unknown_type_acquisition_option_0.category,
|
||||
code: Diagnostics.Unknown_type_acquisition_option_0.code,
|
||||
file: undefined,
|
||||
start: 0,
|
||||
|
||||
+101
-119
@@ -95,6 +95,44 @@ namespace ts {
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
}
|
||||
|
||||
function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) {
|
||||
{
|
||||
const jsonText = JSON.stringify(json);
|
||||
const result = parseJsonText(caseInsensitiveTsconfigPath, jsonText);
|
||||
const actual = ts.parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
for (const error of expected.errors) {
|
||||
if (error.file) {
|
||||
error.file = result;
|
||||
}
|
||||
}
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
{
|
||||
const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
expected.errors = map(expected.errors, error => {
|
||||
return <Diagnostic>{
|
||||
category: error.category,
|
||||
code: error.code,
|
||||
file: undefined,
|
||||
length: undefined,
|
||||
messageText: error.messageText,
|
||||
start: undefined,
|
||||
};
|
||||
});
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: DiagnosticMessage, arg0: string) {
|
||||
const text = JSON.stringify(json);
|
||||
const file = <SourceFile>{
|
||||
fileName: caseInsensitiveTsconfigPath,
|
||||
kind: SyntaxKind.SourceFile,
|
||||
text
|
||||
};
|
||||
return ts.createFileDiagnostic(file, start, length, diagnosticMessage, arg0);
|
||||
}
|
||||
|
||||
describe("matchFiles", () => {
|
||||
it("with defaults", () => {
|
||||
const json = {};
|
||||
@@ -109,8 +147,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
describe("with literal file list", () => {
|
||||
@@ -130,8 +167,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("missing files are still present", () => {
|
||||
const json = {
|
||||
@@ -149,8 +185,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("are not removed due to excludes", () => {
|
||||
const json = {
|
||||
@@ -171,8 +206,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -193,8 +227,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with non .ts file extensions are excluded", () => {
|
||||
const json = {
|
||||
@@ -212,8 +245,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -231,8 +263,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("with literal excludes", () => {
|
||||
const json = {
|
||||
@@ -252,8 +283,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with wildcard excludes", () => {
|
||||
const json = {
|
||||
@@ -280,8 +310,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive excludes", () => {
|
||||
const json = {
|
||||
@@ -307,8 +336,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with case sensitive exclude", () => {
|
||||
const json = {
|
||||
@@ -327,8 +355,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -352,8 +379,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -379,8 +405,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -404,8 +429,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -436,8 +460,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("same named declarations are excluded", () => {
|
||||
@@ -458,8 +481,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`*` matches only ts files", () => {
|
||||
const json = {
|
||||
@@ -479,8 +501,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`?` matches only a single character", () => {
|
||||
const json = {
|
||||
@@ -499,8 +520,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive directory", () => {
|
||||
const json = {
|
||||
@@ -521,8 +541,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with multiple recursive directories", () => {
|
||||
const json = {
|
||||
@@ -545,8 +564,7 @@ namespace ts {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("case sensitive", () => {
|
||||
const json = {
|
||||
@@ -564,8 +582,7 @@ namespace ts {
|
||||
"/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -584,8 +601,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("always include literal files", () => {
|
||||
const json = {
|
||||
@@ -609,8 +625,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude folders", () => {
|
||||
const json = {
|
||||
@@ -634,8 +649,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -656,8 +670,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -680,8 +693,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -703,8 +715,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude .js files when allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -728,8 +739,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("include .js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -753,8 +763,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include explicitly listed .min.js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -778,8 +787,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include paths outside of the project", () => {
|
||||
const json = {
|
||||
@@ -802,8 +810,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -825,8 +832,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -846,8 +852,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -866,8 +871,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -888,8 +892,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=none, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -911,8 +914,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -936,8 +938,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -961,8 +962,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=none, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -986,8 +986,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -1013,8 +1012,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -1040,8 +1038,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude .min.js files using wildcards", () => {
|
||||
const json = {
|
||||
@@ -1067,8 +1064,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
describe("with trailing recursive directory", () => {
|
||||
it("in includes", () => {
|
||||
@@ -1080,15 +1076,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
|
||||
createDiagnosticForConfigFile(json, 12, 4, ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1108,8 +1103,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
});
|
||||
describe("with multiple recursive directory patterns", () => {
|
||||
@@ -1122,15 +1116,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
|
||||
createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1144,7 +1137,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**")
|
||||
createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1156,8 +1149,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1171,15 +1163,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
|
||||
createDiagnosticForConfigFile(json, 12, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
|
||||
it("in includes after a subdirectory", () => {
|
||||
@@ -1191,15 +1182,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
|
||||
createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
|
||||
it("in excludes immediately after", () => {
|
||||
@@ -1214,7 +1204,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..")
|
||||
createDiagnosticForConfigFile(json, 34, 7, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1226,8 +1216,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("in excludes after a subdirectory", () => {
|
||||
@@ -1242,7 +1231,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
|
||||
createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1254,8 +1243,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1272,8 +1260,7 @@ namespace ts {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1297,8 +1284,7 @@ namespace ts {
|
||||
"c:/dev/w": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
describe("that are explicitly included", () => {
|
||||
it("without wildcards", () => {
|
||||
@@ -1317,8 +1303,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive wildcards that match directories", () => {
|
||||
const json = {
|
||||
@@ -1339,8 +1324,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive wildcards that match nothing", () => {
|
||||
const json = {
|
||||
@@ -1361,8 +1345,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with wildcard excludes that implicitly exclude dotted files", () => {
|
||||
const json = {
|
||||
@@ -1382,8 +1365,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,10 @@ namespace ts.projectSystem {
|
||||
describe("Project errors", () => {
|
||||
function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: string[]) {
|
||||
assert.isTrue(projectFiles !== undefined, "missing project files");
|
||||
const errors = projectFiles.projectErrors;
|
||||
checkProjectErrorsWorker(projectFiles.projectErrors, expectedErrors);
|
||||
}
|
||||
|
||||
function checkProjectErrorsWorker(errors: Diagnostic[], expectedErrors: string[]) {
|
||||
assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`);
|
||||
if (expectedErrors.length) {
|
||||
for (let i = 0; i < errors.length; i++) {
|
||||
@@ -122,12 +125,13 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, [
|
||||
"')' expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Failed to parse file '/a/b/tsconfig.json'"
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, [
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
}
|
||||
// fix config and trigger watcher
|
||||
host.reloadFS([file1, file2, correctConfig]);
|
||||
@@ -137,6 +141,8 @@ namespace ts.projectSystem {
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, []);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,6 +172,8 @@ namespace ts.projectSystem {
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, []);
|
||||
}
|
||||
// break config and trigger watcher
|
||||
host.reloadFS([file1, file2, corruptedConfig]);
|
||||
@@ -174,13 +182,14 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, [
|
||||
"')' expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Failed to parse file '/a/b/tsconfig.json'"
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, [
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ts.projectSystem {
|
||||
it("works with external project", () => {
|
||||
const file1 = makeFile("/a.ts");
|
||||
const et = new EventTracker([file1]);
|
||||
const compilerOptions: ts.CompilerOptions = { strict: true };
|
||||
const compilerOptions: ts.server.protocol.CompilerOptions = { strict: true };
|
||||
|
||||
const projectFileName = "/hunter2/foo.csproj";
|
||||
|
||||
@@ -138,8 +138,6 @@ namespace ts.projectSystem {
|
||||
declaration: true,
|
||||
|
||||
lib: ["es6", "dom"],
|
||||
|
||||
checkJs: "" as any as boolean,
|
||||
};
|
||||
(compilerOptions as any).unknownCompilerOption = "hunter2"; // These are always ignored.
|
||||
const tsconfig = makeFile("/tsconfig.json", { compilerOptions, files: ["/a.ts"] });
|
||||
|
||||
@@ -3,37 +3,69 @@
|
||||
|
||||
namespace ts {
|
||||
describe("parseConfigFileTextToJson", () => {
|
||||
function assertParseResult(jsonText: string, expectedConfigObject: { config?: any; error?: Diagnostic }) {
|
||||
function assertParseResult(jsonText: string, expectedConfigObject: { config?: any; error?: Diagnostic[] }) {
|
||||
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
|
||||
assert.equal(JSON.stringify(parsed), JSON.stringify(expectedConfigObject));
|
||||
}
|
||||
|
||||
function assertParseError(jsonText: string) {
|
||||
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
|
||||
assert.isTrue(undefined === parsed.config);
|
||||
assert.deepEqual(parsed.config, {});
|
||||
assert.isTrue(undefined !== parsed.error);
|
||||
}
|
||||
|
||||
function assertParseErrorWithExcludesKeyword(jsonText: string) {
|
||||
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
|
||||
const parsedCommand = ts.parseJsonConfigFileContent(parsed.config, ts.sys, "tests/cases/unittests");
|
||||
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
|
||||
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
|
||||
{
|
||||
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
|
||||
const parsedCommand = ts.parseJsonConfigFileContent(parsed.config, ts.sys, "tests/cases/unittests");
|
||||
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
|
||||
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
|
||||
}
|
||||
{
|
||||
const parsed = ts.parseJsonText("/apath/tsconfig.json", jsonText);
|
||||
const parsedCommand = ts.parseJsonSourceFileConfigFileContent(parsed, ts.sys, "tests/cases/unittests");
|
||||
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
|
||||
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
|
||||
}
|
||||
}
|
||||
|
||||
function getParsedCommandJson(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) {
|
||||
const parsed = ts.parseConfigFileTextToJson(configFileName, jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
return ts.parseJsonConfigFileContent(parsed.config, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
}
|
||||
|
||||
function getParsedCommandJsonNode(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) {
|
||||
const parsed = ts.parseJsonText(configFileName, jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
return ts.parseJsonSourceFileConfigFileContent(parsed, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
}
|
||||
|
||||
function assertParseFileList(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedFileList: string[]) {
|
||||
const json = JSON.parse(jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
const parsed = ts.parseJsonConfigFileContent(json, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
|
||||
{
|
||||
const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList);
|
||||
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
|
||||
}
|
||||
{
|
||||
const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList);
|
||||
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
|
||||
}
|
||||
}
|
||||
|
||||
function assertParseFileDiagnostics(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedDiagnosticCode: number) {
|
||||
const json = JSON.parse(jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
const parsed = ts.parseJsonConfigFileContent(json, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
assert.isTrue(parsed.errors.length >= 0);
|
||||
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
|
||||
function assertParseFileDiagnostics(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedDiagnosticCode: number, noLocation?: boolean) {
|
||||
{
|
||||
const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList);
|
||||
assert.isTrue(parsed.errors.length >= 0);
|
||||
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
|
||||
}
|
||||
{
|
||||
const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList);
|
||||
assert.isTrue(parsed.errors.length >= 0);
|
||||
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
|
||||
if (!noLocation) {
|
||||
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode && e.file && e.start && e.length).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)} with location information`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it("returns empty config for file with only whitespaces", () => {
|
||||
@@ -199,7 +231,9 @@ namespace ts {
|
||||
}
|
||||
"files": ["file1.ts"]
|
||||
}`;
|
||||
const { configJsonObject, diagnostics } = sanitizeConfigFile("config.json", content);
|
||||
const result = parseJsonText("config.json", content);
|
||||
const diagnostics = result.parseDiagnostics;
|
||||
const configJsonObject = convertToObject(result, diagnostics);
|
||||
const expectedResult = {
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
@@ -229,7 +263,8 @@ namespace ts {
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.js"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code,
|
||||
/*noLocation*/ true);
|
||||
});
|
||||
|
||||
it("generates errors for empty directory", () => {
|
||||
@@ -242,7 +277,8 @@ namespace ts {
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
[],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code,
|
||||
/*noLocation*/ true);
|
||||
});
|
||||
|
||||
it("generates errors for empty include", () => {
|
||||
@@ -253,7 +289,8 @@ namespace ts {
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.ts"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code,
|
||||
/*noLocation*/ true);
|
||||
});
|
||||
|
||||
it("generates errors for includes with outDir", () => {
|
||||
@@ -267,7 +304,8 @@ namespace ts {
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.ts"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code,
|
||||
/*noLocation*/ true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ namespace ts.projectSystem {
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
|
||||
const project = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(project, [file1.path, libFile.path, file2.path]);
|
||||
checkProjectActualFiles(project, [file1.path, libFile.path, file2.path, configFile.path]);
|
||||
checkProjectRootFiles(project, [file1.path, file2.path]);
|
||||
// watching all files except one that was open
|
||||
checkWatchedFiles(host, [configFile.path, file2.path, libFile.path]);
|
||||
@@ -992,7 +992,7 @@ namespace ts.projectSystem {
|
||||
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
const project = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(project, [file1.path, nodeModuleFile.path]);
|
||||
checkProjectActualFiles(project, [file1.path, nodeModuleFile.path, configFile.path]);
|
||||
checkNumberOfInferredProjects(projectService, 1);
|
||||
|
||||
configFile.content = `{
|
||||
@@ -1003,7 +1003,7 @@ namespace ts.projectSystem {
|
||||
}`;
|
||||
host.reloadFS(files);
|
||||
host.triggerFileWatcherCallback(configFile.path);
|
||||
checkProjectActualFiles(project, [file1.path, classicModuleFile.path]);
|
||||
checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]);
|
||||
checkNumberOfInferredProjects(projectService, 1);
|
||||
});
|
||||
|
||||
@@ -1566,7 +1566,7 @@ namespace ts.projectSystem {
|
||||
host.reloadFS([file1, file2, file3, configFile]);
|
||||
host.triggerDirectoryWatcherCallback(getDirectoryPath(configFile.path), configFile.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, file3.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, file3.path, configFile.path]);
|
||||
});
|
||||
|
||||
it("correctly migrate files between projects", () => {
|
||||
@@ -1624,7 +1624,7 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, configFile.path]);
|
||||
|
||||
host.reloadFS([file1, file2, configFile]);
|
||||
|
||||
@@ -1655,7 +1655,7 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, configFile.path]);
|
||||
|
||||
const modifiedConfigFile = {
|
||||
path: configFile.path,
|
||||
@@ -1688,7 +1688,7 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, configFile.path]);
|
||||
|
||||
const modifiedConfigFile = {
|
||||
path: configFile.path,
|
||||
@@ -1769,11 +1769,11 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]);
|
||||
|
||||
projectService.openClientFile(file2.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]);
|
||||
|
||||
host.reloadFS([file1, file2]);
|
||||
host.triggerFileWatcherCallback(config.path, /*removed*/ true);
|
||||
@@ -1808,13 +1808,13 @@ namespace ts.projectSystem {
|
||||
});
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, config.path]);
|
||||
|
||||
projectService.closeClientFile(f1.path);
|
||||
|
||||
projectService.openClientFile(f2.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, config.path]);
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]);
|
||||
});
|
||||
|
||||
@@ -1838,7 +1838,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// HTML file will not be included in any projects yet
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, config.path]);
|
||||
|
||||
// Specify .html extension as mixed content
|
||||
const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }];
|
||||
@@ -1847,7 +1847,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// HTML file still not included in the project as it is closed
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, config.path]);
|
||||
|
||||
// Open HTML file
|
||||
projectService.applyChangesInOpenFiles(
|
||||
@@ -1857,7 +1857,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// Now HTML file is included in the project
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]);
|
||||
|
||||
// Check identifiers defined in HTML content are available in .ts file
|
||||
const project = projectService.configuredProjects[0];
|
||||
@@ -1872,7 +1872,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// HTML file is still included in project
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]);
|
||||
|
||||
// Check identifiers defined in HTML content are not available in .ts file
|
||||
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5);
|
||||
@@ -2488,7 +2488,7 @@ namespace ts.projectSystem {
|
||||
options: {}
|
||||
});
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, tsconfig.path]);
|
||||
|
||||
// rename tsconfig.json back to lib.ts
|
||||
host.reloadFS([f1, f2]);
|
||||
@@ -2546,8 +2546,8 @@ namespace ts.projectSystem {
|
||||
options: {}
|
||||
});
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 2 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path, cTsconfig.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path, dTsconfig.path]);
|
||||
|
||||
// remove one config file
|
||||
projectService.openExternalProject({
|
||||
@@ -2557,7 +2557,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [dLib.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [dLib.path, dTsconfig.path]);
|
||||
|
||||
// remove second config file
|
||||
projectService.openExternalProject({
|
||||
@@ -2577,8 +2577,8 @@ namespace ts.projectSystem {
|
||||
options: {}
|
||||
});
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 2 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path, cTsconfig.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path, dTsconfig.path]);
|
||||
|
||||
// close all projects - no projects should be opened
|
||||
projectService.closeExternalProject(projectName);
|
||||
@@ -2634,13 +2634,13 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(app.path);
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path, config1.path]);
|
||||
|
||||
host.reloadFS([libES5, libES2015Promise, app, config2]);
|
||||
host.triggerFileWatcherCallback(config1.path);
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path, config2.path]);
|
||||
});
|
||||
|
||||
it("should handle non-existing directories in config file", () => {
|
||||
@@ -2695,7 +2695,7 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path, config.path]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2766,7 +2766,7 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t1.path, tsconfig.path]);
|
||||
|
||||
// delete t1
|
||||
host.reloadFS([f1, tsconfig]);
|
||||
@@ -2775,7 +2775,7 @@ namespace ts.projectSystem {
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, tsconfig.path]);
|
||||
|
||||
// create t2
|
||||
host.reloadFS([f1, tsconfig, t2]);
|
||||
@@ -2784,7 +2784,7 @@ namespace ts.projectSystem {
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t2.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t2.path, tsconfig.path]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2969,7 +2969,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, node.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, node.path, config.path]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3980,4 +3980,69 @@ namespace ts.projectSystem {
|
||||
assert.isUndefined(project.getCompilerOptions().maxNodeModuleJsDepth);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Options Diagnostic locations reported correctly with changes in configFile contents", () => {
|
||||
it("when options change", () => {
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
};
|
||||
const configFileContentBeforeComment = `{`;
|
||||
const configFileContentComment = `
|
||||
// comment`;
|
||||
const configFileContentAfterComment = `
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"declaration": true
|
||||
}
|
||||
}`;
|
||||
const configFileContentWithComment = configFileContentBeforeComment + configFileContentComment + configFileContentAfterComment;
|
||||
const configFileContentWithoutCommentLine = configFileContentBeforeComment + configFileContentAfterComment;
|
||||
|
||||
const configFile = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: configFileContentWithComment
|
||||
};
|
||||
const host = createServerHost([file, libFile, configFile]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([file], session);
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const projectName = projectService.configuredProjects[0].getProjectName();
|
||||
|
||||
const diags = session.executeCommand(<server.protocol.SemanticDiagnosticsSyncRequest>{
|
||||
type: "request",
|
||||
command: server.CommandNames.SemanticDiagnosticsSync,
|
||||
seq: 2,
|
||||
arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true }
|
||||
}).response;
|
||||
assert.isTrue(diags.length === 2);
|
||||
|
||||
configFile.content = configFileContentWithoutCommentLine;
|
||||
host.reloadFS([file, configFile]);
|
||||
host.triggerFileWatcherCallback(configFile.path);
|
||||
|
||||
const diagsAfterEdit = session.executeCommand(<server.protocol.SemanticDiagnosticsSyncRequest>{
|
||||
type: "request",
|
||||
command: server.CommandNames.SemanticDiagnosticsSync,
|
||||
seq: 2,
|
||||
arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true }
|
||||
}).response;
|
||||
assert.isTrue(diagsAfterEdit.length === 2);
|
||||
|
||||
verifyDiagnostic(diags[0], diagsAfterEdit[0]);
|
||||
verifyDiagnostic(diags[1], diagsAfterEdit[1]);
|
||||
|
||||
function verifyDiagnostic(beforeEditDiag: server.protocol.DiagnosticWithLinePosition, afterEditDiag: server.protocol.DiagnosticWithLinePosition) {
|
||||
assert.equal(beforeEditDiag.message, afterEditDiag.message);
|
||||
assert.equal(beforeEditDiag.code, afterEditDiag.code);
|
||||
assert.equal(beforeEditDiag.category, afterEditDiag.category);
|
||||
assert.equal(beforeEditDiag.startLocation.line, afterEditDiag.startLocation.line + 1);
|
||||
assert.equal(beforeEditDiag.startLocation.offset, afterEditDiag.startLocation.offset);
|
||||
assert.equal(beforeEditDiag.endLocation.line, afterEditDiag.endLocation.line + 1);
|
||||
assert.equal(beforeEditDiag.endLocation.offset, afterEditDiag.endLocation.offset);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace ts.projectSystem {
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
service.openClientFile(f1.path);
|
||||
service.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path]);
|
||||
checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path, config.path]);
|
||||
installer.installAll(0);
|
||||
});
|
||||
});
|
||||
@@ -133,12 +133,12 @@ namespace ts.projectSystem {
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [file1.path]);
|
||||
checkProjectActualFiles(p, [file1.path, tsconfig.path]);
|
||||
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, jquery.path]);
|
||||
checkProjectActualFiles(p, [file1.path, jquery.path, tsconfig.path]);
|
||||
});
|
||||
|
||||
it("inferred project (typings installed)", () => {
|
||||
@@ -684,12 +684,12 @@ namespace ts.projectSystem {
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [app.path]);
|
||||
checkProjectActualFiles(p, [app.path, jsconfig.path]);
|
||||
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]);
|
||||
});
|
||||
|
||||
it("configured projects discover from bower_components", () => {
|
||||
@@ -730,13 +730,13 @@ namespace ts.projectSystem {
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [app.path]);
|
||||
checkProjectActualFiles(p, [app.path, jsconfig.path]);
|
||||
checkWatchedFiles(host, [jsconfig.path, "/bower_components", "/node_modules"]);
|
||||
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]);
|
||||
});
|
||||
|
||||
it("configured projects discover from bower.json", () => {
|
||||
@@ -777,12 +777,12 @@ namespace ts.projectSystem {
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [app.path]);
|
||||
checkProjectActualFiles(p, [app.path, jsconfig.path]);
|
||||
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]);
|
||||
});
|
||||
|
||||
it("Malformed package.json should be watched", () => {
|
||||
@@ -1206,4 +1206,4 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,20 +976,14 @@ namespace ts.server {
|
||||
configFilename = normalizePath(configFilename);
|
||||
|
||||
const configFileContent = this.host.readFile(configFilename);
|
||||
let errors: Diagnostic[];
|
||||
|
||||
const result = parseConfigFileTextToJson(configFilename, configFileContent);
|
||||
let config = result.config;
|
||||
|
||||
if (result.error) {
|
||||
// try to reparse config file
|
||||
const { configJsonObject: sanitizedConfig, diagnostics } = sanitizeConfigFile(configFilename, configFileContent);
|
||||
config = sanitizedConfig;
|
||||
errors = diagnostics.length ? diagnostics : [result.error];
|
||||
const result = parseJsonText(configFilename, configFileContent);
|
||||
if (!result.endOfFileToken) {
|
||||
result.endOfFileToken = <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
|
||||
}
|
||||
|
||||
const parsedCommandLine = parseJsonConfigFileContent(
|
||||
config,
|
||||
const errors = result.parseDiagnostics;
|
||||
const parsedCommandLine = parseJsonSourceFileConfigFileContent(
|
||||
result,
|
||||
this.host,
|
||||
getDirectoryPath(configFilename),
|
||||
/*existingOptions*/ {},
|
||||
@@ -998,23 +992,23 @@ namespace ts.server {
|
||||
this.hostConfiguration.extraFileExtensions);
|
||||
|
||||
if (parsedCommandLine.errors.length) {
|
||||
errors = concatenate(errors, parsedCommandLine.errors);
|
||||
errors.push(...parsedCommandLine.errors);
|
||||
}
|
||||
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
if (parsedCommandLine.fileNames.length === 0) {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename));
|
||||
return { success: false, configFileErrors: errors };
|
||||
}
|
||||
|
||||
const projectOptions: ProjectOptions = {
|
||||
files: parsedCommandLine.fileNames,
|
||||
compilerOptions: parsedCommandLine.options,
|
||||
configHasExtendsProperty: config.extends !== undefined,
|
||||
configHasFilesProperty: config.files !== undefined,
|
||||
configHasIncludeProperty: config.include !== undefined,
|
||||
configHasExcludeProperty: config.exclude !== undefined,
|
||||
configHasExtendsProperty: parsedCommandLine.raw["extends"] !== undefined,
|
||||
configHasFilesProperty: parsedCommandLine.raw["files"] !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw["include"] !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw["exclude"] !== undefined,
|
||||
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
|
||||
typeAcquisition: parsedCommandLine.typeAcquisition,
|
||||
compileOnSave: parsedCommandLine.compileOnSave
|
||||
@@ -1183,7 +1177,7 @@ namespace ts.server {
|
||||
return {
|
||||
success: conversionResult.success,
|
||||
project,
|
||||
errors: project.getProjectErrors()
|
||||
errors: project.getGlobalProjectErrors()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+43
-6
@@ -216,7 +216,14 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getProjectErrors() {
|
||||
/**
|
||||
* Get the errors that dont have any file name associated
|
||||
*/
|
||||
getGlobalProjectErrors() {
|
||||
return filter(this.projectErrors, diagnostic => !diagnostic.file);
|
||||
}
|
||||
|
||||
getAllProjectErrors() {
|
||||
return this.projectErrors;
|
||||
}
|
||||
|
||||
@@ -363,7 +370,7 @@ namespace ts.server {
|
||||
return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles);
|
||||
}
|
||||
|
||||
getFileNames(excludeFilesFromExternalLibraries?: boolean) {
|
||||
getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) {
|
||||
if (!this.program) {
|
||||
return [];
|
||||
}
|
||||
@@ -386,9 +393,39 @@ namespace ts.server {
|
||||
}
|
||||
result.push(asNormalizedPath(f.fileName));
|
||||
}
|
||||
if (!excludeConfigFiles) {
|
||||
const configFile = this.program.getCompilerOptions().configFile;
|
||||
if (configFile) {
|
||||
result.push(asNormalizedPath(configFile.fileName));
|
||||
if (configFile.extendedSourceFiles) {
|
||||
for (const f of configFile.extendedSourceFiles) {
|
||||
result.push(asNormalizedPath(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
hasConfigFile(configFilePath: NormalizedPath) {
|
||||
if (this.program && this.languageServiceEnabled) {
|
||||
const configFile = this.program.getCompilerOptions().configFile;
|
||||
if (configFile) {
|
||||
if (configFilePath === asNormalizedPath(configFile.fileName)) {
|
||||
return true;
|
||||
}
|
||||
if (configFile.extendedSourceFiles) {
|
||||
for (const f of configFile.extendedSourceFiles) {
|
||||
if (configFilePath === asNormalizedPath(f)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
getAllEmittableFiles() {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return [];
|
||||
@@ -663,7 +700,7 @@ namespace ts.server {
|
||||
if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) {
|
||||
// if current structure version is the same - return info without any changes
|
||||
if (this.projectStructureVersion === this.lastReportedVersion && !updatedFileNames) {
|
||||
return { info, projectErrors: this.projectErrors };
|
||||
return { info, projectErrors: this.getGlobalProjectErrors() };
|
||||
}
|
||||
// compute and return the difference
|
||||
const lastReportedFileNames = this.lastReportedFileNames;
|
||||
@@ -685,14 +722,14 @@ namespace ts.server {
|
||||
});
|
||||
this.lastReportedFileNames = currentFiles;
|
||||
this.lastReportedVersion = this.projectStructureVersion;
|
||||
return { info, changes: { added, removed, updated }, projectErrors: this.projectErrors };
|
||||
return { info, changes: { added, removed, updated }, projectErrors: this.getGlobalProjectErrors() };
|
||||
}
|
||||
else {
|
||||
// unknown version - return everything
|
||||
const projectFileNames = this.getFileNames();
|
||||
this.lastReportedFileNames = arrayToMap(projectFileNames, x => x);
|
||||
this.lastReportedVersion = this.projectStructureVersion;
|
||||
return { info, files: projectFileNames, projectErrors: this.projectErrors };
|
||||
return { info, files: projectFileNames, projectErrors: this.getGlobalProjectErrors() };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +819,7 @@ namespace ts.server {
|
||||
|
||||
setCompilerOptions(options?: CompilerOptions) {
|
||||
// Avoid manipulating the given options directly
|
||||
const newOptions = options ? clone(options) : this.getCompilerOptions();
|
||||
const newOptions = options ? cloneCompilerOptions(options) : this.getCompilerOptions();
|
||||
if (!newOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1943,6 +1943,13 @@ namespace ts.server.protocol {
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export interface DiagnosticWithFileName extends Diagnostic {
|
||||
/**
|
||||
* Name of the file the diagnostic is in
|
||||
*/
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export interface DiagnosticEventBody {
|
||||
/**
|
||||
* The file for which diagnostic information is reported.
|
||||
@@ -1977,7 +1984,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* An arry of diagnostic information items for the found config file.
|
||||
*/
|
||||
diagnostics: Diagnostic[];
|
||||
diagnostics: DiagnosticWithFileName[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+76
-14
@@ -84,14 +84,20 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
function formatConfigFileDiag(diag: ts.Diagnostic): protocol.Diagnostic {
|
||||
return {
|
||||
start: undefined,
|
||||
end: undefined,
|
||||
text: ts.flattenDiagnosticMessageText(diag.messageText, "\n"),
|
||||
category: DiagnosticCategory[diag.category].toLowerCase(),
|
||||
source: diag.source
|
||||
};
|
||||
function convertToILineInfo(lineAndCharacter: LineAndCharacter): ILineInfo {
|
||||
return { line: lineAndCharacter.line + 1, offset: lineAndCharacter.character + 1 };
|
||||
}
|
||||
|
||||
function formatConfigFileDiag(diag: ts.Diagnostic, includeFileName: true): protocol.DiagnosticWithFileName;
|
||||
function formatConfigFileDiag(diag: ts.Diagnostic, includeFileName: false): protocol.Diagnostic;
|
||||
function formatConfigFileDiag(diag: ts.Diagnostic, includeFileName: boolean): protocol.Diagnostic | protocol.DiagnosticWithFileName {
|
||||
const start = diag.file && convertToILineInfo(getLineAndCharacterOfPosition(diag.file, diag.start));
|
||||
const end = diag.file && convertToILineInfo(getLineAndCharacterOfPosition(diag.file, diag.start + diag.length));
|
||||
const text = ts.flattenDiagnosticMessageText(diag.messageText, "\n");
|
||||
const { code, source } = diag;
|
||||
const category = DiagnosticCategory[diag.category].toLowerCase();
|
||||
return includeFileName ? { start, end, text, code, category, source, fileName: diag.file && diag.file.fileName } :
|
||||
{ start, end, text, code, category, source };
|
||||
}
|
||||
|
||||
export interface PendingErrorCheck {
|
||||
@@ -384,7 +390,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
public configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: ts.Diagnostic[]) {
|
||||
const bakedDiags = ts.map(diagnostics, formatConfigFileDiag);
|
||||
const bakedDiags = ts.map(diagnostics, diagnostic => formatConfigFileDiag(diagnostic, /*includeFileName*/ true));
|
||||
const ev: protocol.ConfigFileDiagnosticEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
@@ -517,9 +523,55 @@ namespace ts.server {
|
||||
return projectFileName && this.projectService.findProject(projectFileName);
|
||||
}
|
||||
|
||||
private getConfigFileAndProject(args: protocol.FileRequestArgs) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
const file = toNormalizedPath(args.file);
|
||||
|
||||
return {
|
||||
configFile: project && project.hasConfigFile(file) && file,
|
||||
project
|
||||
};
|
||||
}
|
||||
|
||||
private getConfigFileDiagnostics(configFile: NormalizedPath, project: Project, includeLinePosition: boolean) {
|
||||
const projectErrors = project.getAllProjectErrors();
|
||||
const optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics();
|
||||
const diagnosticsForConfigFile = filter(
|
||||
concatenate(projectErrors, optionsErrors),
|
||||
diagnostic => diagnostic.file && diagnostic.file.fileName === configFile
|
||||
);
|
||||
return includeLinePosition ?
|
||||
this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) :
|
||||
map(
|
||||
diagnosticsForConfigFile,
|
||||
diagnostic => formatConfigFileDiag(diagnostic, /*includeFileName*/ false)
|
||||
);
|
||||
}
|
||||
|
||||
private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]) {
|
||||
return diagnostics.map(d => <protocol.DiagnosticWithLinePosition>{
|
||||
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
|
||||
start: d.start,
|
||||
length: d.length,
|
||||
category: DiagnosticCategory[d.category].toLowerCase(),
|
||||
code: d.code,
|
||||
startLocation: d.file && convertToILineInfo(getLineAndCharacterOfPosition(d.file, d.start)),
|
||||
endLocation: d.file && convertToILineInfo(getLineAndCharacterOfPosition(d.file, d.start + d.length))
|
||||
});
|
||||
}
|
||||
|
||||
private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
return this.convertToDiagnosticsWithLinePosition(project.getLanguageService().getCompilerOptionsDiagnostics(), /*scriptInfo*/ undefined);
|
||||
// Get diagnostics that dont have associated file with them
|
||||
// The diagnostics which have file would be in config file and
|
||||
// would be reported as part of configFileDiagnostics
|
||||
return this.convertToDiagnosticsWithLinePosition(
|
||||
filter(
|
||||
project.getLanguageService().getCompilerOptionsDiagnostics(),
|
||||
diagnostic => !diagnostic.file
|
||||
),
|
||||
/*scriptInfo*/ undefined
|
||||
);
|
||||
}
|
||||
|
||||
private convertToDiagnosticsWithLinePosition(diagnostics: Diagnostic[], scriptInfo: ScriptInfo) {
|
||||
@@ -645,10 +697,20 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
|
||||
const { configFile } = this.getConfigFileAndProject(args);
|
||||
if (configFile) {
|
||||
// all the config file errors are reported as part of semantic check so nothing to report here
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
|
||||
const { configFile, project } = this.getConfigFileAndProject(args);
|
||||
if (configFile) {
|
||||
return this.getConfigFileDiagnostics(configFile, project, args.includeLinePosition);
|
||||
}
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
|
||||
}
|
||||
|
||||
@@ -692,15 +754,15 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getProjectInfo(args: protocol.ProjectInfoRequestArgs): protocol.ProjectInfo {
|
||||
return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList);
|
||||
return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false);
|
||||
}
|
||||
|
||||
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean) {
|
||||
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean, excludeConfigFiles: boolean) {
|
||||
const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName, /*refreshInferredProjects*/ true, /*errorOnMissingProject*/ true);
|
||||
const projectInfo = {
|
||||
configFileName: project.getProjectName(),
|
||||
languageServiceDisabled: !project.languageServiceEnabled,
|
||||
fileNames: needFileNameList ? project.getFileNames() : undefined
|
||||
fileNames: needFileNameList ? project.getFileNames(/*excludeFilesFromExternalLibraries*/ false, excludeConfigFiles) : undefined
|
||||
};
|
||||
return projectInfo;
|
||||
}
|
||||
@@ -1553,7 +1615,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getDiagnosticsForProject(next: NextStep, delay: number, fileName: string): void {
|
||||
const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true);
|
||||
const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true, /*excludeConfigFiles*/ true);
|
||||
if (languageServiceDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace ts.server {
|
||||
export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
|
||||
return {
|
||||
projectName: project.getProjectName(),
|
||||
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true),
|
||||
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true),
|
||||
compilerOptions: project.getCompilerOptions(),
|
||||
typeAcquisition,
|
||||
unresolvedImports,
|
||||
|
||||
+13
-18
@@ -76,7 +76,7 @@ namespace ts.JsTyping {
|
||||
|
||||
if (!safeList) {
|
||||
const result = readConfigFile(safeListPath, (path: string) => host.readFile(path));
|
||||
safeList = result.config ? createMapFromTemplate<string>(result.config) : EmptySafeList;
|
||||
safeList = createMapFromTemplate<string>(result.config);
|
||||
}
|
||||
|
||||
const filesToWatch: string[] = [];
|
||||
@@ -163,20 +163,18 @@ namespace ts.JsTyping {
|
||||
filesToWatch.push(jsonPath);
|
||||
}
|
||||
const result = readConfigFile(jsonPath, (path: string) => host.readFile(path));
|
||||
if (result.config) {
|
||||
const jsonConfig: PackageJson = result.config;
|
||||
if (jsonConfig.dependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.dependencies));
|
||||
}
|
||||
if (jsonConfig.devDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.devDependencies));
|
||||
}
|
||||
if (jsonConfig.optionalDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.optionalDependencies));
|
||||
}
|
||||
if (jsonConfig.peerDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.peerDependencies));
|
||||
}
|
||||
const jsonConfig: PackageJson = result.config;
|
||||
if (jsonConfig.dependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.dependencies));
|
||||
}
|
||||
if (jsonConfig.devDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.devDependencies));
|
||||
}
|
||||
if (jsonConfig.optionalDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.optionalDependencies));
|
||||
}
|
||||
if (jsonConfig.peerDependencies) {
|
||||
mergeTypings(getOwnKeys(jsonConfig.peerDependencies));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,9 +220,6 @@ namespace ts.JsTyping {
|
||||
continue;
|
||||
}
|
||||
const result = readConfigFile(normalizedFileName, (path: string) => host.readFile(path));
|
||||
if (!result.config) {
|
||||
continue;
|
||||
}
|
||||
const packageJson: PackageJson = result.config;
|
||||
|
||||
// npm 3's package.json contains a "_requiredBy" field
|
||||
|
||||
@@ -1299,8 +1299,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const currentOptions = program.getCompilerOptions();
|
||||
const newOptions = hostCache.compilationSettings();
|
||||
// If the compilation settings do no match, then the program is not up-to-date
|
||||
return compareDataObjects(program.getCompilerOptions(), hostCache.compilationSettings());
|
||||
if (!compareDataObjects(currentOptions, newOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If everything matches but the text of config file is changed,
|
||||
// error locations can change for program options, so update the program
|
||||
if (currentOptions.configFile && newOptions.configFile) {
|
||||
return currentOptions.configFile.text === newOptions.configFile.text;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-15
@@ -1109,27 +1109,16 @@ namespace ts {
|
||||
() => {
|
||||
const text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength());
|
||||
|
||||
const result = parseConfigFileTextToJson(fileName, text);
|
||||
|
||||
if (result.error) {
|
||||
return {
|
||||
options: {},
|
||||
typeAcquisition: {},
|
||||
files: [],
|
||||
raw: {},
|
||||
errors: [realizeDiagnostic(result.error, "\r\n")]
|
||||
};
|
||||
}
|
||||
|
||||
const result = parseJsonText(fileName, text);
|
||||
const normalizedFileName = normalizeSlashes(fileName);
|
||||
const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
const configFile = parseJsonSourceFileConfigFileContent(result, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
|
||||
return {
|
||||
options: configFile.options,
|
||||
typeAcquisition: configFile.typeAcquisition,
|
||||
files: configFile.fileNames,
|
||||
raw: configFile.raw,
|
||||
errors: realizeDiagnostics(configFile.errors, "\r\n")
|
||||
errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -1248,4 +1237,4 @@ namespace TypeScript.Services {
|
||||
// TODO: it should be moved into a namespace though.
|
||||
|
||||
/* @internal */
|
||||
const toolsVersion = "2.5";
|
||||
const toolsVersion = "2.5";
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace ts {
|
||||
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o =>
|
||||
typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number"));
|
||||
|
||||
options = clone(options);
|
||||
options = cloneCompilerOptions(options);
|
||||
|
||||
for (const opt of commandLineOptionsStringToEnum) {
|
||||
if (!hasProperty(options, opt.name)) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"../compiler/checker.ts",
|
||||
"../compiler/factory.ts",
|
||||
"../compiler/visitor.ts",
|
||||
"../compiler/transformers/utilities.ts",
|
||||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/esnext.ts",
|
||||
|
||||
@@ -982,6 +982,12 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function cloneCompilerOptions(options: CompilerOptions): CompilerOptions {
|
||||
const result = clone(options);
|
||||
setConfigFileInOptions(result, options && options.configFile);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function compareDataObjects(dst: any, src: any): boolean {
|
||||
if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
|
||||
return false;
|
||||
@@ -1306,30 +1312,6 @@ namespace ts {
|
||||
return ensureScriptKind(fileName, scriptKind);
|
||||
}
|
||||
|
||||
export function sanitizeConfigFile(configFileName: string, content: string) {
|
||||
const options: TranspileOptions = {
|
||||
fileName: "config.js",
|
||||
compilerOptions: {
|
||||
target: ScriptTarget.ES2015,
|
||||
removeComments: true
|
||||
},
|
||||
reportDiagnostics: true
|
||||
};
|
||||
const { outputText, diagnostics } = ts.transpileModule("(" + content + ")", options);
|
||||
// Becasue the content was wrapped in "()", the start position of diagnostics needs to be subtract by 1
|
||||
// also, the emitted result will have "(" in the beginning and ");" in the end. We need to strip these
|
||||
// as well
|
||||
const trimmedOutput = outputText.trim();
|
||||
for (const diagnostic of diagnostics) {
|
||||
diagnostic.start = diagnostic.start - 1;
|
||||
}
|
||||
const {config, error} = parseConfigFileTextToJson(configFileName, trimmedOutput.substring(1, trimmedOutput.length - 2), /*stripComments*/ false);
|
||||
return {
|
||||
configJsonObject: config || {},
|
||||
diagnostics: error ? concatenate(diagnostics, [error]) : diagnostics
|
||||
};
|
||||
}
|
||||
|
||||
export function getFirstNonSpaceCharacterPosition(text: string, position: number) {
|
||||
while (isWhiteSpaceLike(text.charCodeAt(position))) {
|
||||
position += 1;
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
/index.ts(4,5): error TS2339: Property 'y' does not exist on type 'typeof "shortid"'.
|
||||
|
||||
|
||||
==== /tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "bin"
|
||||
},
|
||||
"exclude": [ "node_modules" ]
|
||||
}
|
||||
==== /index.ts (1 errors) ====
|
||||
/// <reference path="/typings/index.d.ts" />
|
||||
import * as foo from "shortid";
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
c:/root/tsconfig.json(5,9): error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
|
||||
|
||||
==== c:/root/tsconfig.json (1 errors) ====
|
||||
// paths should error in the absence of baseurl
|
||||
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
~~~~~~~
|
||||
!!! error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
"*": [
|
||||
"*",
|
||||
"generated/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== c:/root/f1.ts (0 errors) ====
|
||||
export var x = 1;
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
c:/root/tsconfig.json(4,9): error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
|
||||
|
||||
==== c:/root/tsconfig.json (1 errors) ====
|
||||
// paths should error in the absence of baseurl
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
~~~~~~~
|
||||
!!! error TS5060: Option 'paths' cannot be used without specifying '--baseUrl' option.
|
||||
"*": [
|
||||
"*",
|
||||
"generated/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== c:/root/f1.ts (0 errors) ====
|
||||
export var x = 1;
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
tests/cases/compiler/root/tsconfig.json(8,13): error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
tests/cases/compiler/root/tsconfig.json(8,22): error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
|
||||
|
||||
==== tests/cases/compiler/root/tsconfig.json (2 errors) ====
|
||||
// baseurl is defined in tsconfig.json
|
||||
// paths has errors
|
||||
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"*1*": [ "*2*" ]
|
||||
~~~~~
|
||||
!!! error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
~~~~~
|
||||
!!! error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/root/src/folder1/file1.ts (0 errors) ====
|
||||
export var x = 1;
|
||||
@@ -1,8 +1,23 @@
|
||||
error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
tests/cases/compiler/root/tsconfig.json(8,13): error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
tests/cases/compiler/root/tsconfig.json(8,22): error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
|
||||
|
||||
==== tests/cases/compiler/root/tsconfig.json (2 errors) ====
|
||||
// baseurl is defined in tsconfig.json
|
||||
// paths has errors
|
||||
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"*1*": [ "*2*" ]
|
||||
~~~~~
|
||||
!!! error TS5061: Pattern '*1*' can have at most one '*' character.
|
||||
~~~~~
|
||||
!!! error TS5062: Substitution '*2*' in pattern '*1*' in can have at most one '*' character.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/root/src/folder1/file1.ts (0 errors) ====
|
||||
export var x = 1;
|
||||
+10
@@ -1,6 +1,16 @@
|
||||
/a.ts(1,21): error TS2307: Cannot find module 'foo'.
|
||||
|
||||
|
||||
==== /tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"foo": ["foo/foo.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== /a.ts (1 errors) ====
|
||||
import { foo } from "foo";
|
||||
~~~~~
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
error TS5063: Substitutions for pattern '*' should be an array.
|
||||
tests/cases/compiler/tsconfig.json(5,18): error TS5063: Substitutions for pattern '*' should be an array.
|
||||
|
||||
|
||||
==== tests/cases/compiler/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*": "*"
|
||||
~~~
|
||||
!!! error TS5063: Substitutions for pattern '*' should be an array.
|
||||
}
|
||||
}
|
||||
}
|
||||
==== tests/cases/compiler/a.ts (0 errors) ====
|
||||
let x = 1;
|
||||
@@ -1,6 +1,16 @@
|
||||
error TS5064: Substitution '1' for pattern '*' has incorrect type, expected 'string', got 'number'.
|
||||
tests/cases/compiler/tsconfig.json(5,19): error TS5064: Substitution '1' for pattern '*' has incorrect type, expected 'string', got 'number'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*": [1]
|
||||
~
|
||||
!!! error TS5064: Substitution '1' for pattern '*' has incorrect type, expected 'string', got 'number'.
|
||||
}
|
||||
}
|
||||
}
|
||||
==== tests/cases/compiler/a.ts (0 errors) ====
|
||||
let x = 1;
|
||||
@@ -1,6 +1,17 @@
|
||||
error TS5066: Substitutions for pattern 'foo' shouldn't be an empty array.
|
||||
tests/cases/compiler/tsconfig.json(5,20): error TS5066: Substitutions for pattern 'foo' shouldn't be an empty array.
|
||||
|
||||
|
||||
==== tests/cases/compiler/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"foo": []
|
||||
~~
|
||||
!!! error TS5066: Substitutions for pattern 'foo' shouldn't be an empty array.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/a.ts (0 errors) ====
|
||||
let x = 1;
|
||||
+14
@@ -1,6 +1,20 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+14
@@ -1,6 +1,20 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+15
@@ -1,6 +1,21 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true,
|
||||
"noResolve": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+15
@@ -1,6 +1,21 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true,
|
||||
"noResolve": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+13
@@ -1,6 +1,19 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+13
@@ -1,6 +1,19 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+15
@@ -1,6 +1,21 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+15
@@ -1,6 +1,21 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+16
@@ -1,6 +1,22 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true,
|
||||
"noResolve": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+16
@@ -1,6 +1,22 @@
|
||||
main.ts(1,21): error TS2307: Cannot find module 'angular2/core'.
|
||||
|
||||
|
||||
==== tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "system",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true,
|
||||
"noResolve": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
]
|
||||
}
|
||||
==== main.ts (1 errors) ====
|
||||
import * as ng from "angular2/core";
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+6
-1
@@ -1,6 +1,11 @@
|
||||
error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesNotSpecified/tsconfig.json(2,24): error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
|
||||
|
||||
==== DifferentNamesNotSpecified/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "out": "test.js" }
|
||||
~~~~~
|
||||
!!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
}
|
||||
==== DifferentNamesNotSpecified/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+9
-1
@@ -1,7 +1,15 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"out": "test.js",
|
||||
"allowJs": true
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
}
|
||||
}
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/b.js (0 errors) ====
|
||||
|
||||
+12
-3
@@ -1,9 +1,18 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json(3,5): error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json (2 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"out": "test.js",
|
||||
~~~~~
|
||||
!!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
"allowJs": true
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
}
|
||||
}
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
==== DifferentNamesNotSpecifiedWithAllowJs/b.js (0 errors) ====
|
||||
|
||||
+5
@@ -2,5 +2,10 @@ error TS6054: File 'DifferentNamesSpecified/b.js' has unsupported extension. The
|
||||
|
||||
|
||||
!!! error TS6054: File 'DifferentNamesSpecified/b.js' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'.
|
||||
==== DifferentNamesSpecified/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": { "out": "test.js" },
|
||||
"files": [ "a.ts", "b.js" ]
|
||||
}
|
||||
==== DifferentNamesSpecified/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+7
-1
@@ -1,8 +1,14 @@
|
||||
error TS6054: File 'DifferentNamesSpecified/b.js' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'.
|
||||
error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesSpecified/tsconfig.json(2,24): error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
|
||||
|
||||
!!! error TS6054: File 'DifferentNamesSpecified/b.js' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'.
|
||||
==== DifferentNamesSpecified/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "out": "test.js" },
|
||||
~~~~~
|
||||
!!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
"files": [ "a.ts", "b.js" ]
|
||||
}
|
||||
==== DifferentNamesSpecified/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+10
-1
@@ -1,7 +1,16 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
DifferentNamesSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== DifferentNamesSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"out": "test.js",
|
||||
"allowJs": true
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
},
|
||||
"files": [ "a.ts", "b.js" ]
|
||||
}
|
||||
==== DifferentNamesSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
==== DifferentNamesSpecifiedWithAllowJs/b.js (0 errors) ====
|
||||
|
||||
+13
-3
@@ -1,9 +1,19 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesSpecifiedWithAllowJs/tsconfig.json(3,5): error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
DifferentNamesSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== DifferentNamesSpecifiedWithAllowJs/tsconfig.json (2 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"out": "test.js",
|
||||
~~~~~
|
||||
!!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out.
|
||||
"allowJs": true
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
},
|
||||
"files": [ "a.ts", "b.js" ]
|
||||
}
|
||||
==== DifferentNamesSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
==== DifferentNamesSpecifiedWithAllowJs/b.js (0 errors) ====
|
||||
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameDTsSpecifiedWithAllowJs/tsconfig.json(2,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameDTsSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "allowJs": true },
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
"files": [ "a.d.ts" ]
|
||||
}
|
||||
==== SameNameDTsSpecifiedWithAllowJs/a.d.ts (0 errors) ====
|
||||
declare var test: number;
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameDTsSpecifiedWithAllowJs/tsconfig.json(2,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameDTsSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "allowJs": true },
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
"files": [ "a.d.ts" ]
|
||||
}
|
||||
==== SameNameDTsSpecifiedWithAllowJs/a.d.ts (0 errors) ====
|
||||
declare var test: number;
|
||||
+5
-2
@@ -1,11 +1,14 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file.
|
||||
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
|
||||
SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
!!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file.
|
||||
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{ "compilerOptions": { "allowJs": true } }
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/a.d.ts (0 errors) ====
|
||||
declare var a: number;
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/a.js (0 errors) ====
|
||||
|
||||
+5
-2
@@ -1,11 +1,14 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file.
|
||||
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
|
||||
SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
!!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file.
|
||||
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{ "compilerOptions": { "allowJs": true } }
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/a.d.ts (0 errors) ====
|
||||
declare var a: number;
|
||||
==== SameNameDTsNotSpecifiedWithAllowJs/a.js (0 errors) ====
|
||||
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameFilesNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameFilesNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{ "compilerOptions": { "allowJs": true } }
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== SameNameFilesNotSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameFilesNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameFilesNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{ "compilerOptions": { "allowJs": true } }
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
==== SameNameFilesNotSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameTsSpecifiedWithAllowJs/tsconfig.json(2,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameTsSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "allowJs": true },
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
"files": [ "a.ts" ]
|
||||
}
|
||||
==== SameNameTsSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
SameNameTsSpecifiedWithAllowJs/tsconfig.json(2,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
|
||||
|
||||
==== SameNameTsSpecifiedWithAllowJs/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "allowJs": true },
|
||||
~~~~~~~~~
|
||||
!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
|
||||
"files": [ "a.ts" ]
|
||||
}
|
||||
==== SameNameTsSpecifiedWithAllowJs/a.ts (0 errors) ====
|
||||
var test = 10;
|
||||
+10
@@ -1,6 +1,16 @@
|
||||
importHigher/root.ts(6,1): error TS2322: Type '"10"' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== importHigher/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"maxNodeModuleJsDepth": 2
|
||||
}
|
||||
}
|
||||
|
||||
==== entry.js (0 errors) ====
|
||||
var m3 = require("m3");
|
||||
|
||||
|
||||
+10
@@ -1,6 +1,16 @@
|
||||
importHigher/root.ts(6,1): error TS2322: Type '"10"' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== importHigher/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"maxNodeModuleJsDepth": 2
|
||||
}
|
||||
}
|
||||
|
||||
==== entry.js (0 errors) ====
|
||||
var m3 = require("m3");
|
||||
|
||||
|
||||
+11
@@ -2,6 +2,17 @@ maxDepthExceeded/root.ts(3,1): error TS2322: Type '"10"' is not assignable to ty
|
||||
maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property.
|
||||
|
||||
|
||||
==== maxDepthExceeded/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": 1, // Note: Module m1 is already included as a root file
|
||||
"outDir": "built"
|
||||
},
|
||||
"include": ["**/*"],
|
||||
"exclude": ["node_modules/m2/**/*"]
|
||||
}
|
||||
|
||||
==== relative.js (0 errors) ====
|
||||
exports.relativeProp = true;
|
||||
|
||||
|
||||
+11
@@ -2,6 +2,17 @@ maxDepthExceeded/root.ts(3,1): error TS2322: Type '"10"' is not assignable to ty
|
||||
maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property.
|
||||
|
||||
|
||||
==== maxDepthExceeded/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": 1, // Note: Module m1 is already included as a root file
|
||||
"outDir": "built"
|
||||
},
|
||||
"include": ["**/*"],
|
||||
"exclude": ["node_modules/m2/**/*"]
|
||||
}
|
||||
|
||||
==== relative.js (0 errors) ====
|
||||
exports.relativeProp = true;
|
||||
|
||||
|
||||
+8
@@ -1,6 +1,14 @@
|
||||
maxDepthIncreased/root.ts(7,1): error TS2322: Type '"10"' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== maxDepthIncreased/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": 3
|
||||
}
|
||||
}
|
||||
|
||||
==== index.js (0 errors) ====
|
||||
exports.person = {
|
||||
"name": "John Doe",
|
||||
|
||||
+8
@@ -1,6 +1,14 @@
|
||||
maxDepthIncreased/root.ts(7,1): error TS2322: Type '"10"' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== maxDepthIncreased/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": 3
|
||||
}
|
||||
}
|
||||
|
||||
==== index.js (0 errors) ====
|
||||
exports.person = {
|
||||
"name": "John Doe",
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
////{ "files": ["a.ts", "b.ts"] }
|
||||
|
||||
goTo.file("a.ts")
|
||||
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"])
|
||||
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
////{ "files": ["a.ts", "c.ts", "b.ts"] }
|
||||
|
||||
goTo.file("a.ts");
|
||||
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"])
|
||||
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])
|
||||
|
||||
@@ -76,6 +76,40 @@ namespace ts {
|
||||
"c:/dev/jspm_packages/a.ts"
|
||||
]);
|
||||
|
||||
function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void {
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
}
|
||||
|
||||
function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) {
|
||||
{
|
||||
const jsonText = JSON.stringify(json);
|
||||
const result = parseJsonText("c:/dev/tsconfig.json", jsonText);
|
||||
const actual = ts.parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
for (const error of expected.errors) {
|
||||
if (error.file) {
|
||||
error.file = result;
|
||||
}
|
||||
}
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
{
|
||||
const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
expected.errors = map(expected.errors, error => {
|
||||
return <Diagnostic>{
|
||||
category: error.category,
|
||||
code: error.code,
|
||||
file: undefined,
|
||||
length: undefined,
|
||||
messageText: error.messageText,
|
||||
start: undefined,
|
||||
};
|
||||
});
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
describe("matchFiles", () => {
|
||||
describe("with literal file list", () => {
|
||||
it("without exclusions", () => {
|
||||
@@ -94,10 +128,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("missing files are still present", () => {
|
||||
const json = {
|
||||
@@ -115,10 +146,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("are not removed due to excludes", () => {
|
||||
const json = {
|
||||
@@ -139,10 +167,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -163,10 +188,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with non .ts file extensions are excluded", () => {
|
||||
const json = {
|
||||
@@ -181,10 +203,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -199,10 +218,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with literal excludes", () => {
|
||||
const json = {
|
||||
@@ -222,10 +238,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with wildcard excludes", () => {
|
||||
const json = {
|
||||
@@ -252,10 +265,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive excludes", () => {
|
||||
const json = {
|
||||
@@ -281,10 +291,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with case sensitive exclude", () => {
|
||||
const json = {
|
||||
@@ -303,10 +310,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -327,10 +331,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -356,10 +357,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -384,10 +382,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -410,10 +405,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`*` matches only ts files", () => {
|
||||
const json = {
|
||||
@@ -433,10 +425,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`?` matches only a single character", () => {
|
||||
const json = {
|
||||
@@ -455,10 +444,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive directory", () => {
|
||||
const json = {
|
||||
@@ -479,10 +465,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with multiple recursive directories", () => {
|
||||
const json = {
|
||||
@@ -505,10 +488,7 @@ namespace ts {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("case sensitive", () => {
|
||||
const json = {
|
||||
@@ -526,10 +506,7 @@ namespace ts {
|
||||
"/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -545,10 +522,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("always include literal files", () => {
|
||||
const json = {
|
||||
@@ -572,10 +546,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude folders", () => {
|
||||
const json = {
|
||||
@@ -599,10 +570,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -620,10 +588,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -646,10 +611,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -671,10 +633,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude .js files when allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -695,10 +654,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include .js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -722,10 +678,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include paths outside of the project", () => {
|
||||
const json = {
|
||||
@@ -748,10 +701,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("include paths outside of the project using relative paths", () => {
|
||||
@@ -774,10 +724,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -794,10 +741,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -816,10 +760,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -840,10 +781,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("with jsx=none, allowJs=false", () => {
|
||||
@@ -866,10 +804,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -893,10 +828,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -947,10 +879,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -976,10 +905,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -1025,10 +951,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1045,10 +968,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
describe("with multiple recursive directory patterns", () => {
|
||||
@@ -1066,10 +986,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1095,10 +1012,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1117,10 +1031,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("in includes after a subdirectory", () => {
|
||||
@@ -1137,10 +1048,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("in excludes immediately after", () => {
|
||||
@@ -1167,10 +1075,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("in excludes after a subdirectory", () => {
|
||||
@@ -1197,10 +1102,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user