From 5771adbbe72a7b82ad58f4dd1b092f9444d3c604 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Jan 2017 13:51:00 -0800 Subject: [PATCH 01/17] Resolve Json file when module resolution strategy is node --- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 6 ++- src/compiler/moduleNameResolver.ts | 13 ++++-- src/compiler/parser.ts | 16 ++++++- src/compiler/program.ts | 3 +- src/harness/harness.ts | 2 +- .../unittests/reuseProgramStructure.ts | 4 ++ .../unittests/tsserverProjectSystem.ts | 4 ++ .../cachedModuleResolution6.trace.json | 7 +++ .../cachedModuleResolution7.trace.json | 5 +++ ...portWithTrailingSlash_noResolve.trace.json | 2 + ...lutionWithExtensions_unexpected.trace.json | 13 ++++++ ...utionWithExtensions_unexpected2.trace.json | 7 +++ .../packageJsonMain_isNonRecursive.trace.json | 12 +++++ ...tion_withExtension_failedLookup.trace.json | 8 ++++ .../reference/requireOfJsonFile.errors.txt | 22 +++++++++ .../baselines/reference/requireOfJsonFile.js | 28 ++++++++++++ .../reference/requireOfJsonFile.symbols | 32 +++++++++++++ .../reference/requireOfJsonFile.types | 45 +++++++++++++++++++ ...mMultipleNodeModulesDirectories.trace.json | 12 +++++ ...romNodeModulesInParentDirectory.trace.json | 3 ++ tests/cases/compiler/requireOfJsonFile.ts | 16 +++++++ 22 files changed, 252 insertions(+), 10 deletions(-) mode change 100755 => 100644 src/compiler/program.ts create mode 100644 tests/baselines/reference/requireOfJsonFile.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFile.js create mode 100644 tests/baselines/reference/requireOfJsonFile.symbols create mode 100644 tests/baselines/reference/requireOfJsonFile.types create mode 100644 tests/cases/compiler/requireOfJsonFile.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb7f8d013fcc7..3a715e5acb9c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2084,7 +2084,7 @@ namespace ts { } // May be an untyped module. If so, ignore resolutionDiagnostic. - if (resolvedModule && !extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { + if (resolvedModule && !resolutionExtensionIsTypeScriptOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { if (isForAugmentation) { const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ecf667237c50e..00a28dbbbcd77 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2758,7 +2758,7 @@ namespace ts { } } - const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx]; + const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; export function removeFileExtension(path: string): string { for (const ext of extensionsToRemove) { const extensionless = tryRemoveExtension(path, ext); @@ -3091,6 +3091,10 @@ namespace ts { return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts; } + export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) { + return extensionIsTypeScript(ext) || ext === Extension.Json; + } + /** * Gets the extension from a path. * Path must have a valid extension. diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 50181bb98e4f7..30f310cac10e3 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -48,6 +48,7 @@ namespace ts { enum Extensions { TypeScript, /** '.ts', '.tsx', or '.d.ts' */ JavaScript, /** '.js' or '.jsx' */ + Json, /** '.json' */ DtsOnly /** Only '.d.ts' */ } @@ -730,7 +731,7 @@ namespace ts { const failedLookupLocations: string[] = []; const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; - const result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); + const result = (jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript))) || tryResolve(Extensions.Json); if (result && result.value) { const { resolved, originalPath, isExternalLibraryImport } = result.value; return createResolvedModuleWithFailedLookupLocations(resolved, originalPath, isExternalLibraryImport, failedLookupLocations); @@ -889,7 +890,7 @@ namespace ts { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJavaScriptFileExtension(candidate)) { + if (hasJavaScriptFileExtension(candidate) || fileExtensionIs(candidate, Extension.Json)) { const extensionless = removeFileExtension(candidate); if (state.traceEnabled) { const extension = candidate.substring(extensionless.length); @@ -916,6 +917,8 @@ namespace ts { return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts); case Extensions.JavaScript: return tryExtension(Extension.Js) || tryExtension(Extension.Jsx); + case Extensions.Json: + return tryExtension(Extension.Json); } function tryExtension(ext: Extension): PathAndExtension | undefined { @@ -1013,7 +1016,7 @@ namespace ts { } function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, extensions: Extensions, candidate: string, failedLookupLocations: Push, state: ModuleResolutionState): PathAndExtension | undefined { - const file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); + const file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript && extensions !== Extensions.Json, jsonContent, candidate, state); if (!file) { return undefined; } @@ -1052,6 +1055,8 @@ namespace ts { switch (extensions) { case Extensions.JavaScript: return extension === Extension.Js || extension === Extension.Jsx; + case Extensions.Json: + return extension === Extension.Json; case Extensions.TypeScript: return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Dts; case Extensions.DtsOnly: @@ -1127,7 +1132,7 @@ namespace ts { if (packageResult) { return packageResult; } - if (extensions !== Extensions.JavaScript) { + if (extensions !== Extensions.JavaScript && extensions !== Extensions.Json) { const nodeModulesAtTypes = combinePaths(nodeModulesFolder, "@types"); let nodeModulesAtTypesExists = nodeModulesFolderExists; if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes, state.host)) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 70ddb7b791df1..813a77d71a616 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -260,6 +260,7 @@ namespace ts { return visitNodes(cbNode, cbNodes, (node).statements); case SyntaxKind.SourceFile: return visitNodes(cbNode, cbNodes, (node).statements) || + visitNode(cbNode, (node).jsonObject) || visitNode(cbNode, (node).endOfFileToken); case SyntaxKind.VariableStatement: return visitNodes(cbNode, cbNodes, node.decorators) || @@ -660,6 +661,13 @@ namespace ts { export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { scriptKind = ensureScriptKind(fileName, scriptKind); + if (scriptKind === ScriptKind.JSON) { + const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); + result.statements = emptyArray; + result.typeReferenceDirectives = emptyArray; + result.amdDependencies = emptyArray; + return result; + } initializeState(sourceText, languageVersion, syntaxCursor, scriptKind); @@ -681,8 +689,8 @@ namespace ts { return isInvalid ? entityName : undefined; } - export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { - initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON); + export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): JsonSourceFile { + initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); const result = sourceFile; @@ -701,6 +709,10 @@ namespace ts { parseExpected(SyntaxKind.OpenBraceToken); } + if (setParentNodes) { + fixupParentReferences(sourceFile); + } + sourceFile.parseDiagnostics = parseDiagnostics; clearState(); return result; diff --git a/src/compiler/program.ts b/src/compiler/program.ts old mode 100755 new mode 100644 index 1ce672a6a7536..0f2cb34ec2160 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1975,7 +1975,7 @@ namespace ts { } const isFromNodeModulesSearch = resolution.isExternalLibraryImport; - const isJsFile = !extensionIsTypeScript(resolution.extension); + const isJsFile = !resolutionExtensionIsTypeScriptOrJson(resolution.extension); const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; const resolvedFileName = resolution.resolvedFileName; @@ -2404,6 +2404,7 @@ namespace ts { switch (extension) { case Extension.Ts: case Extension.Dts: + case Extension.Json: // These are always allowed. return undefined; case Extension.Tsx: diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d3bd537ad4c08..9fa0ce6087e7e 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1207,7 +1207,7 @@ namespace Harness { } - const programFileNames = programFiles.map(file => file.unitName); + const programFileNames = programFiles.map(file => file.unitName).filter(fileName => !ts.fileExtensionIs(fileName, ts.Extension.Json)); const compilerHost = createCompilerHost( programFiles.concat(otherFiles), diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index 70325831f5129..c43fe2f5528e0 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -471,6 +471,10 @@ namespace ts { "File 'node_modules/a.jsx' does not exist.", "File 'node_modules/a/index.js' does not exist.", "File 'node_modules/a/index.jsx' does not exist.", + "Loading module 'a' from 'node_modules' folder, target file type 'Json'.", + "File 'node_modules/a/package.json' does not exist.", + "File 'node_modules/a.json' does not exist.", + "File 'node_modules/a/index.json' does not exist.", "======== Module name 'a' was not resolved. ========" ], "initialProgram: execute module resolution normally."); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index e09dff2a6d5dd..517896ca8ca5f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3221,6 +3221,10 @@ namespace ts.projectSystem { "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", + "Loading module 'lib' from 'node_modules' folder, target file type 'Json'.", + "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/node_modules' does not exist, skipping all lookups in it.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'lib' was not resolved. ========", `Auto discovery for typings is enabled in project '${proj.getProjectName()}'. Running extra resolution pass for module 'lib' using cache location '/a/cache'.`, "File '/a/cache/node_modules/lib.d.ts' does not exist.", diff --git a/tests/baselines/reference/cachedModuleResolution6.trace.json b/tests/baselines/reference/cachedModuleResolution6.trace.json index 50c1c15b3e1be..efb20f4ddc1be 100644 --- a/tests/baselines/reference/cachedModuleResolution6.trace.json +++ b/tests/baselines/reference/cachedModuleResolution6.trace.json @@ -15,6 +15,13 @@ "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", + "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", + "Directory '/a/b/c/d/e/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/b/c/d/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/b/c/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/node_modules' does not exist, skipping all lookups in it.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========", "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", diff --git a/tests/baselines/reference/cachedModuleResolution7.trace.json b/tests/baselines/reference/cachedModuleResolution7.trace.json index fa1db9d115e28..74c57e042503a 100644 --- a/tests/baselines/reference/cachedModuleResolution7.trace.json +++ b/tests/baselines/reference/cachedModuleResolution7.trace.json @@ -11,6 +11,11 @@ "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", + "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", + "Directory '/a/b/c/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", + "Directory '/a/node_modules' does not exist, skipping all lookups in it.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========", "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", diff --git a/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json b/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json index 1ee467c378905..0f66680ea4439 100644 --- a/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json +++ b/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json @@ -5,5 +5,7 @@ "Directory '/foo/' does not exist, skipping all lookups in it.", "Loading module as file / folder, candidate module location '/foo/', target file type 'JavaScript'.", "Directory '/foo/' does not exist, skipping all lookups in it.", + "Loading module as file / folder, candidate module location '/foo/', target file type 'Json'.", + "Directory '/foo/' does not exist, skipping all lookups in it.", "======== Module name './foo/' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index 5f32a4bf511ef..f2cbd45826d1f 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -31,5 +31,18 @@ "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", "File '/node_modules/normalize.css/index.js' does not exist.", "File '/node_modules/normalize.css/index.jsx' does not exist.", + "Loading module 'normalize.css' from 'node_modules' folder, target file type 'Json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", + "Found 'package.json' at '/node_modules/normalize.css/package.json'.", + "File '/node_modules/normalize.css.json' does not exist.", + "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", + "File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.", + "File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.", + "Loading module as file / folder, candidate module location '/node_modules/normalize.css/normalize.css', target file type 'Json'.", + "File '/node_modules/normalize.css/normalize.css.json' does not exist.", + "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", + "File '/node_modules/normalize.css/index.json' does not exist.", "======== Module name 'normalize.css' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index bab6be18d397f..3dd0a7861e372 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -34,5 +34,12 @@ "'package.json' does not have a 'main' field.", "File '/node_modules/foo/index.js' does not exist.", "File '/node_modules/foo/index.jsx' does not exist.", + "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo.json' does not exist.", + "'package.json' does not have a 'main' field.", + "File '/node_modules/foo/index.json' does not exist.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json index 81f5be11a6d76..653f224b43a98 100644 --- a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -31,5 +31,17 @@ "File '/node_modules/foo/oof/index.jsx' does not exist.", "File '/node_modules/foo/index.js' does not exist.", "File '/node_modules/foo/index.jsx' does not exist.", + "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo.json' does not exist.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", + "File '/node_modules/foo/oof' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/foo/oof', target file type 'Json'.", + "File '/node_modules/foo/oof.json' does not exist.", + "File '/node_modules/foo/oof/index.json' does not exist.", + "File '/node_modules/foo/index.json' does not exist.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json index 803520f12fd5a..aa3489d9fe1c0 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json @@ -17,5 +17,13 @@ "Loading module as file / folder, candidate module location '/foo/foo.ts', target file type 'JavaScript'.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", "Directory '/node_modules' does not exist, skipping all lookups in it.", + "'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo'.", + "'paths' option is specified, looking for a pattern to match module name 'foo'.", + "Module name 'foo', matched pattern 'foo'.", + "Trying substitution 'foo/foo.ts', candidate module location: 'foo/foo.ts'.", + "File '/foo/foo.ts' does not exist.", + "Loading module as file / folder, candidate module location '/foo/foo.ts', target file type 'Json'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFile.errors.txt b/tests/baselines/reference/requireOfJsonFile.errors.txt new file mode 100644 index 0000000000000..9e1239803087c --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFile.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/file1.ts(1,21): error TS2306: File 'tests/cases/compiler/b.json' is not a module. +tests/cases/compiler/file1.ts(3,21): error TS2306: File 'tests/cases/compiler/b.json' is not a module. + + +==== tests/cases/compiler/file1.ts (2 errors) ==== + import b1 = require('./b'); + ~~~~~ +!!! error TS2306: File 'tests/cases/compiler/b.json' is not a module. + let x = b1.a; + import b2 = require('./b.json'); + ~~~~~~~~~~ +!!! error TS2306: File 'tests/cases/compiler/b.json' is not a module. + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (0 errors) ==== + { + "a": true, + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js new file mode 100644 index 0000000000000..b3b37406830e5 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/requireOfJsonFile.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [b.js] +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFile.symbols b/tests/baselines/reference/requireOfJsonFile.symbols new file mode 100644 index 0000000000000..cdf69b0e4bc07 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFile.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFile.types b/tests/baselines/reference/requireOfJsonFile.types new file mode 100644 index 0000000000000..01f84ffc0accd --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFile.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : any + +let x = b1.a; +>x : any +>b1.a : any +>b1 : any +>a : any + +import b2 = require('./b.json'); +>b2 : any + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : any +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : any +>b : any +>b : any +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { [x: string]: any; "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json index fdcbcdb7ab1d0..bee93e5be25c6 100644 --- a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json +++ b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json @@ -17,6 +17,10 @@ "File '/foo/node_modules/xyz.jsx' does not exist.", "File '/node_modules/xyz.js' does not exist.", "File '/node_modules/xyz.jsx' does not exist.", + "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", + "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", + "File '/foo/node_modules/xyz.json' does not exist.", + "File '/node_modules/xyz.json' does not exist.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving module 'pdq' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -36,6 +40,10 @@ "File '/foo/node_modules/pdq.jsx' does not exist.", "File '/node_modules/pdq.js' does not exist.", "File '/node_modules/pdq.jsx' does not exist.", + "Loading module 'pdq' from 'node_modules' folder, target file type 'Json'.", + "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", + "File '/foo/node_modules/pdq.json' does not exist.", + "File '/node_modules/pdq.json' does not exist.", "======== Module name 'pdq' was not resolved. ========", "======== Resolving module 'abc' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -55,6 +63,10 @@ "File '/foo/node_modules/abc.jsx' does not exist.", "File '/node_modules/abc.js' does not exist.", "File '/node_modules/abc.jsx' does not exist.", + "Loading module 'abc' from 'node_modules' folder, target file type 'Json'.", + "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", + "File '/foo/node_modules/abc.json' does not exist.", + "File '/node_modules/abc.json' does not exist.", "======== Module name 'abc' was not resolved. ========", "======== Resolving type reference directive 'grumpy', containing file '/foo/bar/__inferred type names__.ts', root directory '/foo/node_modules/@types,/node_modules/@types'. ========", "Resolving with primary search path '/foo/node_modules/@types, /node_modules/@types'.", diff --git a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json index a15e20239c65a..95fdca59f945e 100644 --- a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json +++ b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json @@ -11,6 +11,9 @@ "Directory '/src/node_modules' does not exist, skipping all lookups in it.", "File '/node_modules/xyz.js' does not exist.", "File '/node_modules/xyz.jsx' does not exist.", + "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", + "Directory '/src/node_modules' does not exist, skipping all lookups in it.", + "File '/node_modules/xyz.json' does not exist.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving type reference directive 'foo', containing file '/src/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts new file mode 100644 index 0000000000000..7295dac0179cf --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -0,0 +1,16 @@ +// @module: commonjs + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file From ee2e267d38ac426ba448ef6ec15f5f7aef21a3e6 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 26 Jan 2018 14:06:22 -0800 Subject: [PATCH 02/17] Replace usage of jsonObject on JsonSourceFile --- src/compiler/commandLineParser.ts | 8 ++++---- src/compiler/parser.ts | 14 ++++++++++---- src/compiler/program.ts | 4 ++-- src/compiler/types.ts | 6 +++++- tests/baselines/reference/api/tsserverlibrary.d.ts | 5 ++++- tests/baselines/reference/api/typescript.d.ts | 5 ++++- tests/baselines/reference/requireOfJsonFile.js | 4 ++++ 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 825f2c632e75d..08378374c9b00 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1056,11 +1056,11 @@ namespace ts { errors: Push, knownRootOptions: Map | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { - if (!sourceFile.jsonObject) { + if (!sourceFile.statements.length) { return {}; } - return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions, + return convertObjectLiteralExpressionToJson(sourceFile.statements[0].expression, knownRootOptions, /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined); function convertObjectLiteralExpressionToJson( @@ -2092,8 +2092,8 @@ namespace ts { }); function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic { - if (jsonSourceFile && jsonSourceFile.jsonObject) { - for (const property of getPropertyAssignment(jsonSourceFile.jsonObject, specKey)) { + if (jsonSourceFile && jsonSourceFile.statements.length) { + for (const property of getPropertyAssignment(jsonSourceFile.statements[0].expression, specKey)) { if (isArrayLiteralExpression(property.initializer)) { for (const element of property.initializer.elements) { if (isStringLiteral(element) && element.text === spec) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 813a77d71a616..9eaab774a1be3 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -260,7 +260,6 @@ namespace ts { return visitNodes(cbNode, cbNodes, (node).statements); case SyntaxKind.SourceFile: return visitNodes(cbNode, cbNodes, (node).statements) || - visitNode(cbNode, (node).jsonObject) || visitNode(cbNode, (node).endOfFileToken); case SyntaxKind.VariableStatement: return visitNodes(cbNode, cbNodes, node.decorators) || @@ -663,7 +662,6 @@ namespace ts { scriptKind = ensureScriptKind(fileName, scriptKind); if (scriptKind === ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); - result.statements = emptyArray; result.typeReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; return result; @@ -693,22 +691,30 @@ namespace ts { initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); - const result = sourceFile; + const result = sourceFile as JsonSourceFile; // Prime the scanner. nextToken(); + const pos = getNodePos(); if (token() === SyntaxKind.EndOfFileToken) { sourceFile.endOfFileToken = parseTokenNode(); } else if (token() === SyntaxKind.OpenBraceToken || lookAhead(() => token() === SyntaxKind.StringLiteral)) { - result.jsonObject = parseObjectLiteralExpression(); + const statement = createNode(SyntaxKind.ExpressionStatement) as JsonObjectLiteralExpressionStatement; + statement.expression = parseObjectLiteralExpression(); + finishNode(statement); + sourceFile.statements = createNodeArray([statement], pos); sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); } else { parseExpected(SyntaxKind.OpenBraceToken); } + if (!sourceFile.statements) { + sourceFile.statements = createNodeArray([], pos, pos); + } + if (setParentNodes) { fixupParentReferences(sourceFile); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0f2cb34ec2160..b2ea3467916b2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2333,8 +2333,8 @@ namespace ts { 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 (options.configFile && options.configFile.statements.length) { + for (const prop of getPropertyAssignment(options.configFile.statements[0].expression, "compilerOptions")) { if (isObjectLiteralExpression(prop.initializer)) { _compilerOptionsObjectLiteralSyntax = prop.initializer; break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0e1f08a69d840..d550bf9704fb7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2576,10 +2576,14 @@ namespace ts { } export interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + export interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } + export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ee3bd07d28028..29ed483e632b5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1631,9 +1631,12 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0075da066683d..430cfb9c44434 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1631,9 +1631,12 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - jsonObject?: ObjectLiteralExpression; + statements: NodeArray; extendedSourceFiles?: string[]; } + interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression; + } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile | undefined; diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js index b3b37406830e5..6b9ca77370717 100644 --- a/tests/baselines/reference/requireOfJsonFile.js +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -16,6 +16,10 @@ if (x) { } //// [b.js] +{ + "a": true, + "b": "hello" +}; //// [file1.js] "use strict"; exports.__esModule = true; From 3572fad9817303a4356097381304899c5678924f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Jan 2017 13:51:00 -0800 Subject: [PATCH 03/17] Bind and resolve the module for json file --- src/compiler/binder.ts | 11 +++++++ src/compiler/checker.ts | 5 +++ src/compiler/utilities.ts | 5 +++ .../reference/requireOfJsonFile.errors.txt | 22 ------------- .../reference/requireOfJsonFile.symbols | 6 ++++ .../reference/requireOfJsonFile.types | 32 +++++++++---------- 6 files changed, 43 insertions(+), 38 deletions(-) delete mode 100644 tests/baselines/reference/requireOfJsonFile.errors.txt diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 782363dd6dfc8..2b289a0e988aa 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -288,6 +288,10 @@ namespace ts { return InternalSymbolName.Index; case SyntaxKind.ExportDeclaration: return InternalSymbolName.ExportStar; + case SyntaxKind.SourceFile: + // json file should behave as + // module.exports = ... + return InternalSymbolName.ExportEquals; case SyntaxKind.BinaryExpression: if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) { // module.exports = ... @@ -2220,6 +2224,13 @@ namespace ts { if (isExternalModule(file)) { bindSourceFileAsExternalModule(); } + else if (isJsonSourceFile(file)) { + bindSourceFileAsExternalModule(); + // Create symbol equivalent for the module.exports = {} + const originalSymbol = file.symbol; + declareSymbol(file.symbol.exports, file.symbol, file, SymbolFlags.Property, SymbolFlags.All); + file.symbol = originalSymbol; + } } function bindSourceFileAsExternalModule() { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3a715e5acb9c3..ba53d2aa7aaa1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4366,6 +4366,11 @@ namespace ts { return links.type = anyType; } // Handle export default expressions + if (declaration.kind === SyntaxKind.SourceFile) { + Debug.assert(isJsonSourceFile(declaration as SourceFile)); + const jsonSourceFile = declaration; + return links.type = jsonSourceFile.statements.length ? checkObjectLiteral(jsonSourceFile.statements[0].expression) : emptyObjectType; + } if (declaration.kind === SyntaxKind.ExportAssignment) { return links.type = checkExpression((declaration).expression); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d8ee9f3dbf0f4..e0f20cdda7d9d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -701,6 +701,11 @@ namespace ts { return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined; } + + export function isJsonSourceFile(file: SourceFile): file is JsonSourceFile { + return file.scriptKind === ScriptKind.JSON; + } + export function isConstEnumDeclaration(node: Node): boolean { return node.kind === SyntaxKind.EnumDeclaration && isConst(node); } diff --git a/tests/baselines/reference/requireOfJsonFile.errors.txt b/tests/baselines/reference/requireOfJsonFile.errors.txt deleted file mode 100644 index 9e1239803087c..0000000000000 --- a/tests/baselines/reference/requireOfJsonFile.errors.txt +++ /dev/null @@ -1,22 +0,0 @@ -tests/cases/compiler/file1.ts(1,21): error TS2306: File 'tests/cases/compiler/b.json' is not a module. -tests/cases/compiler/file1.ts(3,21): error TS2306: File 'tests/cases/compiler/b.json' is not a module. - - -==== tests/cases/compiler/file1.ts (2 errors) ==== - import b1 = require('./b'); - ~~~~~ -!!! error TS2306: File 'tests/cases/compiler/b.json' is not a module. - let x = b1.a; - import b2 = require('./b.json'); - ~~~~~~~~~~ -!!! error TS2306: File 'tests/cases/compiler/b.json' is not a module. - if (x) { - let b = b2.b; - x = (b1.b === b); - } - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFile.symbols b/tests/baselines/reference/requireOfJsonFile.symbols index cdf69b0e4bc07..803c02e016a5d 100644 --- a/tests/baselines/reference/requireOfJsonFile.symbols +++ b/tests/baselines/reference/requireOfJsonFile.symbols @@ -4,7 +4,9 @@ import b1 = require('./b'); let x = b1.a; >x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) import b2 = require('./b.json'); >b2 : Symbol(b2, Decl(file1.ts, 1, 13)) @@ -14,11 +16,15 @@ if (x) { let b = b2.b; >b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) >b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) x = (b1.b === b); >x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) >b : Symbol(b, Decl(file1.ts, 4, 7)) } diff --git a/tests/baselines/reference/requireOfJsonFile.types b/tests/baselines/reference/requireOfJsonFile.types index 01f84ffc0accd..40bb6d0f65d28 100644 --- a/tests/baselines/reference/requireOfJsonFile.types +++ b/tests/baselines/reference/requireOfJsonFile.types @@ -1,34 +1,34 @@ === tests/cases/compiler/file1.ts === import b1 = require('./b'); ->b1 : any +>b1 : { [x: string]: any; "a": boolean; "b": string; } let x = b1.a; ->x : any ->b1.a : any ->b1 : any ->a : any +>x : boolean +>b1.a : boolean +>b1 : { [x: string]: any; "a": boolean; "b": string; } +>a : boolean import b2 = require('./b.json'); ->b2 : any +>b2 : { [x: string]: any; "a": boolean; "b": string; } if (x) { ->x : any +>x : boolean let b = b2.b; ->b : any ->b2.b : any ->b2 : any ->b : any +>b : string +>b2.b : string +>b2 : { [x: string]: any; "a": boolean; "b": string; } +>b : string x = (b1.b === b); >x = (b1.b === b) : boolean ->x : any +>x : boolean >(b1.b === b) : boolean >b1.b === b : boolean ->b1.b : any ->b1 : any ->b : any ->b : any +>b1.b : string +>b1 : { [x: string]: any; "a": boolean; "b": string; } +>b : string +>b : string } === tests/cases/compiler/b.json === From 00b6c32a10b4714fe8622eb4e3db6cf8e42a6d63 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Jan 2017 13:51:00 -0800 Subject: [PATCH 04/17] Fix emit for json file --- src/compiler/emitter.ts | 8 +++++++- src/harness/harness.ts | 6 +++++- tests/baselines/reference/requireOfJsonFile.js | 4 ++-- tests/cases/compiler/requireOfJsonFile.ts | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3fa05950b23d8..3c4f7d8b19f58 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -56,6 +56,10 @@ namespace ts { // 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 (isJsonSourceFile(sourceFile)) { + return Extension.Json; + } + if (options.jsx === JsxEmit.Preserve) { if (isSourceFileJavaScript(sourceFile)) { if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) { @@ -1615,7 +1619,9 @@ namespace ts { function emitExpressionStatement(node: ExpressionStatement) { emitExpression(node.expression); - writeSemicolon(); + if (!isJsonSourceFile(currentSourceFile)) { + writeSemicolon(); + } } function emitIfStatement(node: IfStatement) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9fa0ce6087e7e..fd86922ae0128 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1802,6 +1802,10 @@ namespace Harness { return ts.endsWith(fileName, ts.Extension.Jsx); } + export function isJSON(fileName: string) { + return ts.endsWith(fileName, ts.Extension.Json); + } + export function isJSMap(fileName: string) { return ts.endsWith(fileName, ".js.map") || ts.endsWith(fileName, ".jsx.map"); } @@ -1822,7 +1826,7 @@ namespace Harness { // .d.ts file, add to declFiles emit this.declFilesCode.push(emittedFile); } - else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) { + else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName) || isJSON(emittedFile.fileName)) { // .js file, add to files this.files.push(emittedFile); } diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js index 6b9ca77370717..6d6498bf0203e 100644 --- a/tests/baselines/reference/requireOfJsonFile.js +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -15,11 +15,11 @@ if (x) { "b": "hello" } -//// [b.js] +//// [b.json] { "a": true, "b": "hello" -}; +} //// [file1.js] "use strict"; exports.__esModule = true; diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts index 7295dac0179cf..d214bcda45009 100644 --- a/tests/cases/compiler/requireOfJsonFile.ts +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -1,4 +1,5 @@ // @module: commonjs +// @outdir: out/ // @Filename: file1.ts import b1 = require('./b'); From a1922fd41fb0e48a5fc7df91068d29e7f51d481d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Jan 2017 13:51:00 -0800 Subject: [PATCH 05/17] More tests and also do not add index signature for json module --- src/compiler/checker.ts | 2 +- src/compiler/parser.ts | 4 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 4 ++ .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../reference/requireOfJsonFile.types | 12 +++--- .../requireOfJsonFileWithAmd.errors.txt | 22 +++++++++++ .../reference/requireOfJsonFileWithAmd.js | 27 ++++++++++++++ .../requireOfJsonFileWithAmd.symbols | 24 ++++++++++++ .../reference/requireOfJsonFileWithAmd.types | 33 +++++++++++++++++ .../requireOfJsonFileWithEmptyObject.js | 25 +++++++++++++ .../requireOfJsonFileWithEmptyObject.symbols | 23 ++++++++++++ .../requireOfJsonFileWithEmptyObject.types | 24 ++++++++++++ ...onFileWithEmptyObjectWithErrors.errors.txt | 23 ++++++++++++ ...uireOfJsonFileWithEmptyObjectWithErrors.js | 27 ++++++++++++++ ...fJsonFileWithEmptyObjectWithErrors.symbols | 28 ++++++++++++++ ...eOfJsonFileWithEmptyObjectWithErrors.types | 37 +++++++++++++++++++ .../requireOfJsonFileWithNoContent.errors.txt | 22 +++++++++++ .../requireOfJsonFileWithNoContent.js | 25 +++++++++++++ .../requireOfJsonFileWithNoContent.symbols | 27 ++++++++++++++ .../requireOfJsonFileWithNoContent.types | 36 ++++++++++++++++++ .../compiler/requireOfJsonFileWithAmd.ts | 17 +++++++++ .../requireOfJsonFileWithEmptyObject.ts | 14 +++++++ ...uireOfJsonFileWithEmptyObjectWithErrors.ts | 15 ++++++++ .../requireOfJsonFileWithNoContent.ts | 13 +++++++ 26 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithAmd.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithAmd.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithAmd.types create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObject.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObject.types create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types create mode 100644 tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithNoContent.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithNoContent.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithNoContent.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithAmd.ts create mode 100644 tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts create mode 100644 tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts create mode 100644 tests/cases/compiler/requireOfJsonFileWithNoContent.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba53d2aa7aaa1..b943135b0062f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14882,7 +14882,7 @@ namespace ts { const contextualType = getApparentTypeOfContextualType(node); const contextualTypeHasPattern = contextualType && contextualType.pattern && (contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression); - const isJSObjectLiteral = !contextualType && isInJavaScriptFile(node); + const isJSObjectLiteral = !contextualType && (isInJavaScriptFile(node) && !isInJsonFile(node)); let typeFlags: TypeFlags = 0; let patternWithComputedProperties = false; let hasComputedStringProperty = false; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9eaab774a1be3..5ce69b1ff4b0b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -747,9 +747,11 @@ namespace ts { switch (scriptKind) { case ScriptKind.JS: case ScriptKind.JSX: - case ScriptKind.JSON: contextFlags = NodeFlags.JavaScriptFile; break; + case ScriptKind.JSON: + contextFlags = NodeFlags.JavaScriptFile | NodeFlags.JsonFile; + break; default: contextFlags = NodeFlags.None; break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d550bf9704fb7..80adbc1fbc073 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -492,6 +492,7 @@ namespace ts { JSDoc = 1 << 20, // If node was parsed inside jsdoc /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. /* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) + JsonFile = 1 << 23, // If node was parsed in a Json BlockScoped = Let | Const, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e0f20cdda7d9d..63a02d8d7b89a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1432,6 +1432,10 @@ namespace ts { return node && !!(node.flags & NodeFlags.JavaScriptFile); } + export function isInJsonFile(node: Node | undefined): boolean { + return node && !!(node.flags & NodeFlags.JsonFile); + } + export function isInJSDoc(node: Node | undefined): boolean { return node && !!(node.flags & NodeFlags.JSDoc); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 29ed483e632b5..1abd2401a0377 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -413,6 +413,7 @@ declare namespace ts { ThisNodeOrAnySubNodesHasError = 131072, HasAggregatedChildData = 262144, JSDoc = 1048576, + JsonFile = 8388608, BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 430cfb9c44434..d766ef8a5e630 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -413,6 +413,7 @@ declare namespace ts { ThisNodeOrAnySubNodesHasError = 131072, HasAggregatedChildData = 262144, JSDoc = 1048576, + JsonFile = 8388608, BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, diff --git a/tests/baselines/reference/requireOfJsonFile.types b/tests/baselines/reference/requireOfJsonFile.types index 40bb6d0f65d28..7911e2eb1ab2d 100644 --- a/tests/baselines/reference/requireOfJsonFile.types +++ b/tests/baselines/reference/requireOfJsonFile.types @@ -1,15 +1,15 @@ === tests/cases/compiler/file1.ts === import b1 = require('./b'); ->b1 : { [x: string]: any; "a": boolean; "b": string; } +>b1 : { "a": boolean; "b": string; } let x = b1.a; >x : boolean >b1.a : boolean ->b1 : { [x: string]: any; "a": boolean; "b": string; } +>b1 : { "a": boolean; "b": string; } >a : boolean import b2 = require('./b.json'); ->b2 : { [x: string]: any; "a": boolean; "b": string; } +>b2 : { "a": boolean; "b": string; } if (x) { >x : boolean @@ -17,7 +17,7 @@ if (x) { let b = b2.b; >b : string >b2.b : string ->b2 : { [x: string]: any; "a": boolean; "b": string; } +>b2 : { "a": boolean; "b": string; } >b : string x = (b1.b === b); @@ -26,14 +26,14 @@ if (x) { >(b1.b === b) : boolean >b1.b === b : boolean >b1.b : string ->b1 : { [x: string]: any; "a": boolean; "b": string; } +>b1 : { "a": boolean; "b": string; } >b : string >b : string } === tests/cases/compiler/b.json === { ->{ "a": true, "b": "hello"} : { [x: string]: any; "a": boolean; "b": string; } +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } "a": true, >"a" : boolean diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt new file mode 100644 index 0000000000000..0a9654750e1dc --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/file1.ts(1,21): error TS2307: Cannot find module './b'. +tests/cases/compiler/file1.ts(3,21): error TS2307: Cannot find module './b.json'. + + +==== tests/cases/compiler/file1.ts (2 errors) ==== + import b1 = require('./b'); + ~~~~~ +!!! error TS2307: Cannot find module './b'. + let x = b1.a; + import b2 = require('./b.json'); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './b.json'. + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (0 errors) ==== + { + "a": true, + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.js b/tests/baselines/reference/requireOfJsonFileWithAmd.js new file mode 100644 index 0000000000000..ebc5a2d42e76b --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/requireOfJsonFileWithAmd.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [file1.js] +define(["require", "exports", "./b", "./b.json"], function (require, exports, b1, b2) { + "use strict"; + exports.__esModule = true; + var x = b1.a; + if (x) { + var b = b2.b; + x = (b1.b === b); + } +}); diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.symbols b/tests/baselines/reference/requireOfJsonFileWithAmd.symbols new file mode 100644 index 0000000000000..1729461ef07bb --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.types b/tests/baselines/reference/requireOfJsonFileWithAmd.types new file mode 100644 index 0000000000000..7984743550dae --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : any + +let x = b1.a; +>x : any +>b1.a : any +>b1 : any +>a : any + +import b2 = require('./b.json'); +>b2 : any + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : any +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : any +>b : any +>b : any +} + diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js new file mode 100644 index 0000000000000..12c912195d4b0 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1; +import b2 = require('./b.json'); +if (x) { + x = b2; +} + +//// [b.json] +{ +} + +//// [b.json] +{} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); +var x = b1; +var b2 = require("./b.json"); +if (x) { + x = b2; +} diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols new file mode 100644 index 0000000000000..4edf64ef72086 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 11)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + x = b2; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 11)) +} + +=== tests/cases/compiler/b.json === +{ +No type information for this code.} +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types new file mode 100644 index 0000000000000..6a8bad1793bb1 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : {} + +let x = b1; +>x : {} +>b1 : {} + +import b2 = require('./b.json'); +>b2 : {} + +if (x) { +>x : {} + + x = b2; +>x = b2 : {} +>x : {} +>b2 : {} +} + +=== tests/cases/compiler/b.json === +{ +>{} : {} +} diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt new file mode 100644 index 0000000000000..258c4dd60b01f --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/file1.ts(2,12): error TS2339: Property 'a' does not exist on type '{}'. +tests/cases/compiler/file1.ts(5,16): error TS2339: Property 'b' does not exist on type '{}'. +tests/cases/compiler/file1.ts(6,13): error TS2339: Property 'b' does not exist on type '{}'. + + +==== tests/cases/compiler/file1.ts (3 errors) ==== + import b1 = require('./b'); + let x = b1.a; + ~ +!!! error TS2339: Property 'a' does not exist on type '{}'. + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + ~ +!!! error TS2339: Property 'b' does not exist on type '{}'. + x = (b1.b === b); + ~ +!!! error TS2339: Property 'b' does not exist on type '{}'. + } + +==== tests/cases/compiler/b.json (0 errors) ==== + { + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js new file mode 100644 index 0000000000000..996f0d4d2db64 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ +} + +//// [b.json] +{} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols new file mode 100644 index 0000000000000..b9edfe487ad8e --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ +No type information for this code.} +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types new file mode 100644 index 0000000000000..510acba9357cd --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : {} + +let x = b1.a; +>x : any +>b1.a : any +>b1 : {} +>a : any + +import b2 = require('./b.json'); +>b2 : {} + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : {} +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : {} +>b : any +>b : any +} + +=== tests/cases/compiler/b.json === +{ +>{} : {} +} diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt b/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt new file mode 100644 index 0000000000000..c1d050bdaad38 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/file1.ts(2,12): error TS2339: Property 'a' does not exist on type '{}'. +tests/cases/compiler/file1.ts(5,16): error TS2339: Property 'b' does not exist on type '{}'. +tests/cases/compiler/file1.ts(6,13): error TS2339: Property 'b' does not exist on type '{}'. + + +==== tests/cases/compiler/file1.ts (3 errors) ==== + import b1 = require('./b'); + let x = b1.a; + ~ +!!! error TS2339: Property 'a' does not exist on type '{}'. + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + ~ +!!! error TS2339: Property 'b' does not exist on type '{}'. + x = (b1.b === b); + ~ +!!! error TS2339: Property 'b' does not exist on type '{}'. + } + +==== tests/cases/compiler/b.json (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.js b/tests/baselines/reference/requireOfJsonFileWithNoContent.js new file mode 100644 index 0000000000000..2deed5a2d43bf --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/requireOfJsonFileWithNoContent.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] + + +//// [b.json] +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols b/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols new file mode 100644 index 0000000000000..6a7a1ebbc51d4 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === + +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.types b/tests/baselines/reference/requireOfJsonFileWithNoContent.types new file mode 100644 index 0000000000000..5ead1cfc83478 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : {} + +let x = b1.a; +>x : any +>b1.a : any +>b1 : {} +>a : any + +import b2 = require('./b.json'); +>b2 : {} + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : {} +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : {} +>b : any +>b : any +} + +=== tests/cases/compiler/b.json === + +No type information for this code. \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithAmd.ts b/tests/cases/compiler/requireOfJsonFileWithAmd.ts new file mode 100644 index 0000000000000..682874fe5c071 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithAmd.ts @@ -0,0 +1,17 @@ +// @module: amd +// @outdir: out/ + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts new file mode 100644 index 0000000000000..4ec163b56e550 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @outdir: out/ + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1; +import b2 = require('./b.json'); +if (x) { + x = b2; +} + +// @Filename: b.json +{ +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts new file mode 100644 index 0000000000000..4e1a21f938ed3 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts @@ -0,0 +1,15 @@ +// @module: commonjs +// @outdir: out/ + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts new file mode 100644 index 0000000000000..c0d94bb269a21 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts @@ -0,0 +1,13 @@ +// @module: commonjs +// @outdir: out/ + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json From ca590d6fed5a066dcf71804147ba8325bc91deb9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 26 Jan 2018 15:14:48 -0800 Subject: [PATCH 06/17] Need allowJs to be true to use the json module resolution --- src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 3 +- src/compiler/core.ts | 25 +++++++++----- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/program.ts | 4 +-- src/harness/fourslash.ts | 3 +- src/services/jsTyping.ts | 4 +-- ...sFileCompilationWithMapFileAsJs.errors.txt | 4 +-- ...hMapFileAsJsWithInlineSourceMap.errors.txt | 4 +-- .../requireOfJsonFileWithoutAllowJs.js | 27 +++++++++++++++ .../requireOfJsonFileWithoutAllowJs.symbols | 24 ++++++++++++++ .../requireOfJsonFileWithoutAllowJs.types | 33 +++++++++++++++++++ tests/cases/compiler/requireOfJsonFile.ts | 1 + .../compiler/requireOfJsonFileWithAmd.ts | 1 + .../requireOfJsonFileWithEmptyObject.ts | 1 + ...uireOfJsonFileWithEmptyObjectWithErrors.ts | 1 + .../requireOfJsonFileWithNoContent.ts | 1 + .../requireOfJsonFileWithoutAllowJs.ts | 17 ++++++++++ 18 files changed, 137 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b943135b0062f..249431aa97dd0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2084,7 +2084,7 @@ namespace ts { } // May be an untyped module. If so, ignore resolutionDiagnostic. - if (resolvedModule && !resolutionExtensionIsTypeScriptOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { + if (resolvedModule && !extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { if (isForAugmentation) { const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 08378374c9b00..a804b00f0b6a0 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2037,7 +2037,8 @@ namespace ts { // Rather than requery this for each file and filespec, we query the supported extensions // once and store it on the expansion context. - const supportedExtensions = getSupportedExtensions(options, extraFileExtensions); + // When computing file names, do not include json files. Use only module resolution or explicit includes for them + const supportedExtensions = getSupportedExtensions(options, extraFileExtensions, /*excludeJson*/ true); // Literal files are always included verbatim. An "include" or "exclude" specification cannot // remove a literal file. diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 00a28dbbbcd77..52358737dcf88 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2674,14 +2674,21 @@ namespace ts { export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray = [Extension.Dts, Extension.Ts, Extension.Tsx]; export const supportedJavascriptExtensions: ReadonlyArray = [Extension.Js, Extension.Jsx]; const allSupportedExtensions: ReadonlyArray = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions]; + let allSupportedExtensionsIncludingJson: ReadonlyArray | undefined; + function getAllSupportedExtensionsIncludingJson() { + return allSupportedExtensionsIncludingJson || (allSupportedExtensionsIncludingJson = [...allSupportedExtensions, Extension.Json]); + } - export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray): ReadonlyArray { + export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray, excludeJson?: boolean): ReadonlyArray { const needAllExtensions = options && options.allowJs; + const useJsonExtension = needAllExtensions && !excludeJson && getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeJs; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { - return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; + return useJsonExtension ? + getAllSupportedExtensionsIncludingJson() : + needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; } return deduplicate( - [...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)], + [...(useJsonExtension ? getAllSupportedExtensionsIncludingJson() : allSupportedExtensions), ...extraFileExtensions.map(e => e.extension)], equateStringsCaseSensitive, compareStringsCaseSensitive ); @@ -2691,6 +2698,10 @@ namespace ts { return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension)); } + export function hasJavaScriptOrJsonFileExtension(fileName: string) { + return hasJavaScriptFileExtension(fileName) || fileExtensionIs(fileName, Extension.Json); + } + export function hasTypeScriptFileExtension(fileName: string) { return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); } @@ -3091,10 +3102,6 @@ namespace ts { return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts; } - export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) { - return extensionIsTypeScript(ext) || ext === Extension.Json; - } - /** * Gets the extension from a path. * Path must have a valid extension. @@ -3112,7 +3119,9 @@ namespace ts { } export function tryGetExtensionFromPath(path: string): Extension | undefined { - return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)); + return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || + find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)) || + (fileExtensionIs(path, Extension.Json) ? Extension.Json : undefined); } // Retrieves any string from the final "." onwards from a base file name. diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 30f310cac10e3..f1d97b684040b 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -890,7 +890,7 @@ namespace ts { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJavaScriptFileExtension(candidate) || fileExtensionIs(candidate, Extension.Json)) { + if (hasJavaScriptOrJsonFileExtension(candidate)) { const extensionless = removeFileExtension(candidate); if (state.traceEnabled) { const extension = candidate.substring(extensionless.length); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b2ea3467916b2..7c7b480deff0a 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1975,7 +1975,7 @@ namespace ts { } const isFromNodeModulesSearch = resolution.isExternalLibraryImport; - const isJsFile = !resolutionExtensionIsTypeScriptOrJson(resolution.extension); + const isJsFile = !extensionIsTypeScript(resolution.extension); const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; const resolvedFileName = resolution.resolvedFileName; @@ -2404,7 +2404,6 @@ namespace ts { switch (extension) { case Extension.Ts: case Extension.Dts: - case Extension.Json: // These are always allowed. return undefined; case Extension.Tsx: @@ -2412,6 +2411,7 @@ namespace ts { case Extension.Jsx: return needJsx() || needAllowJs(); case Extension.Js: + case Extension.Json: return needAllowJs(); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 7fdbbbc964098..1b849f36b3aec 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -511,8 +511,9 @@ namespace FourSlash { } private getAllDiagnostics(): ts.Diagnostic[] { + const options = this.languageService.getProgram().getCompilerOptions(); return ts.flatMap(this.languageServiceAdapterHost.getFilenames(), fileName => - ts.isAnySupportedFileExtension(fileName) ? this.getDiagnostics(fileName) : []); + ts.fileExtensionIsOneOf(fileName, ts.getSupportedExtensions(options)) ? this.getDiagnostics(fileName) : []); } public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) { diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index bd6c2e5cb9f9c..a32be9802c24e 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -98,7 +98,7 @@ namespace ts.JsTyping { // Only infer typings for .js and .jsx files fileNames = mapDefined(fileNames, fileName => { const path = normalizePath(fileName); - if (hasJavaScriptFileExtension(path)) { + if (hasJavaScriptOrJsonFileExtension(path)) { return path; } }); @@ -193,7 +193,7 @@ namespace ts.JsTyping { */ function getTypingNamesFromSourceFileNames(fileNames: string[]) { const fromFileNames = mapDefined(fileNames, j => { - if (!hasJavaScriptFileExtension(j)) return undefined; + if (!hasJavaScriptOrJsonFileExtension(j)) return undefined; const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase())); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); diff --git a/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt b/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt index f9d88bd272751..5e0ff050c12fe 100644 --- a/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt +++ b/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt @@ -1,11 +1,11 @@ error TS5055: Cannot write file 'tests/cases/compiler/b.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. -error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. +error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. !!! error TS5055: Cannot write file 'tests/cases/compiler/b.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. -!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. +!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. ==== tests/cases/compiler/a.ts (0 errors) ==== class c { } diff --git a/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt b/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt index f9d88bd272751..5e0ff050c12fe 100644 --- a/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt +++ b/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt @@ -1,11 +1,11 @@ error TS5055: Cannot write file 'tests/cases/compiler/b.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. -error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. +error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. !!! error TS5055: Cannot write file 'tests/cases/compiler/b.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. -!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. +!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. ==== tests/cases/compiler/a.ts (0 errors) ==== class c { } diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js new file mode 100644 index 0000000000000..ab52cbb14941d --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts] //// + +//// [file1.ts] +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols new file mode 100644 index 0000000000000..1729461ef07bb --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types new file mode 100644 index 0000000000000..7984743550dae --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); +>b1 : any + +let x = b1.a; +>x : any +>b1.a : any +>b1 : any +>a : any + +import b2 = require('./b.json'); +>b2 : any + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : any +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : any +>b : any +>b : any +} + diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts index d214bcda45009..016c079562064 100644 --- a/tests/cases/compiler/requireOfJsonFile.ts +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -1,5 +1,6 @@ // @module: commonjs // @outdir: out/ +// @allowJs: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithAmd.ts b/tests/cases/compiler/requireOfJsonFileWithAmd.ts index 682874fe5c071..d37c9dd4f0e63 100644 --- a/tests/cases/compiler/requireOfJsonFileWithAmd.ts +++ b/tests/cases/compiler/requireOfJsonFileWithAmd.ts @@ -1,5 +1,6 @@ // @module: amd // @outdir: out/ +// @allowJs: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts index 4ec163b56e550..05f1d2d637cf9 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts @@ -1,5 +1,6 @@ // @module: commonjs // @outdir: out/ +// @allowJs: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts index 4e1a21f938ed3..31ab0ea0a7c38 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts @@ -1,5 +1,6 @@ // @module: commonjs // @outdir: out/ +// @allowJs: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts index c0d94bb269a21..4d3c63c6ffa30 100644 --- a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts +++ b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts @@ -1,5 +1,6 @@ // @module: commonjs // @outdir: out/ +// @allowJs: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts new file mode 100644 index 0000000000000..d214bcda45009 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts @@ -0,0 +1,17 @@ +// @module: commonjs +// @outdir: out/ + +// @Filename: file1.ts +import b1 = require('./b'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file From a790a92f7ddf68c3415656855da30bc6aa29899c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 30 Jan 2018 10:53:54 -0800 Subject: [PATCH 07/17] Parse all json values at root --- src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 136 +++++++++-------- src/compiler/parser.ts | 42 ++++-- src/compiler/program.ts | 5 +- src/compiler/types.ts | 131 +++++++++-------- src/compiler/utilities.ts | 7 + src/harness/unittests/tsconfigParsing.ts | 15 +- .../reference/api/tsserverlibrary.d.ts | 19 ++- tests/baselines/reference/api/typescript.d.ts | 19 ++- .../reference/requireOfJsonFileTypes.js | 85 +++++++++++ .../reference/requireOfJsonFileTypes.symbols | 103 +++++++++++++ .../reference/requireOfJsonFileTypes.types | 139 ++++++++++++++++++ .../cases/compiler/requireOfJsonFileTypes.ts | 49 ++++++ 13 files changed, 594 insertions(+), 158 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileTypes.js create mode 100644 tests/baselines/reference/requireOfJsonFileTypes.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileTypes.types create mode 100644 tests/cases/compiler/requireOfJsonFileTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 249431aa97dd0..5772e1a2241b7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4369,7 +4369,7 @@ namespace ts { if (declaration.kind === SyntaxKind.SourceFile) { Debug.assert(isJsonSourceFile(declaration as SourceFile)); const jsonSourceFile = declaration; - return links.type = jsonSourceFile.statements.length ? checkObjectLiteral(jsonSourceFile.statements[0].expression) : emptyObjectType; + return links.type = jsonSourceFile.statements.length ? checkExpression(jsonSourceFile.statements[0].expression) : emptyObjectType; } if (declaration.kind === SyntaxKind.ExportAssignment) { return links.type = checkExpression((declaration).expression); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a804b00f0b6a0..c8e7bf8d19ffe 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -937,9 +937,9 @@ namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): JsonSourceFile { + export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): TsConfigSourceFile { const textOrDiagnostic = tryReadFile(fileName, readFile); - return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] }; + return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] }; } function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | Diagnostic { @@ -957,58 +957,62 @@ namespace ts { return arrayToMap(options, option => option.name); } - let _tsconfigRootOptions: Map; + let _tsconfigRootOptions: TsConfigOnlyOption; function getTsconfigRootOptionsMap() { if (_tsconfigRootOptions === undefined) { - _tsconfigRootOptions = commandLineOptionsToMap([ - { - name: "compilerOptions", - type: "object", - elementOptions: commandLineOptionsToMap(optionDeclarations), - extraKeyDiagnosticMessage: Diagnostics.Unknown_compiler_option_0 - }, - { - name: "typingOptions", - type: "object", - elementOptions: commandLineOptionsToMap(typeAcquisitionDeclarations), - extraKeyDiagnosticMessage: Diagnostics.Unknown_type_acquisition_option_0 - }, - { - name: "typeAcquisition", - type: "object", - elementOptions: commandLineOptionsToMap(typeAcquisitionDeclarations), - extraKeyDiagnosticMessage: Diagnostics.Unknown_type_acquisition_option_0 - }, - { - name: "extends", - type: "string" - }, - { - name: "files", - type: "list", - element: { - name: "files", + _tsconfigRootOptions = { + name: undefined, // should never be needed since this is root + type: "object", + elementOptions: commandLineOptionsToMap([ + { + name: "compilerOptions", + type: "object", + elementOptions: commandLineOptionsToMap(optionDeclarations), + extraKeyDiagnosticMessage: Diagnostics.Unknown_compiler_option_0 + }, + { + name: "typingOptions", + type: "object", + elementOptions: commandLineOptionsToMap(typeAcquisitionDeclarations), + extraKeyDiagnosticMessage: Diagnostics.Unknown_type_acquisition_option_0 + }, + { + name: "typeAcquisition", + type: "object", + elementOptions: commandLineOptionsToMap(typeAcquisitionDeclarations), + extraKeyDiagnosticMessage: Diagnostics.Unknown_type_acquisition_option_0 + }, + { + name: "extends", type: "string" - } - }, - { - name: "include", - type: "list", - element: { + }, + { + name: "files", + type: "list", + element: { + name: "files", + type: "string" + } + }, + { name: "include", - type: "string" - } - }, - { - name: "exclude", - type: "list", - element: { + type: "list", + element: { + name: "include", + type: "string" + } + }, + { name: "exclude", - type: "string" - } - }, - compileOnSaveCommandLineOption - ]); + type: "list", + element: { + name: "exclude", + type: "string" + } + }, + compileOnSaveCommandLineOption + ]) + }; } return _tsconfigRootOptions; } @@ -1054,14 +1058,17 @@ namespace ts { function convertToObjectWorker( sourceFile: JsonSourceFile, errors: Push, - knownRootOptions: Map | undefined, + knownRootOptions: CommandLineOption | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { if (!sourceFile.statements.length) { return {}; } - return convertObjectLiteralExpressionToJson(sourceFile.statements[0].expression, knownRootOptions, - /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined); + return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions); + + function isRootOptionMap(knownOptions: Map | undefined) { + return knownRootOptions && (knownRootOptions as TsConfigOnlyOption).elementOptions === knownOptions; + } function convertObjectLiteralExpressionToJson( node: ObjectLiteralExpression, @@ -1094,7 +1101,7 @@ namespace ts { // Notify key value set, if user asked for it if (jsonConversionNotifier && // Current callbacks are only on known parent option or if we are setting values in the root - (parentOption || knownOptions === knownRootOptions)) { + (parentOption || isRootOptionMap(knownOptions))) { const isValidOptionValue = isCompilerOptionsValue(option, value); if (parentOption) { if (isValidOptionValue) { @@ -1102,7 +1109,7 @@ namespace ts { jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value); } } - else if (knownOptions === knownRootOptions) { + else if (isRootOptionMap(knownOptions)) { if (isValidOptionValue) { // Notify about the valid root key value being set jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer); @@ -1408,12 +1415,12 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine { + export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine { return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions); } /*@internal*/ - export function setConfigFileInOptions(options: CompilerOptions, configFile: JsonSourceFile) { + export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile) { if (configFile) { Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile }); } @@ -1441,7 +1448,7 @@ namespace ts { */ function parseJsonConfigFileContentWorker( json: any, - sourceFile: JsonSourceFile, + sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, @@ -1562,7 +1569,7 @@ namespace ts { */ function parseConfig( json: any, - sourceFile: JsonSourceFile, + sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, configFileName: string, @@ -1639,7 +1646,7 @@ namespace ts { } function parseOwnConfigOfJsonSourceFile( - sourceFile: JsonSourceFile, + sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, configFileName: string | undefined, @@ -1729,7 +1736,7 @@ namespace ts { } function getExtendedConfig( - sourceFile: JsonSourceFile, + sourceFile: TsConfigSourceFile, extendedConfigPath: string, host: ts.ParseConfigHost, basePath: string, @@ -1981,7 +1988,7 @@ namespace ts { host: ParseConfigHost, errors: Push, extraFileExtensions: ReadonlyArray, - jsonSourceFile: JsonSourceFile + jsonSourceFile: TsConfigSourceFile ): ExpandResult { basePath = normalizePath(basePath); let validatedIncludeSpecs: ReadonlyArray, validatedExcludeSpecs: ReadonlyArray; @@ -2083,7 +2090,7 @@ namespace ts { }; } - function validateSpecs(specs: ReadonlyArray, errors: Push, allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string): ReadonlyArray { + function validateSpecs(specs: ReadonlyArray, errors: Push, allowTrailingRecursion: boolean, jsonSourceFile: TsConfigSourceFile, specKey: string): ReadonlyArray { return specs.filter(spec => { const diag = specToDiagnostic(spec, allowTrailingRecursion); if (diag !== undefined) { @@ -2093,8 +2100,9 @@ namespace ts { }); function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic { - if (jsonSourceFile && jsonSourceFile.statements.length) { - for (const property of getPropertyAssignment(jsonSourceFile.statements[0].expression, specKey)) { + const jsonObjectLiteral = getTsConfigObjectLiteralExpression(jsonSourceFile); + if (jsonObjectLiteral) { + for (const property of getPropertyAssignment(jsonObjectLiteral, specKey)) { if (isArrayLiteralExpression(property.initializer)) { for (const element of property.initializer.elements) { if (isStringLiteral(element) && element.text === spec) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5ce69b1ff4b0b..774e9d42578b0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -697,23 +697,43 @@ namespace ts { nextToken(); const pos = getNodePos(); if (token() === SyntaxKind.EndOfFileToken) { + sourceFile.statements = createNodeArray([], pos, pos); sourceFile.endOfFileToken = parseTokenNode(); } - else if (token() === SyntaxKind.OpenBraceToken || - lookAhead(() => token() === SyntaxKind.StringLiteral)) { - const statement = createNode(SyntaxKind.ExpressionStatement) as JsonObjectLiteralExpressionStatement; - statement.expression = parseObjectLiteralExpression(); + else { + const statement = createNode(SyntaxKind.ExpressionStatement) as JsonObjectExpressionStatement; + switch (token()) { + case SyntaxKind.OpenBracketToken: + statement.expression = parseArrayLiteralExpression(); + break; + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: + statement.expression = parseTokenNode(); + break; + case SyntaxKind.MinusToken: + if (lookAhead(() => nextToken() === SyntaxKind.NumericLiteral && nextToken() !== SyntaxKind.ColonToken)) { + statement.expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; + } + else { + statement.expression = parseObjectLiteralExpression(); + } + break; + case SyntaxKind.NumericLiteral: + case SyntaxKind.StringLiteral: + if (lookAhead(() => nextToken() !== SyntaxKind.ColonToken)) { + statement.expression = parseLiteralNode() as StringLiteral | NumericLiteral; + break; + } + // falls through + default: + statement.expression = parseObjectLiteralExpression(); + break; + } finishNode(statement); sourceFile.statements = createNodeArray([statement], pos); sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); } - else { - parseExpected(SyntaxKind.OpenBraceToken); - } - - if (!sourceFile.statements) { - sourceFile.statements = createNodeArray([], pos, pos); - } if (setParentNodes) { fixupParentReferences(sourceFile); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7c7b480deff0a..362aa258bb845 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2333,8 +2333,9 @@ namespace ts { function getCompilerOptionsObjectLiteralSyntax() { if (_compilerOptionsObjectLiteralSyntax === undefined) { _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword - if (options.configFile && options.configFile.statements.length) { - for (const prop of getPropertyAssignment(options.configFile.statements[0].expression, "compilerOptions")) { + const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile); + if (jsonObjectLiteral) { + for (const prop of getPropertyAssignment(jsonObjectLiteral, "compilerOptions")) { if (isObjectLiteralExpression(prop.initializer)) { _compilerOptionsObjectLiteralSyntax = prop.initializer; break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 80adbc1fbc073..4030ae9247a61 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -44,8 +44,8 @@ namespace ts { /* @internal */ export const enum Comparison { - LessThan = -1, - EqualTo = 0, + LessThan = -1, + EqualTo = 0, GreaterThan = 1 } @@ -458,24 +458,24 @@ namespace ts { } export const enum NodeFlags { - None = 0, - Let = 1 << 0, // Variable declaration - Const = 1 << 1, // Variable declaration - NestedNamespace = 1 << 2, // Namespace declaration - Synthesized = 1 << 3, // Node was synthesized during transformation - Namespace = 1 << 4, // Namespace declaration - ExportContext = 1 << 5, // Export context (initialized by binding) - ContainsThis = 1 << 6, // Interface contains references to "this" - HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) - HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) + None = 0, + Let = 1 << 0, // Variable declaration + Const = 1 << 1, // Variable declaration + NestedNamespace = 1 << 2, // Namespace declaration + Synthesized = 1 << 3, // Node was synthesized during transformation + Namespace = 1 << 4, // Namespace declaration + ExportContext = 1 << 5, // Export context (initialized by binding) + ContainsThis = 1 << 6, // Interface contains references to "this" + HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) + HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope - HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) - DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed - YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator - DecoratorContext = 1 << 13, // If node was parsed as part of a decorator - AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function - ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node - JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript + HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) + DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed + YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator + DecoratorContext = 1 << 13, // If node was parsed as part of a decorator + AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function + ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node + JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node @@ -489,8 +489,8 @@ namespace ts { // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. /* @internal */ PossiblyContainsDynamicImport = 1 << 19, - JSDoc = 1 << 20, // If node was parsed inside jsdoc - /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. + JSDoc = 1 << 20, // If node was parsed inside jsdoc + /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. /* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) JsonFile = 1 << 23, // If node was parsed in a Json @@ -507,19 +507,19 @@ namespace ts { } export const enum ModifierFlags { - None = 0, - Export = 1 << 0, // Declarations - Ambient = 1 << 1, // Declarations - Public = 1 << 2, // Property/Method - Private = 1 << 3, // Property/Method - Protected = 1 << 4, // Property/Method - Static = 1 << 5, // Property/Method - Readonly = 1 << 6, // Property/Method - Abstract = 1 << 7, // Class/Method/ConstructSignature - Async = 1 << 8, // Property/Method/Function - Default = 1 << 9, // Function/Class (export default declaration) - Const = 1 << 11, // Variable declaration - HasComputedFlags = 1 << 29, // Modifier flags have been computed + None = 0, + Export = 1 << 0, // Declarations + Ambient = 1 << 1, // Declarations + Public = 1 << 2, // Property/Method + Private = 1 << 3, // Property/Method + Protected = 1 << 4, // Property/Method + Static = 1 << 5, // Property/Method + Readonly = 1 << 6, // Property/Method + Abstract = 1 << 7, // Class/Method/ConstructSignature + Async = 1 << 8, // Property/Method/Function + Default = 1 << 9, // Function/Class (export default declaration) + Const = 1 << 11, // Variable declaration + HasComputedFlags = 1 << 29, // Modifier flags have been computed AccessibilityModifier = Public | Private | Protected, // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. @@ -1050,16 +1050,16 @@ namespace ts { export interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NeverKeyword; + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.ThisKeyword + | SyntaxKind.VoidKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.NeverKeyword; } export interface ThisTypeNode extends TypeNode { @@ -2376,19 +2376,19 @@ namespace ts { } export const enum FlowFlags { - Unreachable = 1 << 0, // Unreachable code - Start = 1 << 1, // Start of flow graph - BranchLabel = 1 << 2, // Non-looping junction - LoopLabel = 1 << 3, // Looping junction - Assignment = 1 << 4, // Assignment - TrueCondition = 1 << 5, // Condition known to be true + Unreachable = 1 << 0, // Unreachable code + Start = 1 << 1, // Start of flow graph + BranchLabel = 1 << 2, // Non-looping junction + LoopLabel = 1 << 3, // Looping junction + Assignment = 1 << 4, // Assignment + TrueCondition = 1 << 5, // Condition known to be true FalseCondition = 1 << 6, // Condition known to be false - SwitchClause = 1 << 7, // Switch statement clause - ArrayMutation = 1 << 8, // Potential array mutation - Referenced = 1 << 9, // Referenced as antecedent once - Shared = 1 << 10, // Referenced as antecedent more than once - PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow - AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph + SwitchClause = 1 << 7, // Switch statement clause + ArrayMutation = 1 << 8, // Potential array mutation + Referenced = 1 << 9, // Referenced as antecedent once + Shared = 1 << 10, // Referenced as antecedent more than once + PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow + AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -2577,12 +2577,21 @@ namespace ts { } export interface JsonSourceFile extends SourceFile { - statements: NodeArray; + statements: NodeArray; + } + + export interface TsConfigSourceFile extends JsonSourceFile { extendedSourceFiles?: string[]; } - export interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression; + export interface JsonMinusNumericLiteral extends PrefixUnaryExpression { + kind: SyntaxKind.PrefixUnaryExpression; + operator: SyntaxKind.MinusToken; + operand: NumericLiteral; + } + + export interface JsonObjectExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; } export interface ScriptReferenceHost { @@ -4042,7 +4051,7 @@ namespace ts { checkJs?: boolean; /* @internal */ configFilePath?: string; /** configFile is set as non enumerable property so as to avoid checking of json source files */ - /* @internal */ readonly configFile?: JsonSourceFile; + /* @internal */ readonly configFile?: TsConfigSourceFile; declaration?: boolean; emitDeclarationOnly?: boolean; declarationDir?: string; @@ -4120,7 +4129,7 @@ namespace ts { /*@internal*/ watch?: boolean; esModuleInterop?: boolean; - [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; + [option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined; } export interface TypeAcquisition { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 63a02d8d7b89a..084258d539296 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1040,6 +1040,13 @@ namespace ts { }); } + export function getTsConfigObjectLiteralExpression(tsConfigSourceFile: TsConfigSourceFile) { + if (tsConfigSourceFile && tsConfigSourceFile.statements.length) { + const expression = tsConfigSourceFile.statements[0].expression; + return isObjectLiteralExpression(expression) && expression; + } + } + export function getContainingFunction(node: Node): FunctionLike { return findAncestor(node.parent, isFunctionLike); } diff --git a/src/harness/unittests/tsconfigParsing.ts b/src/harness/unittests/tsconfigParsing.ts index 8d56360bba50b..54e5d5a164740 100644 --- a/src/harness/unittests/tsconfigParsing.ts +++ b/src/harness/unittests/tsconfigParsing.ts @@ -8,12 +8,6 @@ namespace ts { assert.equal(JSON.stringify(parsed), JSON.stringify(expectedConfigObject)); } - function assertParseError(jsonText: string) { - const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); - assert.deepEqual(parsed.config, {}); - assert.isTrue(undefined !== parsed.error); - } - function assertParseErrorWithExcludesKeyword(jsonText: string) { { const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); @@ -134,7 +128,14 @@ namespace ts { }); it("returns object with error when json is invalid", () => { - assertParseError("invalid"); + const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", "invalid"); + assert.deepEqual(parsed.config, { invalid: undefined }); + const expected = ts.createCompilerDiagnostic(ts.Diagnostics._0_expected, "{"); + assert.equal(parsed.error.messageText, expected.messageText); + assert.equal(parsed.error.category, expected.category); + assert.equal(parsed.error.code, expected.code); + assert.equal(parsed.error.start, 0); + assert.equal(parsed.error.length, "invalid".length); }); it("returns object when users correctly specify library", () => { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1abd2401a0377..1c2bbee3a11c3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1632,11 +1632,18 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - statements: NodeArray; + statements: NodeArray; + } + interface TsConfigSourceFile extends JsonSourceFile { extendedSourceFiles?: string[]; } - interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression; + interface JsonMinusNumericLiteral extends PrefixUnaryExpression { + kind: SyntaxKind.PrefixUnaryExpression; + operator: SyntaxKind.MinusToken; + operand: NumericLiteral; + } + interface JsonObjectExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; @@ -2378,7 +2385,7 @@ declare namespace ts { /** Paths used to compute primary types search locations */ typeRoots?: string[]; esModuleInterop?: boolean; - [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; + [option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined; } interface TypeAcquisition { enableAutoDiscovery?: boolean; @@ -3365,7 +3372,7 @@ declare namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): JsonSourceFile; + function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): TsConfigSourceFile; /** * Convert the json syntax tree into the json value */ @@ -3385,7 +3392,7 @@ declare namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine; + function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine; function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions; errors: Diagnostic[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d766ef8a5e630..7dffe561824ee 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1632,11 +1632,18 @@ declare namespace ts { sourceFiles: ReadonlyArray; } interface JsonSourceFile extends SourceFile { - statements: NodeArray; + statements: NodeArray; + } + interface TsConfigSourceFile extends JsonSourceFile { extendedSourceFiles?: string[]; } - interface JsonObjectLiteralExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression; + interface JsonMinusNumericLiteral extends PrefixUnaryExpression { + kind: SyntaxKind.PrefixUnaryExpression; + operator: SyntaxKind.MinusToken; + operand: NumericLiteral; + } + interface JsonObjectExpressionStatement extends ExpressionStatement { + expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; @@ -2378,7 +2385,7 @@ declare namespace ts { /** Paths used to compute primary types search locations */ typeRoots?: string[]; esModuleInterop?: boolean; - [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; + [option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined; } interface TypeAcquisition { enableAutoDiscovery?: boolean; @@ -4171,7 +4178,7 @@ declare namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): JsonSourceFile; + function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): TsConfigSourceFile; /** * Convert the json syntax tree into the json value */ @@ -4191,7 +4198,7 @@ declare namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine; + function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray): ParsedCommandLine; function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions; errors: Diagnostic[]; diff --git a/tests/baselines/reference/requireOfJsonFileTypes.js b/tests/baselines/reference/requireOfJsonFileTypes.js new file mode 100644 index 0000000000000..76de6bca9f80f --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileTypes.js @@ -0,0 +1,85 @@ +//// [tests/cases/compiler/requireOfJsonFileTypes.ts] //// + +//// [file1.ts] +import b = require('./b.json'); +import c = require('./c.json'); +import d = require('./d.json'); +import e = require('./e.json'); +import f = require('./f.json'); +import g = require('./g.json'); + +let booleanLiteral: boolean, nullLiteral: null; +let stringLiteral: string; +let numberLiteral: number; + +booleanLiteral = b.a; +stringLiteral = b.b; +nullLiteral = b.c; +booleanLiteral = b.d; +const stringOrNumberOrNull: string | number | null = c[0]; +stringLiteral = d; +numberLiteral = e; +numberLiteral = f[0]; +booleanLiteral = g[0]; + +//// [b.json] +{ + "a": true, + "b": "hello", + "c": null, + "d": false +} + +//// [c.json] +["a", null, "string"] + +//// [d.json] +"dConfig" + +//// [e.json] +-10 + +//// [f.json] +[-10, 30] + +//// [g.json] +[true, false] + +//// [b.json] +{ + "a": true, + "b": "hello", + "c": null, + "d": false +} +//// [c.json] +["a", null, "string"] +//// [d.json] +"dConfig" +//// [e.json] +-10 +//// [f.json] +[-10, 30] +//// [g.json] +[true, false] +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b = require("./b.json"); +var c = require("./c.json"); +var d = require("./d.json"); +var e = require("./e.json"); +var f = require("./f.json"); +var g = require("./g.json"); +var booleanLiteral, nullLiteral; +var stringLiteral; +var numberLiteral; +booleanLiteral = b.a; +stringLiteral = b.b; +nullLiteral = b.c; +booleanLiteral = b.d; +var stringOrNumberOrNull = c[0]; +stringLiteral = d; +numberLiteral = e; +numberLiteral = f[0]; +booleanLiteral = g[0]; diff --git a/tests/baselines/reference/requireOfJsonFileTypes.symbols b/tests/baselines/reference/requireOfJsonFileTypes.symbols new file mode 100644 index 0000000000000..01b0f4a1dcc64 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileTypes.symbols @@ -0,0 +1,103 @@ +=== tests/cases/compiler/file1.ts === +import b = require('./b.json'); +>b : Symbol(b, Decl(file1.ts, 0, 0)) + +import c = require('./c.json'); +>c : Symbol(c, Decl(file1.ts, 0, 31)) + +import d = require('./d.json'); +>d : Symbol(d, Decl(file1.ts, 1, 31)) + +import e = require('./e.json'); +>e : Symbol(e, Decl(file1.ts, 2, 31)) + +import f = require('./f.json'); +>f : Symbol(f, Decl(file1.ts, 3, 31)) + +import g = require('./g.json'); +>g : Symbol(g, Decl(file1.ts, 4, 31)) + +let booleanLiteral: boolean, nullLiteral: null; +>booleanLiteral : Symbol(booleanLiteral, Decl(file1.ts, 7, 3)) +>nullLiteral : Symbol(nullLiteral, Decl(file1.ts, 7, 28)) + +let stringLiteral: string; +>stringLiteral : Symbol(stringLiteral, Decl(file1.ts, 8, 3)) + +let numberLiteral: number; +>numberLiteral : Symbol(numberLiteral, Decl(file1.ts, 9, 3)) + +booleanLiteral = b.a; +>booleanLiteral : Symbol(booleanLiteral, Decl(file1.ts, 7, 3)) +>b.a : Symbol("a", Decl(b.json, 0, 1)) +>b : Symbol(b, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +stringLiteral = b.b; +>stringLiteral : Symbol(stringLiteral, Decl(file1.ts, 8, 3)) +>b.b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) + +nullLiteral = b.c; +>nullLiteral : Symbol(nullLiteral, Decl(file1.ts, 7, 28)) +>b.c : Symbol("c", Decl(b.json, 2, 17)) +>b : Symbol(b, Decl(file1.ts, 0, 0)) +>c : Symbol("c", Decl(b.json, 2, 17)) + +booleanLiteral = b.d; +>booleanLiteral : Symbol(booleanLiteral, Decl(file1.ts, 7, 3)) +>b.d : Symbol("d", Decl(b.json, 3, 14)) +>b : Symbol(b, Decl(file1.ts, 0, 0)) +>d : Symbol("d", Decl(b.json, 3, 14)) + +const stringOrNumberOrNull: string | number | null = c[0]; +>stringOrNumberOrNull : Symbol(stringOrNumberOrNull, Decl(file1.ts, 15, 5)) +>c : Symbol(c, Decl(file1.ts, 0, 31)) + +stringLiteral = d; +>stringLiteral : Symbol(stringLiteral, Decl(file1.ts, 8, 3)) +>d : Symbol(d, Decl(file1.ts, 1, 31)) + +numberLiteral = e; +>numberLiteral : Symbol(numberLiteral, Decl(file1.ts, 9, 3)) +>e : Symbol(e, Decl(file1.ts, 2, 31)) + +numberLiteral = f[0]; +>numberLiteral : Symbol(numberLiteral, Decl(file1.ts, 9, 3)) +>f : Symbol(f, Decl(file1.ts, 3, 31)) + +booleanLiteral = g[0]; +>booleanLiteral : Symbol(booleanLiteral, Decl(file1.ts, 7, 3)) +>g : Symbol(g, Decl(file1.ts, 4, 31)) + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello", +>"b" : Symbol("b", Decl(b.json, 1, 14)) + + "c": null, +>"c" : Symbol("c", Decl(b.json, 2, 17)) + + "d": false +>"d" : Symbol("d", Decl(b.json, 3, 14)) +} + +=== tests/cases/compiler/c.json === +["a", null, "string"] +No type information for this code. +No type information for this code.=== tests/cases/compiler/d.json === +"dConfig" +No type information for this code. +No type information for this code.=== tests/cases/compiler/e.json === +-10 +No type information for this code. +No type information for this code.=== tests/cases/compiler/f.json === +[-10, 30] +No type information for this code. +No type information for this code.=== tests/cases/compiler/g.json === +[true, false] +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileTypes.types b/tests/baselines/reference/requireOfJsonFileTypes.types new file mode 100644 index 0000000000000..d9cd38cd58fdd --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileTypes.types @@ -0,0 +1,139 @@ +=== tests/cases/compiler/file1.ts === +import b = require('./b.json'); +>b : { "a": boolean; "b": string; "c": null; "d": boolean; } + +import c = require('./c.json'); +>c : (string | null)[] + +import d = require('./d.json'); +>d : "dConfig" + +import e = require('./e.json'); +>e : -10 + +import f = require('./f.json'); +>f : number[] + +import g = require('./g.json'); +>g : boolean[] + +let booleanLiteral: boolean, nullLiteral: null; +>booleanLiteral : boolean +>nullLiteral : null +>null : null + +let stringLiteral: string; +>stringLiteral : string + +let numberLiteral: number; +>numberLiteral : number + +booleanLiteral = b.a; +>booleanLiteral = b.a : boolean +>booleanLiteral : boolean +>b.a : boolean +>b : { "a": boolean; "b": string; "c": null; "d": boolean; } +>a : boolean + +stringLiteral = b.b; +>stringLiteral = b.b : string +>stringLiteral : string +>b.b : string +>b : { "a": boolean; "b": string; "c": null; "d": boolean; } +>b : string + +nullLiteral = b.c; +>nullLiteral = b.c : null +>nullLiteral : null +>b.c : null +>b : { "a": boolean; "b": string; "c": null; "d": boolean; } +>c : null + +booleanLiteral = b.d; +>booleanLiteral = b.d : boolean +>booleanLiteral : boolean +>b.d : boolean +>b : { "a": boolean; "b": string; "c": null; "d": boolean; } +>d : boolean + +const stringOrNumberOrNull: string | number | null = c[0]; +>stringOrNumberOrNull : string | number | null +>null : null +>c[0] : string | null +>c : (string | null)[] +>0 : 0 + +stringLiteral = d; +>stringLiteral = d : "dConfig" +>stringLiteral : string +>d : "dConfig" + +numberLiteral = e; +>numberLiteral = e : -10 +>numberLiteral : number +>e : -10 + +numberLiteral = f[0]; +>numberLiteral = f[0] : number +>numberLiteral : number +>f[0] : number +>f : number[] +>0 : 0 + +booleanLiteral = g[0]; +>booleanLiteral = g[0] : boolean +>booleanLiteral : boolean +>g[0] : boolean +>g : boolean[] +>0 : 0 + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello", "c": null, "d": false} : { "a": boolean; "b": string; "c": null; "d": boolean; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello", +>"b" : string +>"hello" : "hello" + + "c": null, +>"c" : null +>null : null + + "d": false +>"d" : boolean +>false : false +} + +=== tests/cases/compiler/c.json === +["a", null, "string"] +>["a", null, "string"] : (string | null)[] +>"a" : "a" +>null : null +>"string" : "string" + +=== tests/cases/compiler/d.json === +"dConfig" +>"dConfig" : "dConfig" + +=== tests/cases/compiler/e.json === +-10 +>-10 : -10 +>10 : 10 + +=== tests/cases/compiler/f.json === +[-10, 30] +>[-10, 30] : number[] +>-10 : -10 +>10 : 10 +>30 : 30 + +=== tests/cases/compiler/g.json === +[true, false] +>[true, false] : boolean[] +>true : true +>false : false + diff --git a/tests/cases/compiler/requireOfJsonFileTypes.ts b/tests/cases/compiler/requireOfJsonFileTypes.ts new file mode 100644 index 0000000000000..93637909919db --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileTypes.ts @@ -0,0 +1,49 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true +// @strictNullChecks: true + +// @Filename: file1.ts +import b = require('./b.json'); +import c = require('./c.json'); +import d = require('./d.json'); +import e = require('./e.json'); +import f = require('./f.json'); +import g = require('./g.json'); + +let booleanLiteral: boolean, nullLiteral: null; +let stringLiteral: string; +let numberLiteral: number; + +booleanLiteral = b.a; +stringLiteral = b.b; +nullLiteral = b.c; +booleanLiteral = b.d; +const stringOrNumberOrNull: string | number | null = c[0]; +stringLiteral = d; +numberLiteral = e; +numberLiteral = f[0]; +booleanLiteral = g[0]; + +// @Filename: b.json +{ + "a": true, + "b": "hello", + "c": null, + "d": false +} + +// @Filename: c.json +["a", null, "string"] + +// @Filename: d.json +"dConfig" + +// @Filename: e.json +-10 + +// @Filename: f.json +[-10, 30] + +// @Filename: g.json +[true, false] \ No newline at end of file From 4257c2fa040b0c3787c392d76de52f8dcd868716 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 23 Feb 2018 15:08:18 -0800 Subject: [PATCH 08/17] Resolve the .json file only if module name contains the extension --- src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 3 +- src/compiler/core.ts | 25 +++----- src/compiler/moduleNameResolver.ts | 7 ++- src/compiler/program.ts | 4 +- src/harness/fourslash.ts | 3 +- .../unittests/reuseProgramStructure.ts | 2 - src/services/jsTyping.ts | 4 +- ...sFileCompilationWithMapFileAsJs.errors.txt | 4 +- ...hMapFileAsJsWithInlineSourceMap.errors.txt | 4 +- ...lutionWithExtensions_unexpected.trace.json | 3 - ...utionWithExtensions_unexpected2.trace.json | 2 - .../packageJsonMain_isNonRecursive.trace.json | 4 -- .../baselines/reference/requireOfJsonFile.js | 4 +- .../reference/requireOfJsonFile.symbols | 2 +- .../reference/requireOfJsonFile.types | 2 +- .../reference/requireOfJsonFileNonRelative.js | 33 +++++++++++ .../requireOfJsonFileNonRelative.symbols | 47 +++++++++++++++ .../requireOfJsonFileNonRelative.types | 58 +++++++++++++++++++ ...FileNonRelativeWithoutExtension.errors.txt | 29 ++++++++++ ...reOfJsonFileNonRelativeWithoutExtension.js | 27 +++++++++ ...sonFileNonRelativeWithoutExtension.symbols | 7 +++ ...fJsonFileNonRelativeWithoutExtension.types | 7 +++ ...NonRelativeWithoutExtensionResolvesToTs.js | 23 ++++++++ ...lativeWithoutExtensionResolvesToTs.symbols | 11 ++++ ...RelativeWithoutExtensionResolvesToTs.types | 11 ++++ .../requireOfJsonFileWithEmptyObject.js | 4 +- .../requireOfJsonFileWithEmptyObject.symbols | 2 +- .../requireOfJsonFileWithEmptyObject.types | 2 +- ...onFileWithEmptyObjectWithErrors.errors.txt | 2 +- ...uireOfJsonFileWithEmptyObjectWithErrors.js | 4 +- ...fJsonFileWithEmptyObjectWithErrors.symbols | 2 +- ...eOfJsonFileWithEmptyObjectWithErrors.types | 2 +- .../requireOfJsonFileWithNoContent.errors.txt | 2 +- .../requireOfJsonFileWithNoContent.js | 4 +- .../requireOfJsonFileWithNoContent.symbols | 2 +- .../requireOfJsonFileWithNoContent.types | 2 +- .../requireOfJsonFileWithoutAllowJs.js | 9 ++- .../requireOfJsonFileWithoutAllowJs.symbols | 16 ++++- .../requireOfJsonFileWithoutAllowJs.types | 46 +++++++++------ ...quireOfJsonFileWithoutExtension.errors.txt | 19 ++++++ .../requireOfJsonFileWithoutExtension.js | 32 ++++++++++ .../requireOfJsonFileWithoutExtension.symbols | 34 +++++++++++ .../requireOfJsonFileWithoutExtension.types | 45 ++++++++++++++ ...eOfJsonFileWithoutExtensionResolvesToTs.js | 44 ++++++++++++++ ...onFileWithoutExtensionResolvesToTs.symbols | 44 ++++++++++++++ ...JsonFileWithoutExtensionResolvesToTs.types | 53 +++++++++++++++++ ...mMultipleNodeModulesDirectories.trace.json | 6 -- ...romNodeModulesInParentDirectory.trace.json | 1 - tests/cases/compiler/requireOfJsonFile.ts | 2 +- .../compiler/requireOfJsonFileNonRelative.ts | 24 ++++++++ ...reOfJsonFileNonRelativeWithoutExtension.ts | 25 ++++++++ ...NonRelativeWithoutExtensionResolvesToTs.ts | 16 +++++ .../requireOfJsonFileWithEmptyObject.ts | 2 +- ...uireOfJsonFileWithEmptyObjectWithErrors.ts | 2 +- .../requireOfJsonFileWithNoContent.ts | 2 +- .../requireOfJsonFileWithoutAllowJs.ts | 2 +- .../requireOfJsonFileWithoutExtension.ts | 18 ++++++ ...eOfJsonFileWithoutExtensionResolvesToTs.ts | 27 +++++++++ 59 files changed, 733 insertions(+), 92 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelative.js create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelative.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelative.types create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.types create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.types create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtension.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtension.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtension.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtension.types create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.types create mode 100644 tests/cases/compiler/requireOfJsonFileNonRelative.ts create mode 100644 tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts create mode 100644 tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts create mode 100644 tests/cases/compiler/requireOfJsonFileWithoutExtension.ts create mode 100644 tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5772e1a2241b7..977dcc7a8fc9d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2084,7 +2084,7 @@ namespace ts { } // May be an untyped module. If so, ignore resolutionDiagnostic. - if (resolvedModule && !extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { + if (resolvedModule && !resolutionExtensionIsTypeScriptOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { if (isForAugmentation) { const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c8e7bf8d19ffe..eddf40cc94b8a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2044,8 +2044,7 @@ namespace ts { // Rather than requery this for each file and filespec, we query the supported extensions // once and store it on the expansion context. - // When computing file names, do not include json files. Use only module resolution or explicit includes for them - const supportedExtensions = getSupportedExtensions(options, extraFileExtensions, /*excludeJson*/ true); + const supportedExtensions = getSupportedExtensions(options, extraFileExtensions); // Literal files are always included verbatim. An "include" or "exclude" specification cannot // remove a literal file. diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 52358737dcf88..00a28dbbbcd77 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2674,21 +2674,14 @@ namespace ts { export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray = [Extension.Dts, Extension.Ts, Extension.Tsx]; export const supportedJavascriptExtensions: ReadonlyArray = [Extension.Js, Extension.Jsx]; const allSupportedExtensions: ReadonlyArray = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions]; - let allSupportedExtensionsIncludingJson: ReadonlyArray | undefined; - function getAllSupportedExtensionsIncludingJson() { - return allSupportedExtensionsIncludingJson || (allSupportedExtensionsIncludingJson = [...allSupportedExtensions, Extension.Json]); - } - export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray, excludeJson?: boolean): ReadonlyArray { + export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray): ReadonlyArray { const needAllExtensions = options && options.allowJs; - const useJsonExtension = needAllExtensions && !excludeJson && getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeJs; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { - return useJsonExtension ? - getAllSupportedExtensionsIncludingJson() : - needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; + return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; } return deduplicate( - [...(useJsonExtension ? getAllSupportedExtensionsIncludingJson() : allSupportedExtensions), ...extraFileExtensions.map(e => e.extension)], + [...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)], equateStringsCaseSensitive, compareStringsCaseSensitive ); @@ -2698,10 +2691,6 @@ namespace ts { return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension)); } - export function hasJavaScriptOrJsonFileExtension(fileName: string) { - return hasJavaScriptFileExtension(fileName) || fileExtensionIs(fileName, Extension.Json); - } - export function hasTypeScriptFileExtension(fileName: string) { return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); } @@ -3102,6 +3091,10 @@ namespace ts { return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts; } + export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) { + return extensionIsTypeScript(ext) || ext === Extension.Json; + } + /** * Gets the extension from a path. * Path must have a valid extension. @@ -3119,9 +3112,7 @@ namespace ts { } export function tryGetExtensionFromPath(path: string): Extension | undefined { - return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || - find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)) || - (fileExtensionIs(path, Extension.Json) ? Extension.Json : undefined); + return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)); } // Retrieves any string from the final "." onwards from a base file name. diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index f1d97b684040b..7f2578e16df84 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -882,6 +882,11 @@ namespace ts { * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { + if (extensions === Extensions.Json) { + const extensionLess = tryRemoveExtension(candidate, Extension.Json); + return extensionLess && tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state); + } + // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { @@ -890,7 +895,7 @@ namespace ts { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJavaScriptOrJsonFileExtension(candidate)) { + if (hasJavaScriptFileExtension(candidate)) { const extensionless = removeFileExtension(candidate); if (state.traceEnabled) { const extension = candidate.substring(extensionless.length); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 362aa258bb845..d5664e98fce43 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1975,7 +1975,7 @@ namespace ts { } const isFromNodeModulesSearch = resolution.isExternalLibraryImport; - const isJsFile = !extensionIsTypeScript(resolution.extension); + const isJsFile = !resolutionExtensionIsTypeScriptOrJson(resolution.extension); const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; const resolvedFileName = resolution.resolvedFileName; @@ -2405,6 +2405,7 @@ namespace ts { switch (extension) { case Extension.Ts: case Extension.Dts: + case Extension.Json: // These are always allowed. return undefined; case Extension.Tsx: @@ -2412,7 +2413,6 @@ namespace ts { case Extension.Jsx: return needJsx() || needAllowJs(); case Extension.Js: - case Extension.Json: return needAllowJs(); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 1b849f36b3aec..7fdbbbc964098 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -511,9 +511,8 @@ namespace FourSlash { } private getAllDiagnostics(): ts.Diagnostic[] { - const options = this.languageService.getProgram().getCompilerOptions(); return ts.flatMap(this.languageServiceAdapterHost.getFilenames(), fileName => - ts.fileExtensionIsOneOf(fileName, ts.getSupportedExtensions(options)) ? this.getDiagnostics(fileName) : []); + ts.isAnySupportedFileExtension(fileName) ? this.getDiagnostics(fileName) : []); } public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) { diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index c43fe2f5528e0..72528e7c71bba 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -473,8 +473,6 @@ namespace ts { "File 'node_modules/a/index.jsx' does not exist.", "Loading module 'a' from 'node_modules' folder, target file type 'Json'.", "File 'node_modules/a/package.json' does not exist.", - "File 'node_modules/a.json' does not exist.", - "File 'node_modules/a/index.json' does not exist.", "======== Module name 'a' was not resolved. ========" ], "initialProgram: execute module resolution normally."); diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index a32be9802c24e..bd6c2e5cb9f9c 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -98,7 +98,7 @@ namespace ts.JsTyping { // Only infer typings for .js and .jsx files fileNames = mapDefined(fileNames, fileName => { const path = normalizePath(fileName); - if (hasJavaScriptOrJsonFileExtension(path)) { + if (hasJavaScriptFileExtension(path)) { return path; } }); @@ -193,7 +193,7 @@ namespace ts.JsTyping { */ function getTypingNamesFromSourceFileNames(fileNames: string[]) { const fromFileNames = mapDefined(fileNames, j => { - if (!hasJavaScriptOrJsonFileExtension(j)) return undefined; + if (!hasJavaScriptFileExtension(j)) return undefined; const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase())); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); diff --git a/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt b/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt index 5e0ff050c12fe..f9d88bd272751 100644 --- a/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt +++ b/tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt @@ -1,11 +1,11 @@ error TS5055: Cannot write file 'tests/cases/compiler/b.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. -error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. +error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. !!! error TS5055: Cannot write file 'tests/cases/compiler/b.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. -!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. +!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. ==== tests/cases/compiler/a.ts (0 errors) ==== class c { } diff --git a/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt b/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt index 5e0ff050c12fe..f9d88bd272751 100644 --- a/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt +++ b/tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt @@ -1,11 +1,11 @@ error TS5055: Cannot write file 'tests/cases/compiler/b.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. -error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. +error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. !!! error TS5055: Cannot write file 'tests/cases/compiler/b.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. -!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'. +!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'. ==== tests/cases/compiler/a.ts (0 errors) ==== class c { } diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index f2cbd45826d1f..b5d62eb0a25a3 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -36,13 +36,10 @@ "'package.json' does not have a 'types' field.", "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", - "File '/node_modules/normalize.css.json' does not exist.", "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", "File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.", "File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.", "Loading module as file / folder, candidate module location '/node_modules/normalize.css/normalize.css', target file type 'Json'.", - "File '/node_modules/normalize.css/normalize.css.json' does not exist.", "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", - "File '/node_modules/normalize.css/index.json' does not exist.", "======== Module name 'normalize.css' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index 3dd0a7861e372..36ef8252cc7f2 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -38,8 +38,6 @@ "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", "Found 'package.json' at '/node_modules/foo/package.json'.", - "File '/node_modules/foo.json' does not exist.", "'package.json' does not have a 'main' field.", - "File '/node_modules/foo/index.json' does not exist.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json index 653f224b43a98..2ee886f24c79e 100644 --- a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -36,12 +36,8 @@ "'package.json' does not have a 'types' field.", "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "Found 'package.json' at '/node_modules/foo/package.json'.", - "File '/node_modules/foo.json' does not exist.", "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", "File '/node_modules/foo/oof' does not exist.", "Loading module as file / folder, candidate module location '/node_modules/foo/oof', target file type 'Json'.", - "File '/node_modules/foo/oof.json' does not exist.", - "File '/node_modules/foo/oof/index.json' does not exist.", - "File '/node_modules/foo/index.json' does not exist.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js index 6d6498bf0203e..ee6cf710045f8 100644 --- a/tests/baselines/reference/requireOfJsonFile.js +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -1,7 +1,7 @@ //// [tests/cases/compiler/requireOfJsonFile.ts] //// //// [file1.ts] -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { @@ -23,7 +23,7 @@ if (x) { //// [file1.js] "use strict"; exports.__esModule = true; -var b1 = require("./b"); +var b1 = require("./b.json"); var x = b1.a; var b2 = require("./b.json"); if (x) { diff --git a/tests/baselines/reference/requireOfJsonFile.symbols b/tests/baselines/reference/requireOfJsonFile.symbols index 803c02e016a5d..a8f82b6b14590 100644 --- a/tests/baselines/reference/requireOfJsonFile.symbols +++ b/tests/baselines/reference/requireOfJsonFile.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFile.types b/tests/baselines/reference/requireOfJsonFile.types index 7911e2eb1ab2d..c718c429408b4 100644 --- a/tests/baselines/reference/requireOfJsonFile.types +++ b/tests/baselines/reference/requireOfJsonFile.types @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : { "a": boolean; "b": string; } let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFileNonRelative.js b/tests/baselines/reference/requireOfJsonFileNonRelative.js new file mode 100644 index 0000000000000..0b78328c70717 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelative.js @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/requireOfJsonFileNonRelative.ts] //// + +//// [file1.ts] +import b1 = require('b.json'); +let x = b1.a; +import b2 = require('c.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [c.json] +{ + "a": true, + "b": "hello" +} + +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("b.json"); +var x = b1.a; +var b2 = require("c.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileNonRelative.symbols b/tests/baselines/reference/requireOfJsonFileNonRelative.symbols new file mode 100644 index 0000000000000..4a38120620494 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelative.symbols @@ -0,0 +1,47 @@ +=== /src/projects/file1.ts === +import b1 = require('b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('c.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(c.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(c.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== /src/projects/node_modules/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} + +=== /src/node_modules/c.json === +{ + "a": true, +>"a" : Symbol("a", Decl(c.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(c.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileNonRelative.types b/tests/baselines/reference/requireOfJsonFileNonRelative.types new file mode 100644 index 0000000000000..8f15e2282d96f --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelative.types @@ -0,0 +1,58 @@ +=== /src/projects/file1.ts === +import b1 = require('b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('c.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== /src/projects/node_modules/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} + +=== /src/node_modules/c.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.errors.txt b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.errors.txt new file mode 100644 index 0000000000000..13660f8b83648 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.errors.txt @@ -0,0 +1,29 @@ +/src/projects/file1.ts(1,20): error TS2307: Cannot find module 'd.json'. +/src/projects/file1.ts(2,20): error TS2307: Cannot find module 'e'. + + +==== /src/projects/file1.ts (2 errors) ==== + import d = require("d.json"); // Should fail + ~~~~~~~~ +!!! error TS2307: Cannot find module 'd.json'. + import e = require("e"); // Should fail + ~~~ +!!! error TS2307: Cannot find module 'e'. + +==== /src/projects/node_modules/b.json (0 errors) ==== + { + "a": true, + "b": "hello" + } + +==== /src/projects/node_modules/e.json (0 errors) ==== + { + "a": true, + "b": "hello" + } + +==== /src/node_modules/c.json (0 errors) ==== + { + "a": true, + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js new file mode 100644 index 0000000000000..c476d43efc179 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts] //// + +//// [file1.ts] +import d = require("d.json"); // Should fail +import e = require("e"); // Should fail + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [e.json] +{ + "a": true, + "b": "hello" +} + +//// [c.json] +{ + "a": true, + "b": "hello" +} + +//// [file1.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.symbols b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.symbols new file mode 100644 index 0000000000000..0eedb44c3dca5 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.symbols @@ -0,0 +1,7 @@ +=== /src/projects/file1.ts === +import d = require("d.json"); // Should fail +>d : Symbol(d, Decl(file1.ts, 0, 0)) + +import e = require("e"); // Should fail +>e : Symbol(e, Decl(file1.ts, 0, 29)) + diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.types b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.types new file mode 100644 index 0000000000000..ec891ba628056 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.types @@ -0,0 +1,7 @@ +=== /src/projects/file1.ts === +import d = require("d.json"); // Should fail +>d : any + +import e = require("e"); // Should fail +>e : any + diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js new file mode 100644 index 0000000000000..b4b8a449b2ea5 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts] //// + +//// [file1.ts] +import f = require("f"); // should work to f.ts +let fnumber: number = f; + +//// [f.json] +{ + "a": true, + "b": "hello" +} + +//// [f.ts] +export = 10; + +//// [f.js] +"use strict"; +module.exports = 10; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var f = require("f"); // should work to f.ts +var fnumber = f; diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.symbols b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.symbols new file mode 100644 index 0000000000000..cf903d2fcfb7c --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.symbols @@ -0,0 +1,11 @@ +=== /src/projects/file1.ts === +import f = require("f"); // should work to f.ts +>f : Symbol(f, Decl(file1.ts, 0, 0)) + +let fnumber: number = f; +>fnumber : Symbol(fnumber, Decl(file1.ts, 1, 3)) +>f : Symbol(f, Decl(file1.ts, 0, 0)) + +=== /src/node_modules/f.ts === +export = 10; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.types b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.types new file mode 100644 index 0000000000000..75c2db9bae9f1 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.types @@ -0,0 +1,11 @@ +=== /src/projects/file1.ts === +import f = require("f"); // should work to f.ts +>f : 10 + +let fnumber: number = f; +>fnumber : number +>f : 10 + +=== /src/node_modules/f.ts === +export = 10; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js index 12c912195d4b0..851a914d30e29 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js @@ -1,7 +1,7 @@ //// [tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts] //// //// [file1.ts] -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1; import b2 = require('./b.json'); if (x) { @@ -17,7 +17,7 @@ if (x) { //// [file1.js] "use strict"; exports.__esModule = true; -var b1 = require("./b"); +var b1 = require("./b.json"); var x = b1; var b2 = require("./b.json"); if (x) { diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols index 4edf64ef72086..84f4cc98c5b41 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) let x = b1; diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types index 6a8bad1793bb1..5cbc36a7e548e 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.types @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : {} let x = b1; diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt index 258c4dd60b01f..0f10e81f8149b 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.errors.txt @@ -4,7 +4,7 @@ tests/cases/compiler/file1.ts(6,13): error TS2339: Property 'b' does not exist o ==== tests/cases/compiler/file1.ts (3 errors) ==== - import b1 = require('./b'); + import b1 = require('./b.json'); let x = b1.a; ~ !!! error TS2339: Property 'a' does not exist on type '{}'. diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js index 996f0d4d2db64..57122096da07c 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js @@ -1,7 +1,7 @@ //// [tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts] //// //// [file1.ts] -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { @@ -18,7 +18,7 @@ if (x) { //// [file1.js] "use strict"; exports.__esModule = true; -var b1 = require("./b"); +var b1 = require("./b.json"); var x = b1.a; var b2 = require("./b.json"); if (x) { diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols index b9edfe487ad8e..819d0c1aabd79 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types index 510acba9357cd..b0eb30cd30778 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.types @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : {} let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt b/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt index c1d050bdaad38..e08b474466c92 100644 --- a/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.errors.txt @@ -4,7 +4,7 @@ tests/cases/compiler/file1.ts(6,13): error TS2339: Property 'b' does not exist o ==== tests/cases/compiler/file1.ts (3 errors) ==== - import b1 = require('./b'); + import b1 = require('./b.json'); let x = b1.a; ~ !!! error TS2339: Property 'a' does not exist on type '{}'. diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.js b/tests/baselines/reference/requireOfJsonFileWithNoContent.js index 2deed5a2d43bf..754e616ae4963 100644 --- a/tests/baselines/reference/requireOfJsonFileWithNoContent.js +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.js @@ -1,7 +1,7 @@ //// [tests/cases/compiler/requireOfJsonFileWithNoContent.ts] //// //// [file1.ts] -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { @@ -16,7 +16,7 @@ if (x) { //// [file1.js] "use strict"; exports.__esModule = true; -var b1 = require("./b"); +var b1 = require("./b.json"); var x = b1.a; var b2 = require("./b.json"); if (x) { diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols b/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols index 6a7a1ebbc51d4..07d1466a57d87 100644 --- a/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.types b/tests/baselines/reference/requireOfJsonFileWithNoContent.types index 5ead1cfc83478..e23845e073ec4 100644 --- a/tests/baselines/reference/requireOfJsonFileWithNoContent.types +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.types @@ -1,5 +1,5 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : {} let x = b1.a; diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js index ab52cbb14941d..eadcd2532f93c 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js @@ -1,7 +1,7 @@ //// [tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts] //// //// [file1.ts] -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { @@ -15,10 +15,15 @@ if (x) { "b": "hello" } +//// [b.json] +{ + "a": true, + "b": "hello" +} //// [file1.js] "use strict"; exports.__esModule = true; -var b1 = require("./b"); +var b1 = require("./b.json"); var x = b1.a; var b2 = require("./b.json"); if (x) { diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols index 1729461ef07bb..a8f82b6b14590 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.symbols @@ -1,10 +1,12 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); +import b1 = require('./b.json'); >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) let x = b1.a; >x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) import b2 = require('./b.json'); >b2 : Symbol(b2, Decl(file1.ts, 1, 13)) @@ -14,11 +16,23 @@ if (x) { let b = b2.b; >b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) >b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) x = (b1.b === b); >x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) >b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) >b : Symbol(b, Decl(file1.ts, 4, 7)) } +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types index 7984743550dae..c718c429408b4 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.types @@ -1,33 +1,45 @@ === tests/cases/compiler/file1.ts === -import b1 = require('./b'); ->b1 : any +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } let x = b1.a; ->x : any ->b1.a : any ->b1 : any ->a : any +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean import b2 = require('./b.json'); ->b2 : any +>b2 : { "a": boolean; "b": string; } if (x) { ->x : any +>x : boolean let b = b2.b; ->b : any ->b2.b : any ->b2 : any ->b : any +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string x = (b1.b === b); >x = (b1.b === b) : boolean ->x : any +>x : boolean >(b1.b === b) : boolean >b1.b === b : boolean ->b1.b : any ->b1 : any ->b : any ->b : any +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string } +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtension.errors.txt b/tests/baselines/reference/requireOfJsonFileWithoutExtension.errors.txt new file mode 100644 index 0000000000000..799b78c26eec8 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtension.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/file1.ts(1,21): error TS2307: Cannot find module './b'. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + import b1 = require('./b'); // This should not resolve + ~~~~~ +!!! error TS2307: Cannot find module './b'. + let x = b1.a; + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (0 errors) ==== + { + "a": true, + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtension.js b/tests/baselines/reference/requireOfJsonFileWithoutExtension.js new file mode 100644 index 0000000000000..4e9bea900b8ea --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtension.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/requireOfJsonFileWithoutExtension.ts] //// + +//// [file1.ts] +import b1 = require('./b'); // This should not resolve +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b"); // This should not resolve +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtension.symbols b/tests/baselines/reference/requireOfJsonFileWithoutExtension.symbols new file mode 100644 index 0000000000000..34125a48dd6d1 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtension.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); // This should not resolve +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtension.types b/tests/baselines/reference/requireOfJsonFileWithoutExtension.types new file mode 100644 index 0000000000000..5c09cd9063d12 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtension.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b'); // This should not resolve +>b1 : any + +let x = b1.a; +>x : any +>b1.a : any +>b1 : any +>a : any + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : any + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : any +>b : any +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js new file mode 100644 index 0000000000000..e6908a72a768d --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts] //// + +//// [file1.ts] +import c1 = require('./c'); // resolves to c.ts +let x2 = c1.a; +import c2 = require('./c.json'); // resolves to c.json +if (x2) { + let b = c2.b; + let x = (c1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [c.json] +{ + "a": true, + "b": "hello" +} + +//// [c.ts] +export = { a: true, b: "hello" }; + +//// [c.js] +"use strict"; +module.exports = { a: true, b: "hello" }; +//// [c.json] +{ + "a": true, + "b": "hello" +} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var c1 = require("./c"); // resolves to c.ts +var x2 = c1.a; +var c2 = require("./c.json"); // resolves to c.json +if (x2) { + var b = c2.b; + var x = (c1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.symbols b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.symbols new file mode 100644 index 0000000000000..fc45f789eac8e --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/file1.ts === +import c1 = require('./c'); // resolves to c.ts +>c1 : Symbol(c1, Decl(file1.ts, 0, 0)) + +let x2 = c1.a; +>x2 : Symbol(x2, Decl(file1.ts, 1, 3)) +>c1.a : Symbol(a, Decl(c.ts, 0, 10)) +>c1 : Symbol(c1, Decl(file1.ts, 0, 0)) +>a : Symbol(a, Decl(c.ts, 0, 10)) + +import c2 = require('./c.json'); // resolves to c.json +>c2 : Symbol(c2, Decl(file1.ts, 1, 14)) + +if (x2) { +>x2 : Symbol(x2, Decl(file1.ts, 1, 3)) + + let b = c2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>c2.b : Symbol("b", Decl(c.json, 1, 14)) +>c2 : Symbol(c2, Decl(file1.ts, 1, 14)) +>b : Symbol("b", Decl(c.json, 1, 14)) + + let x = (c1.b === b); +>x : Symbol(x, Decl(file1.ts, 5, 7)) +>c1.b : Symbol(b, Decl(c.ts, 0, 19)) +>c1 : Symbol(c1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(c.ts, 0, 19)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/c.json === +{ + "a": true, +>"a" : Symbol("a", Decl(c.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(c.json, 1, 14)) +} + +=== tests/cases/compiler/c.ts === +export = { a: true, b: "hello" }; +>a : Symbol(a, Decl(c.ts, 0, 10)) +>b : Symbol(b, Decl(c.ts, 0, 19)) + diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.types b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.types new file mode 100644 index 0000000000000..a2faa9c834e09 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.types @@ -0,0 +1,53 @@ +=== tests/cases/compiler/file1.ts === +import c1 = require('./c'); // resolves to c.ts +>c1 : { a: boolean; b: string; } + +let x2 = c1.a; +>x2 : boolean +>c1.a : boolean +>c1 : { a: boolean; b: string; } +>a : boolean + +import c2 = require('./c.json'); // resolves to c.json +>c2 : { "a": boolean; "b": string; } + +if (x2) { +>x2 : boolean + + let b = c2.b; +>b : string +>c2.b : string +>c2 : { "a": boolean; "b": string; } +>b : string + + let x = (c1.b === b); +>x : boolean +>(c1.b === b) : boolean +>c1.b === b : boolean +>c1.b : string +>c1 : { a: boolean; b: string; } +>b : string +>b : string +} + +=== tests/cases/compiler/c.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} + +=== tests/cases/compiler/c.ts === +export = { a: true, b: "hello" }; +>{ a: true, b: "hello" } : { a: boolean; b: string; } +>a : boolean +>true : true +>b : string +>"hello" : "hello" + diff --git a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json index bee93e5be25c6..277b27adb32f9 100644 --- a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json +++ b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json @@ -19,8 +19,6 @@ "File '/node_modules/xyz.jsx' does not exist.", "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", - "File '/foo/node_modules/xyz.json' does not exist.", - "File '/node_modules/xyz.json' does not exist.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving module 'pdq' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -42,8 +40,6 @@ "File '/node_modules/pdq.jsx' does not exist.", "Loading module 'pdq' from 'node_modules' folder, target file type 'Json'.", "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", - "File '/foo/node_modules/pdq.json' does not exist.", - "File '/node_modules/pdq.json' does not exist.", "======== Module name 'pdq' was not resolved. ========", "======== Resolving module 'abc' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -65,8 +61,6 @@ "File '/node_modules/abc.jsx' does not exist.", "Loading module 'abc' from 'node_modules' folder, target file type 'Json'.", "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", - "File '/foo/node_modules/abc.json' does not exist.", - "File '/node_modules/abc.json' does not exist.", "======== Module name 'abc' was not resolved. ========", "======== Resolving type reference directive 'grumpy', containing file '/foo/bar/__inferred type names__.ts', root directory '/foo/node_modules/@types,/node_modules/@types'. ========", "Resolving with primary search path '/foo/node_modules/@types, /node_modules/@types'.", diff --git a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json index 95fdca59f945e..4a16a8e7afa1d 100644 --- a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json +++ b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json @@ -13,7 +13,6 @@ "File '/node_modules/xyz.jsx' does not exist.", "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", "Directory '/src/node_modules' does not exist, skipping all lookups in it.", - "File '/node_modules/xyz.json' does not exist.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving type reference directive 'foo', containing file '/src/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts index 016c079562064..6c10279aa6f41 100644 --- a/tests/cases/compiler/requireOfJsonFile.ts +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: file1.ts -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { diff --git a/tests/cases/compiler/requireOfJsonFileNonRelative.ts b/tests/cases/compiler/requireOfJsonFileNonRelative.ts new file mode 100644 index 0000000000000..f769f04282a3e --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileNonRelative.ts @@ -0,0 +1,24 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: /src/projects/file1.ts +import b1 = require('b.json'); +let x = b1.a; +import b2 = require('c.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: /src/projects/node_modules/b.json +{ + "a": true, + "b": "hello" +} + +// @Filename: /src/node_modules/c.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts new file mode 100644 index 0000000000000..4e4b4dda6ebf3 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts @@ -0,0 +1,25 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: /src/projects/file1.ts +import d = require("d.json"); // Should fail +import e = require("e"); // Should fail + +// @Filename: /src/projects/node_modules/b.json +{ + "a": true, + "b": "hello" +} + +// @Filename: /src/projects/node_modules/e.json +{ + "a": true, + "b": "hello" +} + +// @Filename: /src/node_modules/c.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts new file mode 100644 index 0000000000000..27126a14545ca --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts @@ -0,0 +1,16 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: /src/projects/file1.ts +import f = require("f"); // should work to f.ts +let fnumber: number = f; + +// @Filename: /src/node_modules/f.json +{ + "a": true, + "b": "hello" +} + +// @Filename: /src/node_modules/f.ts +export = 10; \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts index 05f1d2d637cf9..030ddf16a8b51 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: file1.ts -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1; import b2 = require('./b.json'); if (x) { diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts index 31ab0ea0a7c38..6d8edd2c0cb77 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: file1.ts -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { diff --git a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts index 4d3c63c6ffa30..0f9bbbb28fb64 100644 --- a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts +++ b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: file1.ts -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { diff --git a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts index d214bcda45009..9043be7d44cf9 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts @@ -2,7 +2,7 @@ // @outdir: out/ // @Filename: file1.ts -import b1 = require('./b'); +import b1 = require('./b.json'); let x = b1.a; import b2 = require('./b.json'); if (x) { diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts new file mode 100644 index 0000000000000..7739b1eb7ced7 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts @@ -0,0 +1,18 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: file1.ts +import b1 = require('./b'); // This should not resolve +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts new file mode 100644 index 0000000000000..a3974eaf282ee --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts @@ -0,0 +1,27 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: file1.ts +import c1 = require('./c'); // resolves to c.ts +let x2 = c1.a; +import c2 = require('./c.json'); // resolves to c.json +if (x2) { + let b = c2.b; + let x = (c1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} + +// @Filename: c.json +{ + "a": true, + "b": "hello" +} + +// @Filename: c.ts +export = { a: true, b: "hello" }; \ No newline at end of file From 23a7e2f840eb4656b1abe8066c16e6f846ae3a84 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 23 Feb 2018 18:06:27 -0800 Subject: [PATCH 09/17] Report errors about correctness of the json file --- src/compiler/commandLineParser.ts | 22 +++++---- src/compiler/parser.ts | 1 + .../requireOfJsonFileWithErrors.errors.txt | 19 ++++++++ .../reference/requireOfJsonFileWithErrors.js | 32 +++++++++++++ .../requireOfJsonFileWithErrors.symbols | 38 ++++++++++++++++ .../requireOfJsonFileWithErrors.types | 45 +++++++++++++++++++ .../compiler/requireOfJsonFileWithErrors.ts | 18 ++++++++ 7 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithErrors.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithErrors.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithErrors.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithErrors.ts diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index eddf40cc94b8a..c545cca862823 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1049,19 +1049,21 @@ namespace ts { * Convert the json syntax tree into the json value */ export function convertToObject(sourceFile: JsonSourceFile, errors: Push): any { - return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); + return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); } /** - * Convert the json syntax tree into the json value + * Convert the json syntax tree into the json value and report errors */ - function convertToObjectWorker( + /*@internal*/ + export function convertToObjectWorker( sourceFile: JsonSourceFile, errors: Push, + returnValue: boolean, knownRootOptions: CommandLineOption | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { if (!sourceFile.statements.length) { - return {}; + return returnValue ? {} : undefined; } return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions); @@ -1076,7 +1078,7 @@ namespace ts { extraKeyDiagnosticMessage: DiagnosticMessage | undefined, parentOption: string | undefined ): any { - const result: any = {}; + const result: any = returnValue ? {} : undefined; for (const element of node.properties) { if (element.kind !== SyntaxKind.PropertyAssignment) { errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element, Diagnostics.Property_assignment_expected)); @@ -1097,7 +1099,9 @@ namespace ts { } const value = convertPropertyValueToJson(element.initializer, option); if (typeof keyText !== "undefined") { - result[keyText] = value; + if (returnValue) { + result[keyText] = value; + } // Notify key value set, if user asked for it if (jsonConversionNotifier && // Current callbacks are only on known parent option or if we are setting values in the root @@ -1128,8 +1132,8 @@ namespace ts { function convertArrayLiteralExpressionToJson( elements: NodeArray, elementOption: CommandLineOption | undefined - ): any[] { - return elements.map(element => convertPropertyValueToJson(element, elementOption)); + ): any[] | void { + return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption)); } function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption): any { @@ -1693,7 +1697,7 @@ namespace ts { } } }; - const json = convertToObjectWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator); + const json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator); if (!typeAcquisition) { if (typingOptionstypeAcquisition) { typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ? diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 774e9d42578b0..2cfc36ab9111a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -662,6 +662,7 @@ namespace ts { scriptKind = ensureScriptKind(fileName, scriptKind); if (scriptKind === ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); + convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); result.typeReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; return result; diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt b/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt new file mode 100644 index 0000000000000..bac48b2f2c052 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/b.json(2,5): error TS1327: String literal with double quotes expected. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + import b1 = require('./b.json'); + let x = b1.a; + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (1 errors) ==== + { + 'a': true, + ~~~ +!!! error TS1327: String literal with double quotes expected. + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithErrors.js new file mode 100644 index 0000000000000..9f987ff3d8aaf --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/requireOfJsonFileWithErrors.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + 'a': true, + "b": "hello" +} + +//// [b.json] +{ + 'a': true, + "b": "hello" +} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.symbols b/tests/baselines/reference/requireOfJsonFileWithErrors.symbols new file mode 100644 index 0000000000000..43e877cbed209 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol('a', Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol('a', Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + 'a': true, +>'a' : Symbol('a', Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.types b/tests/baselines/reference/requireOfJsonFileWithErrors.types new file mode 100644 index 0000000000000..35893282bee2f --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { 'a': boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { 'a': boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { 'a': boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { 'a': boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { 'a': boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ 'a': true, "b": "hello"} : { 'a': boolean; "b": string; } + + 'a': true, +>'a' : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/cases/compiler/requireOfJsonFileWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithErrors.ts new file mode 100644 index 0000000000000..ad853e183b5fe --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithErrors.ts @@ -0,0 +1,18 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + 'a': true, + "b": "hello" +} \ No newline at end of file From 4f1640d8e1f3d81975230130600042752a8de0a1 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Sat, 24 Feb 2018 10:15:32 -0800 Subject: [PATCH 10/17] Verify the output file paths for the json module emit --- .../baselines/reference/requireOfJsonFile.js | 4 +- .../reference/requireOfJsonFileNonRelative.js | 2 +- ...reOfJsonFileNonRelativeWithoutExtension.js | 2 +- ...NonRelativeWithoutExtensionResolvesToTs.js | 4 +- .../reference/requireOfJsonFileTypes.js | 14 +++--- .../reference/requireOfJsonFileWithAmd.js | 2 +- .../requireOfJsonFileWithEmptyObject.js | 4 +- ...uireOfJsonFileWithEmptyObjectWithErrors.js | 4 +- .../reference/requireOfJsonFileWithErrors.js | 4 +- .../requireOfJsonFileWithNoContent.js | 4 +- .../requireOfJsonFileWithoutAllowJs.js | 4 +- .../requireOfJsonFileWithoutExtension.js | 4 +- ...eOfJsonFileWithoutExtensionResolvesToTs.js | 6 +-- .../requireOfJsonFileWithoutOutDir.errors.txt | 20 +++++++++ .../requireOfJsonFileWithoutOutDir.js | 27 +++++++++++ .../requireOfJsonFileWithoutOutDir.symbols | 38 ++++++++++++++++ .../requireOfJsonFileWithoutOutDir.types | 45 +++++++++++++++++++ tests/cases/compiler/requireOfJsonFile.ts | 1 + .../compiler/requireOfJsonFileNonRelative.ts | 1 + ...reOfJsonFileNonRelativeWithoutExtension.ts | 1 + ...NonRelativeWithoutExtensionResolvesToTs.ts | 1 + .../cases/compiler/requireOfJsonFileTypes.ts | 1 + .../compiler/requireOfJsonFileWithAmd.ts | 1 + .../requireOfJsonFileWithEmptyObject.ts | 1 + ...uireOfJsonFileWithEmptyObjectWithErrors.ts | 1 + .../compiler/requireOfJsonFileWithErrors.ts | 1 + .../requireOfJsonFileWithNoContent.ts | 1 + .../requireOfJsonFileWithoutAllowJs.ts | 1 + .../requireOfJsonFileWithoutExtension.ts | 1 + ...eOfJsonFileWithoutExtensionResolvesToTs.ts | 1 + .../requireOfJsonFileWithoutOutDir.ts | 17 +++++++ 31 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutOutDir.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutOutDir.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutOutDir.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutOutDir.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts diff --git a/tests/baselines/reference/requireOfJsonFile.js b/tests/baselines/reference/requireOfJsonFile.js index ee6cf710045f8..a93a52b5e3fa6 100644 --- a/tests/baselines/reference/requireOfJsonFile.js +++ b/tests/baselines/reference/requireOfJsonFile.js @@ -15,12 +15,12 @@ if (x) { "b": "hello" } -//// [b.json] +//// [out/b.json] { "a": true, "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileNonRelative.js b/tests/baselines/reference/requireOfJsonFileNonRelative.js index 0b78328c70717..35253e04c9ab7 100644 --- a/tests/baselines/reference/requireOfJsonFileNonRelative.js +++ b/tests/baselines/reference/requireOfJsonFileNonRelative.js @@ -21,7 +21,7 @@ if (x) { "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js index c476d43efc179..7a85dff350116 100644 --- a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtension.js @@ -22,6 +22,6 @@ import e = require("e"); // Should fail "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js index b4b8a449b2ea5..03dd4ab513cf8 100644 --- a/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js +++ b/tests/baselines/reference/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.js @@ -13,10 +13,10 @@ let fnumber: number = f; //// [f.ts] export = 10; -//// [f.js] +//// [out/node_modules/f.js] "use strict"; module.exports = 10; -//// [file1.js] +//// [out/projects/file1.js] "use strict"; exports.__esModule = true; var f = require("f"); // should work to f.ts diff --git a/tests/baselines/reference/requireOfJsonFileTypes.js b/tests/baselines/reference/requireOfJsonFileTypes.js index 76de6bca9f80f..e84f684187a10 100644 --- a/tests/baselines/reference/requireOfJsonFileTypes.js +++ b/tests/baselines/reference/requireOfJsonFileTypes.js @@ -45,24 +45,24 @@ booleanLiteral = g[0]; //// [g.json] [true, false] -//// [b.json] +//// [out/b.json] { "a": true, "b": "hello", "c": null, "d": false } -//// [c.json] +//// [out/c.json] ["a", null, "string"] -//// [d.json] +//// [out/d.json] "dConfig" -//// [e.json] +//// [out/e.json] -10 -//// [f.json] +//// [out/f.json] [-10, 30] -//// [g.json] +//// [out/g.json] [true, false] -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.js b/tests/baselines/reference/requireOfJsonFileWithAmd.js index ebc5a2d42e76b..6e4928174c2d8 100644 --- a/tests/baselines/reference/requireOfJsonFileWithAmd.js +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.js @@ -15,7 +15,7 @@ if (x) { "b": "hello" } -//// [file1.js] +//// [out/file1.js] define(["require", "exports", "./b", "./b.json"], function (require, exports, b1, b2) { "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js index 851a914d30e29..ad6694b525696 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObject.js @@ -12,9 +12,9 @@ if (x) { { } -//// [b.json] +//// [out/b.json] {} -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js index 57122096da07c..ae50a6ea0e580 100644 --- a/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js +++ b/tests/baselines/reference/requireOfJsonFileWithEmptyObjectWithErrors.js @@ -13,9 +13,9 @@ if (x) { { } -//// [b.json] +//// [out/b.json] {} -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithErrors.js b/tests/baselines/reference/requireOfJsonFileWithErrors.js index 9f987ff3d8aaf..a51687c66b017 100644 --- a/tests/baselines/reference/requireOfJsonFileWithErrors.js +++ b/tests/baselines/reference/requireOfJsonFileWithErrors.js @@ -15,12 +15,12 @@ if (x) { "b": "hello" } -//// [b.json] +//// [out/b.json] { 'a': true, "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithNoContent.js b/tests/baselines/reference/requireOfJsonFileWithNoContent.js index 754e616ae4963..4addb7f597c6c 100644 --- a/tests/baselines/reference/requireOfJsonFileWithNoContent.js +++ b/tests/baselines/reference/requireOfJsonFileWithNoContent.js @@ -12,8 +12,8 @@ if (x) { //// [b.json] -//// [b.json] -//// [file1.js] +//// [out/b.json] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js index eadcd2532f93c..0513e2b62086e 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js +++ b/tests/baselines/reference/requireOfJsonFileWithoutAllowJs.js @@ -15,12 +15,12 @@ if (x) { "b": "hello" } -//// [b.json] +//// [out/b.json] { "a": true, "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b.json"); diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtension.js b/tests/baselines/reference/requireOfJsonFileWithoutExtension.js index 4e9bea900b8ea..d3bbce8d371fa 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutExtension.js +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtension.js @@ -15,12 +15,12 @@ if (x) { "b": "hello" } -//// [b.json] +//// [out/b.json] { "a": true, "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var b1 = require("./b"); // This should not resolve diff --git a/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js index e6908a72a768d..438a11834095b 100644 --- a/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js +++ b/tests/baselines/reference/requireOfJsonFileWithoutExtensionResolvesToTs.js @@ -24,15 +24,15 @@ if (x2) { //// [c.ts] export = { a: true, b: "hello" }; -//// [c.js] +//// [out/c.js] "use strict"; module.exports = { a: true, b: "hello" }; -//// [c.json] +//// [out/c.json] { "a": true, "b": "hello" } -//// [file1.js] +//// [out/file1.js] "use strict"; exports.__esModule = true; var c1 = require("./c"); // resolves to c.ts diff --git a/tests/baselines/reference/requireOfJsonFileWithoutOutDir.errors.txt b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.errors.txt new file mode 100644 index 0000000000000..07f0f1b84d76c --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.errors.txt @@ -0,0 +1,20 @@ +error TS5055: Cannot write file 'tests/cases/compiler/b.json' 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. + + +!!! error TS5055: Cannot write file 'tests/cases/compiler/b.json' 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. +==== tests/cases/compiler/file1.ts (0 errors) ==== + import b1 = require('./b.json'); + let x = b1.a; + import b2 = require('./b.json'); + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (0 errors) ==== + { + "a": true, + "b": "hello" + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithoutOutDir.js b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.js new file mode 100644 index 0000000000000..d456f1f8c9f40 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [tests/cases/compiler/file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutOutDir.symbols b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.symbols new file mode 100644 index 0000000000000..a8f82b6b14590 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutOutDir.types b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.types new file mode 100644 index 0000000000000..c718c429408b4 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutOutDir.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts index 6c10279aa6f41..59922a3644783 100644 --- a/tests/cases/compiler/requireOfJsonFile.ts +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileNonRelative.ts b/tests/cases/compiler/requireOfJsonFileNonRelative.ts index f769f04282a3e..8b3d2fd21b0fc 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelative.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelative.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: /src/projects/file1.ts import b1 = require('b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts index 4e4b4dda6ebf3..9e2cff7b3c7bd 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: /src/projects/file1.ts import d = require("d.json"); // Should fail diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts index 27126a14545ca..4e8fd059dff92 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: /src/projects/file1.ts import f = require("f"); // should work to f.ts diff --git a/tests/cases/compiler/requireOfJsonFileTypes.ts b/tests/cases/compiler/requireOfJsonFileTypes.ts index 93637909919db..2f5bdc9dd14d2 100644 --- a/tests/cases/compiler/requireOfJsonFileTypes.ts +++ b/tests/cases/compiler/requireOfJsonFileTypes.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @strictNullChecks: true +// @fullEmitPaths: true // @Filename: file1.ts import b = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithAmd.ts b/tests/cases/compiler/requireOfJsonFileWithAmd.ts index d37c9dd4f0e63..6d6eb20a7b873 100644 --- a/tests/cases/compiler/requireOfJsonFileWithAmd.ts +++ b/tests/cases/compiler/requireOfJsonFileWithAmd.ts @@ -1,6 +1,7 @@ // @module: amd // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts index 030ddf16a8b51..357b55cee5df4 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts index 6d8edd2c0cb77..87278aa721d91 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithErrors.ts index ad853e183b5fe..6148b40563767 100644 --- a/tests/cases/compiler/requireOfJsonFileWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithErrors.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts index 0f9bbbb28fb64..41214ffa1b60f 100644 --- a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts +++ b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts index 9043be7d44cf9..01b61ce533218 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts @@ -1,5 +1,6 @@ // @module: commonjs // @outdir: out/ +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts index 7739b1eb7ced7..a17b9cb1ddddb 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import b1 = require('./b'); // This should not resolve diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts index a3974eaf282ee..65d81fe81eb47 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @allowJs: true +// @fullEmitPaths: true // @Filename: file1.ts import c1 = require('./c'); // resolves to c.ts diff --git a/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts b/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts new file mode 100644 index 0000000000000..bbdb40e0e6376 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts @@ -0,0 +1,17 @@ +// @module: commonjs +// @fullEmitPaths: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file From c154b81986ad32d20ae1d8aaefe5126776c933bf Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 26 Feb 2018 13:52:09 -0800 Subject: [PATCH 11/17] Ensure our readonly emptyArray stays non modified. --- src/compiler/factory.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 92d353aeb0efa..af26ad8337ad8 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -24,14 +24,14 @@ namespace ts { * Make `elements` into a `NodeArray`. If `elements` is `undefined`, returns an empty `NodeArray`. */ export function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray { - if (elements) { + if (!elements || elements === emptyArray) { + elements = []; + } + else { if (isNodeArray(elements)) { return elements; } } - else { - elements = []; - } const array = >elements; array.pos = -1; From a14396320b90db95ce4d2f260f98413211a1d022 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 5 Apr 2018 15:27:44 -0700 Subject: [PATCH 12/17] Resolve json modules only when --resolveJsonModule is specified --- src/compiler/commandLineParser.ts | 6 ++++ src/compiler/diagnosticMessages.json | 9 +++++ src/compiler/moduleNameResolver.ts | 6 +++- src/compiler/program.ts | 6 ++++ src/compiler/types.ts | 1 + .../unittests/reuseProgramStructure.ts | 2 -- .../unittests/tsserverProjectSystem.ts | 4 --- src/server/protocol.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 2 ++ tests/baselines/reference/api/typescript.d.ts | 1 + .../cachedModuleResolution6.trace.json | 7 ---- .../cachedModuleResolution7.trace.json | 5 --- ...portWithTrailingSlash_noResolve.trace.json | 2 -- ...lutionWithExtensions_unexpected.trace.json | 10 ------ ...utionWithExtensions_unexpected2.trace.json | 5 --- .../packageJsonMain_isNonRecursive.trace.json | 8 ----- ...tion_withExtension_failedLookup.trace.json | 8 ----- .../requireOfJsonFileWithAmd.errors.txt | 2 ++ ...sonFileWithoutResolveJsonModule.errors.txt | 19 +++++++++++ ...quireOfJsonFileWithoutResolveJsonModule.js | 24 ++++++++++++++ ...OfJsonFileWithoutResolveJsonModule.symbols | 24 ++++++++++++++ ...reOfJsonFileWithoutResolveJsonModule.types | 33 +++++++++++++++++++ ...mMultipleNodeModulesDirectories.trace.json | 6 ---- ...romNodeModulesInParentDirectory.trace.json | 2 -- tests/cases/compiler/requireOfJsonFile.ts | 1 + .../compiler/requireOfJsonFileNonRelative.ts | 1 + ...reOfJsonFileNonRelativeWithoutExtension.ts | 1 + ...NonRelativeWithoutExtensionResolvesToTs.ts | 1 + .../cases/compiler/requireOfJsonFileTypes.ts | 1 + .../compiler/requireOfJsonFileWithAmd.ts | 1 + .../requireOfJsonFileWithEmptyObject.ts | 1 + ...uireOfJsonFileWithEmptyObjectWithErrors.ts | 1 + .../compiler/requireOfJsonFileWithErrors.ts | 1 + .../requireOfJsonFileWithNoContent.ts | 1 + .../requireOfJsonFileWithoutAllowJs.ts | 1 + .../requireOfJsonFileWithoutExtension.ts | 1 + ...eOfJsonFileWithoutExtensionResolvesToTs.ts | 1 + .../requireOfJsonFileWithoutOutDir.ts | 1 + ...quireOfJsonFileWithoutResolveJsonModule.ts | 16 +++++++++ 39 files changed, 163 insertions(+), 60 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithoutResolveJsonModule.ts diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 70e7f307fb094..f88b43d1304ac 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -506,6 +506,12 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Enable_tracing_of_the_name_resolution_process }, + { + name: "resolveJsonModule", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Resolve_module_name_imported_with_json_extension_to_the_json_source_file + }, { name: "listFiles", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e9bf71dd6eb49..2637d57b14095 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2795,6 +2795,10 @@ "category": "Error", "code": 5069 }, + "Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.": { + "category": "Error", + "code": 5070 + }, "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", @@ -3527,6 +3531,11 @@ "category": "Message", "code": 6194 }, + "Resolve module name imported with '.json' extension to the json source file.": { + "category": "Message", + "code": 6195 + }, + "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 97ccafed8edd9..454c51853e012 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -743,7 +743,11 @@ namespace ts { const failedLookupLocations: string[] = []; const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; - const result = (jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript))) || tryResolve(Extensions.Json); + const result = jsOnly ? + tryResolve(Extensions.JavaScript) : + (tryResolve(Extensions.TypeScript) || + tryResolve(Extensions.JavaScript) || + (compilerOptions.resolveJsonModule ? tryResolve(Extensions.Json) : undefined)); if (result && result.value) { const { resolved, originalPath, isExternalLibraryImport } = result.value; return createResolvedModuleWithFailedLookupLocations(resolved, originalPath, isExternalLibraryImport, failedLookupLocations); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ef30dec8b647e..1294faab91251 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2195,6 +2195,12 @@ namespace ts { } } + if (options.resolveJsonModule) { + if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) { + createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); + } + } + // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted if (options.outDir || // there is --outDir specified diff --git a/src/compiler/types.ts b/src/compiler/types.ts index aed06bc834acd..b174d7d6a6d5d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4220,6 +4220,7 @@ namespace ts { /* @internal */ suppressOutputPathCheck?: boolean; target?: ScriptTarget; traceResolution?: boolean; + resolveJsonModule?: boolean; types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index f25d6573ecbf6..0ba9e6f63518c 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -471,8 +471,6 @@ namespace ts { "File 'node_modules/a.jsx' does not exist.", "File 'node_modules/a/index.js' does not exist.", "File 'node_modules/a/index.jsx' does not exist.", - "Loading module 'a' from 'node_modules' folder, target file type 'Json'.", - "File 'node_modules/a/package.json' does not exist.", "======== Module name 'a' was not resolved. ========" ], "initialProgram: execute module resolution normally."); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index d6dff207ab120..8170c663b1f9d 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3386,10 +3386,6 @@ namespace ts.projectSystem { "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", - "Loading module 'lib' from 'node_modules' folder, target file type 'Json'.", - "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/node_modules' does not exist, skipping all lookups in it.", - "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'lib' was not resolved. ========", `Auto discovery for typings is enabled in project '${proj.getProjectName()}'. Running extra resolution pass for module 'lib' using cache location '/a/cache'.`, "File '/a/cache/node_modules/lib.d.ts' does not exist.", diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 74b6865a3c315..98d10e4e40769 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2716,6 +2716,7 @@ namespace ts.server.protocol { suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget | ts.ScriptTarget; traceResolution?: boolean; + resolveJsonModule?: boolean; types?: string[]; /** Paths used to used to compute primary types search locations */ typeRoots?: string[]; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1504d8f6f3cd8..80a3951796123 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2390,6 +2390,7 @@ declare namespace ts { suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; traceResolution?: boolean; + resolveJsonModule?: boolean; types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; @@ -7239,6 +7240,7 @@ declare namespace ts.server.protocol { suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget | ts.ScriptTarget; traceResolution?: boolean; + resolveJsonModule?: boolean; types?: string[]; /** Paths used to used to compute primary types search locations */ typeRoots?: string[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index dbbd967b971a1..67a07232471e3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2390,6 +2390,7 @@ declare namespace ts { suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; traceResolution?: boolean; + resolveJsonModule?: boolean; types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; diff --git a/tests/baselines/reference/cachedModuleResolution6.trace.json b/tests/baselines/reference/cachedModuleResolution6.trace.json index 197cd0ee0d498..5d43bb94dd278 100644 --- a/tests/baselines/reference/cachedModuleResolution6.trace.json +++ b/tests/baselines/reference/cachedModuleResolution6.trace.json @@ -15,13 +15,6 @@ "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", - "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", - "Directory '/a/b/c/d/e/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/b/c/d/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/b/c/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/node_modules' does not exist, skipping all lookups in it.", - "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========", "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", diff --git a/tests/baselines/reference/cachedModuleResolution7.trace.json b/tests/baselines/reference/cachedModuleResolution7.trace.json index fa54a890ff8a5..49fc1e75b0c7e 100644 --- a/tests/baselines/reference/cachedModuleResolution7.trace.json +++ b/tests/baselines/reference/cachedModuleResolution7.trace.json @@ -11,11 +11,6 @@ "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "Directory '/a/node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", - "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", - "Directory '/a/b/c/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", - "Directory '/a/node_modules' does not exist, skipping all lookups in it.", - "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========", "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", diff --git a/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json b/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json index 0f66680ea4439..1ee467c378905 100644 --- a/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json +++ b/tests/baselines/reference/importWithTrailingSlash_noResolve.trace.json @@ -5,7 +5,5 @@ "Directory '/foo/' does not exist, skipping all lookups in it.", "Loading module as file / folder, candidate module location '/foo/', target file type 'JavaScript'.", "Directory '/foo/' does not exist, skipping all lookups in it.", - "Loading module as file / folder, candidate module location '/foo/', target file type 'Json'.", - "Directory '/foo/' does not exist, skipping all lookups in it.", "======== Module name './foo/' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index b5d62eb0a25a3..5f32a4bf511ef 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -31,15 +31,5 @@ "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", "File '/node_modules/normalize.css/index.js' does not exist.", "File '/node_modules/normalize.css/index.jsx' does not exist.", - "Loading module 'normalize.css' from 'node_modules' folder, target file type 'Json'.", - "'package.json' does not have a 'typings' field.", - "'package.json' does not have a 'types' field.", - "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", - "Found 'package.json' at '/node_modules/normalize.css/package.json'.", - "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", - "File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.", - "File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.", - "Loading module as file / folder, candidate module location '/node_modules/normalize.css/normalize.css', target file type 'Json'.", - "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", "======== Module name 'normalize.css' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index 36ef8252cc7f2..bab6be18d397f 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -34,10 +34,5 @@ "'package.json' does not have a 'main' field.", "File '/node_modules/foo/index.js' does not exist.", "File '/node_modules/foo/index.jsx' does not exist.", - "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", - "'package.json' does not have a 'typings' field.", - "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", - "Found 'package.json' at '/node_modules/foo/package.json'.", - "'package.json' does not have a 'main' field.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json index 2ee886f24c79e..81f5be11a6d76 100644 --- a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -31,13 +31,5 @@ "File '/node_modules/foo/oof/index.jsx' does not exist.", "File '/node_modules/foo/index.js' does not exist.", "File '/node_modules/foo/index.jsx' does not exist.", - "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", - "'package.json' does not have a 'typings' field.", - "'package.json' does not have a 'types' field.", - "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", - "Found 'package.json' at '/node_modules/foo/package.json'.", - "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", - "File '/node_modules/foo/oof' does not exist.", - "Loading module as file / folder, candidate module location '/node_modules/foo/oof', target file type 'Json'.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json index aa3489d9fe1c0..803520f12fd5a 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_failedLookup.trace.json @@ -17,13 +17,5 @@ "Loading module as file / folder, candidate module location '/foo/foo.ts', target file type 'JavaScript'.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", "Directory '/node_modules' does not exist, skipping all lookups in it.", - "'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo'.", - "'paths' option is specified, looking for a pattern to match module name 'foo'.", - "Module name 'foo', matched pattern 'foo'.", - "Trying substitution 'foo/foo.ts', candidate module location: 'foo/foo.ts'.", - "File '/foo/foo.ts' does not exist.", - "Loading module as file / folder, candidate module location '/foo/foo.ts', target file type 'Json'.", - "Loading module 'foo' from 'node_modules' folder, target file type 'Json'.", - "Directory '/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'foo' was not resolved. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt index 0a9654750e1dc..2c43e1d530179 100644 --- a/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithAmd.errors.txt @@ -1,7 +1,9 @@ +error TS5070: Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy. tests/cases/compiler/file1.ts(1,21): error TS2307: Cannot find module './b'. tests/cases/compiler/file1.ts(3,21): error TS2307: Cannot find module './b.json'. +!!! error TS5070: Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy. ==== tests/cases/compiler/file1.ts (2 errors) ==== import b1 = require('./b'); ~~~~~ diff --git a/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.errors.txt b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.errors.txt new file mode 100644 index 0000000000000..7c720cd70ac7d --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/file1.ts(1,21): error TS2307: Cannot find module './b.json'. +tests/cases/compiler/file1.ts(3,21): error TS2307: Cannot find module './b.json'. + + +==== tests/cases/compiler/file1.ts (2 errors) ==== + import b1 = require('./b.json'); // error + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './b.json'. + let x = b1.a; + import b2 = require('./b.json'); // error + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './b.json'. + if (x) { + let b = b2.b; + x = (b1.b === b); + } + +==== tests/cases/compiler/b.json (0 errors) ==== + contents Not read \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.js b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.js new file mode 100644 index 0000000000000..1f01da4df4b30 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/requireOfJsonFileWithoutResolveJsonModule.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); // error +let x = b1.a; +import b2 = require('./b.json'); // error +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +contents Not read + +//// [out/file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); // error +var x = b1.a; +var b2 = require("./b.json"); // error +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.symbols b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.symbols new file mode 100644 index 0000000000000..75de9c447907c --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); // error +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); // error +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + diff --git a/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.types b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.types new file mode 100644 index 0000000000000..b288772663fed --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithoutResolveJsonModule.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); // error +>b1 : any + +let x = b1.a; +>x : any +>b1.a : any +>b1 : any +>a : any + +import b2 = require('./b.json'); // error +>b2 : any + +if (x) { +>x : any + + let b = b2.b; +>b : any +>b2.b : any +>b2 : any +>b : any + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : any +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : any +>b1 : any +>b : any +>b : any +} + diff --git a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json index 277b27adb32f9..fdcbcdb7ab1d0 100644 --- a/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json +++ b/tests/baselines/reference/typeRootsFromMultipleNodeModulesDirectories.trace.json @@ -17,8 +17,6 @@ "File '/foo/node_modules/xyz.jsx' does not exist.", "File '/node_modules/xyz.js' does not exist.", "File '/node_modules/xyz.jsx' does not exist.", - "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", - "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving module 'pdq' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -38,8 +36,6 @@ "File '/foo/node_modules/pdq.jsx' does not exist.", "File '/node_modules/pdq.js' does not exist.", "File '/node_modules/pdq.jsx' does not exist.", - "Loading module 'pdq' from 'node_modules' folder, target file type 'Json'.", - "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'pdq' was not resolved. ========", "======== Resolving module 'abc' from '/foo/bar/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -59,8 +55,6 @@ "File '/foo/node_modules/abc.jsx' does not exist.", "File '/node_modules/abc.js' does not exist.", "File '/node_modules/abc.jsx' does not exist.", - "Loading module 'abc' from 'node_modules' folder, target file type 'Json'.", - "Directory '/foo/bar/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'abc' was not resolved. ========", "======== Resolving type reference directive 'grumpy', containing file '/foo/bar/__inferred type names__.ts', root directory '/foo/node_modules/@types,/node_modules/@types'. ========", "Resolving with primary search path '/foo/node_modules/@types, /node_modules/@types'.", diff --git a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json index 4a16a8e7afa1d..a15e20239c65a 100644 --- a/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json +++ b/tests/baselines/reference/typeRootsFromNodeModulesInParentDirectory.trace.json @@ -11,8 +11,6 @@ "Directory '/src/node_modules' does not exist, skipping all lookups in it.", "File '/node_modules/xyz.js' does not exist.", "File '/node_modules/xyz.jsx' does not exist.", - "Loading module 'xyz' from 'node_modules' folder, target file type 'Json'.", - "Directory '/src/node_modules' does not exist, skipping all lookups in it.", "======== Module name 'xyz' was not resolved. ========", "======== Resolving type reference directive 'foo', containing file '/src/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", diff --git a/tests/cases/compiler/requireOfJsonFile.ts b/tests/cases/compiler/requireOfJsonFile.ts index 59922a3644783..b1e8e3ff25dbc 100644 --- a/tests/cases/compiler/requireOfJsonFile.ts +++ b/tests/cases/compiler/requireOfJsonFile.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileNonRelative.ts b/tests/cases/compiler/requireOfJsonFileNonRelative.ts index 8b3d2fd21b0fc..0cfce0bdb1a0e 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelative.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelative.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: /src/projects/file1.ts import b1 = require('b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts index 9e2cff7b3c7bd..7e1637a40f9d9 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtension.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: /src/projects/file1.ts import d = require("d.json"); // Should fail diff --git a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts index 4e8fd059dff92..4c8181b7a1007 100644 --- a/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts +++ b/tests/cases/compiler/requireOfJsonFileNonRelativeWithoutExtensionResolvesToTs.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: /src/projects/file1.ts import f = require("f"); // should work to f.ts diff --git a/tests/cases/compiler/requireOfJsonFileTypes.ts b/tests/cases/compiler/requireOfJsonFileTypes.ts index 2f5bdc9dd14d2..ce2aed2e824f2 100644 --- a/tests/cases/compiler/requireOfJsonFileTypes.ts +++ b/tests/cases/compiler/requireOfJsonFileTypes.ts @@ -3,6 +3,7 @@ // @allowJs: true // @strictNullChecks: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithAmd.ts b/tests/cases/compiler/requireOfJsonFileWithAmd.ts index 6d6eb20a7b873..3d5f44b61d6bb 100644 --- a/tests/cases/compiler/requireOfJsonFileWithAmd.ts +++ b/tests/cases/compiler/requireOfJsonFileWithAmd.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts index 357b55cee5df4..a098669973fe0 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObject.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts index 87278aa721d91..e28fa58ba86a2 100644 --- a/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithEmptyObjectWithErrors.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithErrors.ts b/tests/cases/compiler/requireOfJsonFileWithErrors.ts index 6148b40563767..e3d830a26d4de 100644 --- a/tests/cases/compiler/requireOfJsonFileWithErrors.ts +++ b/tests/cases/compiler/requireOfJsonFileWithErrors.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts index 41214ffa1b60f..9aed256e0bc0a 100644 --- a/tests/cases/compiler/requireOfJsonFileWithNoContent.ts +++ b/tests/cases/compiler/requireOfJsonFileWithNoContent.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts index 01b61ce533218..c6dc60e9e650f 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts @@ -1,6 +1,7 @@ // @module: commonjs // @outdir: out/ // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts index a17b9cb1ddddb..a000f3404354a 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtension.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b'); // This should not resolve diff --git a/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts index 65d81fe81eb47..30a2c193c239e 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutExtensionResolvesToTs.ts @@ -2,6 +2,7 @@ // @outdir: out/ // @allowJs: true // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import c1 = require('./c'); // resolves to c.ts diff --git a/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts b/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts index bbdb40e0e6376..b25afcba49457 100644 --- a/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts +++ b/tests/cases/compiler/requireOfJsonFileWithoutOutDir.ts @@ -1,5 +1,6 @@ // @module: commonjs // @fullEmitPaths: true +// @resolveJsonModule: true // @Filename: file1.ts import b1 = require('./b.json'); diff --git a/tests/cases/compiler/requireOfJsonFileWithoutResolveJsonModule.ts b/tests/cases/compiler/requireOfJsonFileWithoutResolveJsonModule.ts new file mode 100644 index 0000000000000..76af00dbc7a6d --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithoutResolveJsonModule.ts @@ -0,0 +1,16 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true +// @fullEmitPaths: true + +// @Filename: file1.ts +import b1 = require('./b.json'); // error +let x = b1.a; +import b2 = require('./b.json'); // error +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +contents Not read \ No newline at end of file From 9d3ad545bc03fdac0c6e1414aba0ffbe6f300de0 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 6 Apr 2018 13:37:00 -0700 Subject: [PATCH 13/17] Reverted unintentional formatting changes --- src/compiler/types.ts | 114 +++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b174d7d6a6d5d..e80e71451b7b6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -44,8 +44,8 @@ namespace ts { /* @internal */ export const enum Comparison { - LessThan = -1, - EqualTo = 0, + LessThan = -1, + EqualTo = 0, GreaterThan = 1 } @@ -469,24 +469,24 @@ namespace ts { } export const enum NodeFlags { - None = 0, - Let = 1 << 0, // Variable declaration - Const = 1 << 1, // Variable declaration - NestedNamespace = 1 << 2, // Namespace declaration - Synthesized = 1 << 3, // Node was synthesized during transformation - Namespace = 1 << 4, // Namespace declaration - ExportContext = 1 << 5, // Export context (initialized by binding) - ContainsThis = 1 << 6, // Interface contains references to "this" - HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) - HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) + None = 0, + Let = 1 << 0, // Variable declaration + Const = 1 << 1, // Variable declaration + NestedNamespace = 1 << 2, // Namespace declaration + Synthesized = 1 << 3, // Node was synthesized during transformation + Namespace = 1 << 4, // Namespace declaration + ExportContext = 1 << 5, // Export context (initialized by binding) + ContainsThis = 1 << 6, // Interface contains references to "this" + HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) + HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope - HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) - DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed - YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator - DecoratorContext = 1 << 13, // If node was parsed as part of a decorator - AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function - ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node - JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript + HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) + DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed + YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator + DecoratorContext = 1 << 13, // If node was parsed as part of a decorator + AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function + ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node + JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node @@ -500,10 +500,10 @@ namespace ts { // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. /* @internal */ PossiblyContainsDynamicImport = 1 << 19, - JSDoc = 1 << 20, // If node was parsed inside jsdoc - /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. + JSDoc = 1 << 20, // If node was parsed inside jsdoc + /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. /* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) - JsonFile = 1 << 23, // If node was parsed in a Json + JsonFile = 1 << 23, // If node was parsed in a Json BlockScoped = Let | Const, @@ -518,19 +518,19 @@ namespace ts { } export const enum ModifierFlags { - None = 0, - Export = 1 << 0, // Declarations - Ambient = 1 << 1, // Declarations - Public = 1 << 2, // Property/Method - Private = 1 << 3, // Property/Method - Protected = 1 << 4, // Property/Method - Static = 1 << 5, // Property/Method - Readonly = 1 << 6, // Property/Method - Abstract = 1 << 7, // Class/Method/ConstructSignature - Async = 1 << 8, // Property/Method/Function - Default = 1 << 9, // Function/Class (export default declaration) - Const = 1 << 11, // Variable declaration - HasComputedFlags = 1 << 29, // Modifier flags have been computed + None = 0, + Export = 1 << 0, // Declarations + Ambient = 1 << 1, // Declarations + Public = 1 << 2, // Property/Method + Private = 1 << 3, // Property/Method + Protected = 1 << 4, // Property/Method + Static = 1 << 5, // Property/Method + Readonly = 1 << 6, // Property/Method + Abstract = 1 << 7, // Class/Method/ConstructSignature + Async = 1 << 8, // Property/Method/Function + Default = 1 << 9, // Function/Class (export default declaration) + Const = 1 << 11, // Variable declaration + HasComputedFlags = 1 << 29, // Modifier flags have been computed AccessibilityModifier = Public | Private | Protected, // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. @@ -1057,16 +1057,16 @@ namespace ts { export interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NeverKeyword; + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.ThisKeyword + | SyntaxKind.VoidKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.NeverKeyword; } export interface ImportTypeNode extends NodeWithTypeArguments { @@ -2402,19 +2402,19 @@ namespace ts { } export const enum FlowFlags { - Unreachable = 1 << 0, // Unreachable code - Start = 1 << 1, // Start of flow graph - BranchLabel = 1 << 2, // Non-looping junction - LoopLabel = 1 << 3, // Looping junction - Assignment = 1 << 4, // Assignment - TrueCondition = 1 << 5, // Condition known to be true + Unreachable = 1 << 0, // Unreachable code + Start = 1 << 1, // Start of flow graph + BranchLabel = 1 << 2, // Non-looping junction + LoopLabel = 1 << 3, // Looping junction + Assignment = 1 << 4, // Assignment + TrueCondition = 1 << 5, // Condition known to be true FalseCondition = 1 << 6, // Condition known to be false - SwitchClause = 1 << 7, // Switch statement clause - ArrayMutation = 1 << 8, // Potential array mutation - Referenced = 1 << 9, // Referenced as antecedent once - Shared = 1 << 10, // Referenced as antecedent more than once - PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow - AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph + SwitchClause = 1 << 7, // Switch statement clause + ArrayMutation = 1 << 8, // Potential array mutation + Referenced = 1 << 9, // Referenced as antecedent once + Shared = 1 << 10, // Referenced as antecedent more than once + PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow + AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } From c7b2d9228a34d5162dc8af1d1c99d7086fd393d8 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 30 Apr 2018 11:52:49 -0700 Subject: [PATCH 14/17] PR feedback --- src/compiler/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ed9f5307207aa..b84c8ca004f04 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -702,7 +702,6 @@ namespace ts { initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); - const result = sourceFile as JsonSourceFile; // Prime the scanner. nextToken(); @@ -751,6 +750,7 @@ namespace ts { } sourceFile.parseDiagnostics = parseDiagnostics; + const result = sourceFile as JsonSourceFile; clearState(); return result; } From 97df079feb40d05faa476ead394d256349b6011f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 30 Apr 2018 17:05:22 -0700 Subject: [PATCH 15/17] PR feedback --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f17ecf924a643..5a846cb8d14a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4685,8 +4685,8 @@ namespace ts { return links.type = anyType; } // Handle export default expressions - if (declaration.kind === SyntaxKind.SourceFile) { - Debug.assert(isJsonSourceFile(declaration as SourceFile)); + if (isSourceFile(declaration)) { + Debug.assert(isJsonSourceFile(declaration)); const jsonSourceFile = declaration; return links.type = jsonSourceFile.statements.length ? checkExpression(jsonSourceFile.statements[0].expression) : emptyObjectType; } From 4e6586deb85f34049e97e8d12718bcae070681be Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 4 May 2018 10:45:46 -0700 Subject: [PATCH 16/17] PR feedback --- src/compiler/checker.ts | 3 +-- src/compiler/commandLineParser.ts | 2 ++ src/compiler/program.ts | 2 +- src/compiler/utilities.ts | 20 +++++++------------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c2202f14b55b4..64e2509f9f6d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4719,8 +4719,7 @@ namespace ts { } // Handle export default expressions if (isSourceFile(declaration)) { - Debug.assert(isJsonSourceFile(declaration)); - const jsonSourceFile = declaration; + const jsonSourceFile = cast(declaration, isJsonSourceFile); return links.type = jsonSourceFile.statements.length ? checkExpression(jsonSourceFile.statements[0].expression) : emptyObjectType; } if (declaration.kind === SyntaxKind.ExportAssignment) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 395291750ced0..0f75d445c008d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1076,6 +1076,8 @@ namespace ts { /** * Convert the json syntax tree into the json value and report errors + * This returns the json value (apart from checking errors) only if returnValue provided is true. + * Otherwise it just checks the errors and returns undefined */ /*@internal*/ export function convertToObjectWorker( diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ed436718209cd..4f052581c2028 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2433,7 +2433,7 @@ namespace ts { switch (extension) { case Extension.Ts: case Extension.Dts: - case Extension.Json: + case Extension.Json: // Since module is resolved to json file only when --resolveJsonModule, we dont need further check // These are always allowed. return undefined; case Extension.Tsx: diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f326840afa194..3f7affcc04444 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1076,26 +1076,20 @@ namespace ts { }); } - export function getTsConfigObjectLiteralExpression(tsConfigSourceFile: TsConfigSourceFile) { + export function getTsConfigObjectLiteralExpression(tsConfigSourceFile: TsConfigSourceFile | undefined) { if (tsConfigSourceFile && tsConfigSourceFile.statements.length) { const expression = tsConfigSourceFile.statements[0].expression; return isObjectLiteralExpression(expression) && expression; } } - export function getTsConfigPropArrayElementValue(tsConfigSourceFile: TsConfigSourceFile, propKey: string, elementValue: string): StringLiteral { + export function getTsConfigPropArrayElementValue(tsConfigSourceFile: TsConfigSourceFile | undefined, propKey: string, elementValue: string): StringLiteral | undefined { const jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile); - if (jsonObjectLiteral) { - for (const property of getPropertyAssignment(jsonObjectLiteral, propKey)) { - if (isArrayLiteralExpression(property.initializer)) { - for (const element of property.initializer.elements) { - if (isStringLiteral(element) && element.text === elementValue) { - return element; - } - } - } - } - } + return jsonObjectLiteral && + firstDefined(getPropertyAssignment(jsonObjectLiteral, propKey), property => + isArrayLiteralExpression(property.initializer) ? + find(property.initializer.elements, (element): element is StringLiteral => isStringLiteral(element) && element.text === elementValue) : + undefined); } export function getContainingFunction(node: Node): SignatureDeclaration { From c4143ae0c15acae0015f5aa00e8e2391ef156388 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 4 May 2018 11:14:39 -0700 Subject: [PATCH 17/17] Update the message for resolveJsonModule as per PR feedback --- src/compiler/commandLineParser.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 0f75d445c008d..9710b0c12621e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -505,7 +505,7 @@ namespace ts { name: "resolveJsonModule", type: "boolean", category: Diagnostics.Advanced_Options, - description: Diagnostics.Resolve_module_name_imported_with_json_extension_to_the_json_source_file + description: Diagnostics.Include_modules_imported_with_json_extension }, { name: "listFiles", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index bd2e0055b8027..c12e0a9931b9b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3547,7 +3547,7 @@ "code": 6196, "reportsUnnecessary": true }, - "Resolve module name imported with '.json' extension to the json source file.": { + "Include modules imported with '.json' extension": { "category": "Message", "code": 6197 },