diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 15a3a4e5ef474..402da94f03b18 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2620,6 +2620,10 @@ "category": "Message", "code": 6112 }, + "Conflicting library definitions for '{0}' found at '{1}' and '{2}'. Copy the correct file to a local typings folder to resolve this conflict.": { + "category": "Message", + "code": 6113 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4f8d246911058..9d6e08c6b3c68 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5491,6 +5491,7 @@ namespace ts { function processReferenceComments(sourceFile: SourceFile): void { const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, LanguageVariant.Standard, sourceText); const referencedFiles: FileReference[] = []; + const referencedLibraries: FileReference[] = []; const amdDependencies: { path: string; name: string }[] = []; let amdModuleName: string; @@ -5517,7 +5518,12 @@ namespace ts { sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; const diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { - referencedFiles.push(fileReference); + if (referencePathMatchResult.isLibraryReference) { + referencedLibraries.push(fileReference); + } + else { + referencedFiles.push(fileReference); + } } if (diagnosticMessage) { parseDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); @@ -5549,6 +5555,7 @@ namespace ts { } sourceFile.referencedFiles = referencedFiles; + sourceFile.referencedLibraries = referencedLibraries; sourceFile.amdDependencies = amdDependencies; sourceFile.moduleName = amdModuleName; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b528143384e2f..ff182ee01ea81 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -12,6 +12,13 @@ namespace ts { const emptyArray: any[] = []; + const defaultLibrarySearchPaths = [ + "", + "typings/", + "node_modules/", + "node_modules/@types/", + ]; + export const version = "1.9.0"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string { @@ -371,7 +378,7 @@ namespace ts { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const state = {compilerOptions, host, traceEnabled, skipTsx: false}; + const state = { compilerOptions, host, traceEnabled, skipTsx: false }; let resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, supportedExtensions, state); @@ -407,7 +414,7 @@ namespace ts { } /* @internal */ - export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean } ): boolean { + export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist return !host.directoryExists || host.directoryExists(directoryName); } @@ -554,7 +561,7 @@ namespace ts { return referencedSourceFile - ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations } + ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations } : { resolvedModule: undefined, failedLookupLocations }; } @@ -649,9 +656,9 @@ namespace ts { export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] { let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat( - program.getSyntacticDiagnostics(sourceFile, cancellationToken), - program.getGlobalDiagnostics(cancellationToken), - program.getSemanticDiagnostics(sourceFile, cancellationToken)); + program.getSyntacticDiagnostics(sourceFile, cancellationToken), + program.getGlobalDiagnostics(cancellationToken), + program.getSemanticDiagnostics(sourceFile, cancellationToken)); if (program.getCompilerOptions().declaration) { diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken)); @@ -690,6 +697,9 @@ namespace ts { let program: Program; let files: SourceFile[] = []; let fileProcessingDiagnostics = createDiagnosticCollection(); + const currentDirectory = host.getCurrentDirectory(); + const resolvedLibraries: Map = {}; + const libraryRoot = options.rootDir || options.configFilePath || computeCommonSourceDirectoryOfFilenames(rootNames); const programDiagnostics = createDiagnosticCollection(); let commonSourceDirectory: string; @@ -706,7 +716,6 @@ namespace ts { // Map storing if there is emit blocking diagnostics for given input const hasEmitBlockingDiagnostics = createFileMap(getCanonicalFileName); - const currentDirectory = host.getCurrentDirectory(); const resolveModuleNamesWorker = host.resolveModuleNames ? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile)) : ((moduleNames: string[], containingFile: string) => { @@ -883,8 +892,8 @@ namespace ts { const oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]); const resolutionChanged = oldResolution ? !newResolution || - oldResolution.resolvedFileName !== newResolution.resolvedFileName || - !!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport + oldResolution.resolvedFileName !== newResolution.resolvedFileName || + !!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport : newResolution; if (resolutionChanged) { @@ -1007,9 +1016,9 @@ namespace ts { } function getDiagnosticsHelper( - sourceFile: SourceFile, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[], - cancellationToken: CancellationToken): Diagnostic[] { + sourceFile: SourceFile, + getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[], + cancellationToken: CancellationToken): Diagnostic[] { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } @@ -1484,6 +1493,7 @@ namespace ts { const basePath = getDirectoryPath(fileName); if (!options.noResolve) { processReferencedFiles(file, basePath); + processReferencedLibraries(file, libraryRoot); } // always process imported modules to record module name resolutions @@ -1507,6 +1517,97 @@ namespace ts { }); } + function findLibraryDefinition(searchPath: string) { + let typingFilename = "index.d.ts"; + const packageJsonPath = combinePaths(searchPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + let package: { typings?: string } = {}; + try { + package = JSON.parse(host.readFile(packageJsonPath)); + } + catch (e) { } + + if (package.typings) { + typingFilename = package.typings; + } + } + + const combinedPath = normalizePath(combinePaths(searchPath, typingFilename)); + return host.fileExists(combinedPath) ? combinedPath : undefined; + } + + function processReferencedLibraries(file: SourceFile, compilationRoot: string) { + const primarySearchPaths = map(getEffectiveLibraryPrimarySearchPaths(), path => combinePaths(compilationRoot, path)); + + const failedSearchPaths: string[] = []; + const moduleResolutionState: ModuleResolutionState = { + compilerOptions: options, + host: host, + skipTsx: true, + traceEnabled: false + }; + + for (const ref of file.referencedLibraries) { + // If we already found this library as a primary reference, or failed to find it, nothing to do + const previousResolution = resolvedLibraries[ref.fileName]; + if (previousResolution && (previousResolution.primary || (previousResolution.resolvedFileName === undefined))) { + continue; + } + + let foundIt = false; + + // Check primary library paths + for (const primaryPath of primarySearchPaths) { + const searchPath = combinePaths(primaryPath, ref.fileName); + const resolvedFile = findLibraryDefinition(searchPath); + if (resolvedFile) { + processSourceFile(resolvedFile, /*isDefaultLib*/ false, /*isReference*/ true, file, ref.pos, ref.end); + resolvedLibraries[ref.fileName] = { primary: true, resolvedFileName: resolvedFile }; + foundIt = true; + break; + } + } + + // Check secondary library paths + if (!foundIt) { + const secondaryResult = loadModuleFromNodeModules(ref.fileName, file.fileName, failedSearchPaths, moduleResolutionState); + if (secondaryResult) { + foundIt = true; + // If we already resolved to this file, it must have been a secondary reference. Check file contents + // for sameness and possibly issue an error + if (previousResolution) { + const otherFileText = host.readFile(secondaryResult); + if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) { + fileProcessingDiagnostics.add(createFileDiagnostic(file, ref.pos, ref.end - ref.pos, + Diagnostics.Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_a_local_typings_folder_to_resolve_this_conflict, + ref.fileName, + secondaryResult, + previousResolution.resolvedFileName)); + } + } + else { + // First resolution of this library + processSourceFile(secondaryResult, /*isDefaultLib*/ false, /*isReference*/ true, file, ref.pos, ref.end); + resolvedLibraries[ref.fileName] = { primary: false, resolvedFileName: secondaryResult }; + } + } + } + + if (!foundIt) { + fileProcessingDiagnostics.add(createFileDiagnostic(file, ref.pos, ref.end - ref.pos, Diagnostics.Cannot_find_name_0, ref.fileName)); + // Create an entry as a primary lookup result so we don't keep doing this + resolvedLibraries[ref.fileName] = { primary: true, resolvedFileName: undefined }; + } + } + } + + function getEffectiveLibraryPrimarySearchPaths() { + return options.librarySearchPaths || + (options.configFilePath ? + [options.configFilePath].concat(defaultLibrarySearchPaths) : + defaultLibrarySearchPaths); + } + function getCanonicalFileName(fileName: string): string { return host.getCanonicalFileName(fileName); } @@ -1553,15 +1654,11 @@ namespace ts { return; } - function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string { + function computeCommonSourceDirectoryOfFilenames(fileNames: string[]): string { let commonPathComponents: string[]; - const failed = forEach(files, sourceFile => { + const failed = forEach(fileNames, sourceFile => { // Each file contributes into common source file path - if (isDeclarationFile(sourceFile)) { - return; - } - - const sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory); + const sourcePathComponents = getNormalizedPathComponents(sourceFile, currentDirectory); sourcePathComponents.pop(); // The base file name is not part of the common directory path if (!commonPathComponents) { @@ -1601,6 +1698,16 @@ namespace ts { return getNormalizedPathFromPathComponents(commonPathComponents); } + function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string { + const fileNames: string[] = []; + for (const file of sourceFiles) { + if (!file.isDeclarationFile) { + fileNames.push(file.fileName); + } + } + return computeCommonSourceDirectoryOfFilenames(fileNames); + } + function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean { let allFilesBelongToPath = true; if (sourceFiles) { @@ -1742,7 +1849,7 @@ namespace ts { // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); } } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 24f95ab358f58..38dc5604e9586 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -390,6 +390,7 @@ namespace ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* compilerHost */ undefined); sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped); } + configParseResult.options.configFilePath = configFileName; return configParseResult; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d86bc87ce532b..9e8c44e4d1f90 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1522,6 +1522,7 @@ namespace ts { amdDependencies: AmdDependency[]; moduleName: string; referencedFiles: FileReference[]; + referencedLibraries: FileReference[]; languageVariant: LanguageVariant; isDeclarationFile: boolean; @@ -2395,6 +2396,7 @@ namespace ts { jsx?: JsxEmit; reactNamespace?: string; listFiles?: boolean; + librarySearchPaths?: string[]; locale?: string; mapRoot?: string; module?: ModuleKind; @@ -2444,6 +2446,10 @@ namespace ts { // Do not perform validation of output file name in transpile scenarios /* @internal */ suppressOutputPathCheck?: boolean; + /* @internal */ + // When options come from a config file, its path is recorded here + configFilePath?: string; + [option: string]: string | number | boolean | TsConfigOnlyOptions; } @@ -2714,6 +2720,13 @@ namespace ts { isExternalLibraryImport?: boolean; } + export interface ResolvedLibrary { + // True if the library was found in a primary lookup location + primary: boolean; + // The location of the .d.ts file we located, or undefined if resolution failed + resolvedFileName?: string; + } + export interface ResolvedModuleWithFailedLookupLocations { resolvedModule: ResolvedModule; failedLookupLocations: string[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6b120b745fef2..d83aade9e05f6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6,6 +6,7 @@ namespace ts { fileReference?: FileReference; diagnosticMessage?: DiagnosticMessage; isNoDefaultLib?: boolean; + isLibraryReference?: boolean; } export interface SynthesizedNode extends Node { @@ -498,6 +499,7 @@ namespace ts { } export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + export let fullTripleSlashReferenceLibraryRegEx = /^(\/\/\/\s*/; export let fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; export function isTypeNode(node: Node): boolean { @@ -1536,25 +1538,26 @@ namespace ts { }; } else { - const matchResult = fullTripleSlashReferencePathRegEx.exec(comment); - if (matchResult) { + const refMatchResult = fullTripleSlashReferencePathRegEx.exec(comment); + const refLibResult = !refMatchResult && fullTripleSlashReferenceLibraryRegEx.exec(comment); + if (refMatchResult || refLibResult) { const start = commentRange.pos; const end = commentRange.end; return { fileReference: { pos: start, end: end, - fileName: matchResult[3] + fileName: (refMatchResult || refLibResult)[3] }, - isNoDefaultLib: false - }; - } - else { - return { - diagnosticMessage: Diagnostics.Invalid_reference_directive_syntax, - isNoDefaultLib: false + isNoDefaultLib: false, + isLibraryReference: !!refLibResult }; } + + return { + diagnosticMessage: Diagnostics.Invalid_reference_directive_syntax, + isNoDefaultLib: false + }; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index ddaca6420944f..3c9f8220bb25e 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -817,7 +817,7 @@ namespace Harness { export let fourslashSourceFile: ts.SourceFile; export function getCanonicalFileName(fileName: string): string { - return Harness.IO.useCaseSensitiveFileNames() ? fileName : fileName.toLowerCase(); + return fileName; } export function createCompilerHost( @@ -832,6 +832,8 @@ namespace Harness { // Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); + const harnessNormalizePath = (f: string) => ts.normalizePath(getCanonicalFileName(f)); + const fileMap: ts.FileMap = ts.createFileMap(); for (const file of inputFiles) { if (file.content !== undefined) { @@ -839,6 +841,7 @@ namespace Harness { const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget); const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName); fileMap.set(path, sourceFile); + fileMap.set(harnessNormalizePath(path), sourceFile); } } @@ -867,6 +870,7 @@ namespace Harness { newLineKind === ts.NewLineKind.LineFeed ? lineFeed : Harness.IO.newLine(); + return { getCurrentDirectory: () => currentDirectory, getSourceFile, @@ -875,8 +879,12 @@ namespace Harness { getCanonicalFileName, useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, getNewLine: () => newLine, - fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined, - readFile: (fileName: string): string => { return Harness.IO.readFile(fileName); } + fileExists: fileName => { + return fileMap.contains(harnessNormalizePath(fileName)); + }, + readFile: (fileName: string): string => { + return fileMap.get(harnessNormalizePath(fileName)).getText(); + } }; } diff --git a/src/services/services.ts b/src/services/services.ts index 1c079b84027cd..bef5384ec375f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -792,6 +792,7 @@ namespace ts { public amdDependencies: { name: string; path: string }[]; public moduleName: string; public referencedFiles: FileReference[]; + public referencedLibraries: FileReference[]; public syntacticDiagnostics: Diagnostic[]; public referenceDiagnostics: Diagnostic[]; diff --git a/tests/baselines/reference/library-reference-1.js b/tests/baselines/reference/library-reference-1.js new file mode 100644 index 0000000000000..628790cc3eea5 --- /dev/null +++ b/tests/baselines/reference/library-reference-1.js @@ -0,0 +1,17 @@ +//// [tests/cases/conformance/references/library-reference-1.ts] //// + +//// [index.d.ts] + +// We can find typings in the ./typings folder + +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-1.symbols b/tests/baselines/reference/library-reference-1.symbols new file mode 100644 index 0000000000000..416ec495d5641 --- /dev/null +++ b/tests/baselines/reference/library-reference-1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/references/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 3, 16)) +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + +=== tests/cases/conformance/references/typings/jquery/index.d.ts === + +// We can find typings in the ./typings folder + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + + diff --git a/tests/baselines/reference/library-reference-1.types b/tests/baselines/reference/library-reference-1.types new file mode 100644 index 0000000000000..d2725524d48ec --- /dev/null +++ b/tests/baselines/reference/library-reference-1.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/references/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== tests/cases/conformance/references/typings/jquery/index.d.ts === + +// We can find typings in the ./typings folder + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-2.js b/tests/baselines/reference/library-reference-2.js new file mode 100644 index 0000000000000..f908e94430935 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/references/library-reference-2.ts] //// + +//// [package.json] + +// package.json in a primary reference can refer to another file + +{ + "typings": "jquery.d.ts" +} + +//// [jquery.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-2.symbols b/tests/baselines/reference/library-reference-2.symbols new file mode 100644 index 0000000000000..4743737c4b6f4 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/references/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + +=== tests/cases/conformance/references/typings/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-2.types b/tests/baselines/reference/library-reference-2.types new file mode 100644 index 0000000000000..41167826ce0c7 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/references/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== tests/cases/conformance/references/typings/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-3.js b/tests/baselines/reference/library-reference-3.js new file mode 100644 index 0000000000000..26c5295b7ac3e --- /dev/null +++ b/tests/baselines/reference/library-reference-3.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/references/library-reference-3.ts] //// + +//// [index.d.ts] + +// Secondary references are possible + +declare var $: { foo(): void }; + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-3.symbols b/tests/baselines/reference/library-reference-3.symbols new file mode 100644 index 0000000000000..1e0bc89bbe79e --- /dev/null +++ b/tests/baselines/reference/library-reference-3.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/references/src/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 3, 16)) +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + +=== tests/cases/conformance/references/src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + diff --git a/tests/baselines/reference/library-reference-3.types b/tests/baselines/reference/library-reference-3.types new file mode 100644 index 0000000000000..231dc451c22f4 --- /dev/null +++ b/tests/baselines/reference/library-reference-3.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/references/src/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== tests/cases/conformance/references/src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + diff --git a/tests/baselines/reference/library-reference-4.errors.txt b/tests/baselines/reference/library-reference-4.errors.txt new file mode 100644 index 0000000000000..0090b64afc237 --- /dev/null +++ b/tests/baselines/reference/library-reference-4.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/references/src/root.ts(1,1): error TS2304: Cannot find name 'foo'. +tests/cases/conformance/references/src/root.ts(2,1): error TS2304: Cannot find name 'bar'. + + +==== tests/cases/conformance/references/src/root.ts (2 errors) ==== + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'foo'. + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'bar'. + +==== tests/cases/conformance/references/node_modules/foo/index.d.ts (0 errors) ==== + + // Secondary references may be duplicated if they agree in content + + /// + declare var foo: any; + +==== tests/cases/conformance/references/node_modules/foo/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: any; + +==== tests/cases/conformance/references/node_modules/bar/index.d.ts (0 errors) ==== + /// + declare var bar: any; + +==== tests/cases/conformance/references/node_modules/bar/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: any; + \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-4.js b/tests/baselines/reference/library-reference-4.js new file mode 100644 index 0000000000000..514b3430e8b66 --- /dev/null +++ b/tests/baselines/reference/library-reference-4.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/references/library-reference-4.ts] //// + +//// [index.d.ts] + +// Secondary references may be duplicated if they agree in content + +/// +declare var foo: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [index.d.ts] +/// +declare var bar: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [root.ts] +/// +/// + + +//// [root.js] +/// +/// diff --git a/tests/baselines/reference/library-reference-5.errors.txt b/tests/baselines/reference/library-reference-5.errors.txt new file mode 100644 index 0000000000000..3d1483af9f268 --- /dev/null +++ b/tests/baselines/reference/library-reference-5.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/references/src/root.ts(1,1): error TS2304: Cannot find name 'foo'. +tests/cases/conformance/references/src/root.ts(2,1): error TS2304: Cannot find name 'bar'. + + +==== tests/cases/conformance/references/src/root.ts (2 errors) ==== + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'foo'. + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'bar'. + +==== tests/cases/conformance/references/node_modules/foo/index.d.ts (0 errors) ==== + + // Secondary references may not be duplicated if they disagree in content + + /// + declare var foo: any; + +==== tests/cases/conformance/references/node_modules/foo/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: any; + +==== tests/cases/conformance/references/node_modules/bar/index.d.ts (0 errors) ==== + /// + declare var bar: any; + +==== tests/cases/conformance/references/node_modules/bar/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: {}; + \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-5.js b/tests/baselines/reference/library-reference-5.js new file mode 100644 index 0000000000000..00872041253b8 --- /dev/null +++ b/tests/baselines/reference/library-reference-5.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/references/library-reference-5.ts] //// + +//// [index.d.ts] + +// Secondary references may not be duplicated if they disagree in content + +/// +declare var foo: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [index.d.ts] +/// +declare var bar: any; + +//// [index.d.ts] +declare var alpha: {}; + +//// [root.ts] +/// +/// + + +//// [root.js] +/// +/// diff --git a/tests/cases/conformance/references/library-reference-1.ts b/tests/cases/conformance/references/library-reference-1.ts new file mode 100644 index 0000000000000..76e33ee72cf5d --- /dev/null +++ b/tests/cases/conformance/references/library-reference-1.ts @@ -0,0 +1,11 @@ +// @noImplicitReferences: true + +// We can find typings in the ./typings folder + +// @filename: typings/jquery/index.d.ts +declare var $: { foo(): void }; + + +// @filename: consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-2.ts b/tests/cases/conformance/references/library-reference-2.ts new file mode 100644 index 0000000000000..aa128290ad421 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-2.ts @@ -0,0 +1,16 @@ +// @noImplicitReferences: true + +// package.json in a primary reference can refer to another file + +// @filename: typings/jquery/package.json +{ + "typings": "jquery.d.ts" +} + +// @filename: typings/jquery/jquery.d.ts +declare var $: { foo(): void }; + + +// @filename: consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-3.ts b/tests/cases/conformance/references/library-reference-3.ts new file mode 100644 index 0000000000000..6e1fa61abb374 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-3.ts @@ -0,0 +1,10 @@ +// @noImplicitReferences: true + +// Secondary references are possible + +// @filename: src/node_modules/jquery/index.d.ts +declare var $: { foo(): void }; + +// @filename: src/consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-4.ts b/tests/cases/conformance/references/library-reference-4.ts new file mode 100644 index 0000000000000..2aaac5da78ed6 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-4.ts @@ -0,0 +1,21 @@ +// @noImplicitReferences: true + +// Secondary references may be duplicated if they agree in content + +// @filename: node_modules/foo/index.d.ts +/// +declare var foo: any; + +// @filename: node_modules/foo/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: node_modules/bar/index.d.ts +/// +declare var bar: any; + +// @filename: node_modules/bar/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: src/root.ts +/// +/// diff --git a/tests/cases/conformance/references/library-reference-5.ts b/tests/cases/conformance/references/library-reference-5.ts new file mode 100644 index 0000000000000..e6f4049b27ce3 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-5.ts @@ -0,0 +1,21 @@ +// @noImplicitReferences: true + +// Secondary references may not be duplicated if they disagree in content + +// @filename: node_modules/foo/index.d.ts +/// +declare var foo: any; + +// @filename: node_modules/foo/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: node_modules/bar/index.d.ts +/// +declare var bar: any; + +// @filename: node_modules/bar/node_modules/alpha/index.d.ts +declare var alpha: {}; + +// @filename: src/root.ts +/// +///