diff --git a/Gulpfile.ts b/Gulpfile.ts index 6c91ef52cbb49..d77b61678f6fc 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -411,7 +411,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => { completedDts.pipe(clone()) .pipe(insert.transform((content, file) => { file.path = nodeStandaloneDefinitionsFile; - return content.replace(/declare (namespace|module) ts/g, 'declare module "typescript"'); + return content.replace(/declare (namespace|module) ts {/g, 'declare module "typescript" {\n import * as ts from "typescript";'); })) ]).pipe(gulp.dest(builtLocalDirectory)); }); diff --git a/Jakefile.js b/Jakefile.js index 174be5e702f52..18ed640ce868a 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -46,6 +46,7 @@ var compilerSources = [ "declarationEmitter.ts", "emitter.ts", "program.ts", + "extensions.ts", "commandLineParser.ts", "tsc.ts", "diagnosticInformationMap.generated.ts" @@ -67,6 +68,7 @@ var servicesSources = [ "declarationEmitter.ts", "emitter.ts", "program.ts", + "extensions.ts", "commandLineParser.ts", "diagnosticInformationMap.generated.ts" ].map(function (f) { @@ -131,6 +133,7 @@ var harnessCoreSources = [ "typeWriter.ts", "fourslashRunner.ts", "projectsRunner.ts", + "extensionRunner.ts", "loggedIO.ts", "rwcRunner.ts", "test262Runner.ts", @@ -158,7 +161,7 @@ var harnessSources = harnessCoreSources.concat([ "convertCompilerOptionsFromJson.ts", "convertTypingOptionsFromJson.ts", "tsserverProjectSystem.ts", - "matchFiles.ts" + "matchFiles.ts", ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ @@ -524,7 +527,7 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca // Node package definition file to be distributed without the package. Created by replacing // 'ts' namespace with '"typescript"' as a module. - var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"'); + var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts {/g, 'declare module "typescript" {\n import * as ts from "typescript";'); fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents); }); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 777fc57ea8de3..accac44f6d9fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17918,9 +17918,9 @@ namespace ts { return getTypeOfSymbol(symbol); } - if (isDeclarationName(node)) { + if (isDeclarationName(node) || node.kind === SyntaxKind.SourceFile) { const symbol = getSymbolAtLocation(node); - return symbol && getTypeOfSymbol(symbol); + return symbol && getTypeOfSymbol(symbol) || unknownType; } if (isBindingPattern(node)) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7e2c6eb8d334e..8dd35b033f031 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -282,6 +282,12 @@ namespace ts { experimental: true, description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, + { + name: "extensions", + type: "object", + isTSConfigOnly: true, + description: Diagnostics.List_of_compiler_extensions_to_require + }, { name: "moduleResolution", type: { @@ -429,7 +435,7 @@ namespace ts { name: "strictNullChecks", type: "boolean", description: Diagnostics.Enable_strict_null_checks - } + }, ]; /* @internal */ diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 709a331e02281..6d19ca2bf1611 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2,6 +2,17 @@ /// +namespace ts { + export function startsWith(str: string, prefix: string): boolean { + return str.lastIndexOf(prefix, 0) === 0; + } + + export function endsWith(str: string, suffix: string): boolean { + const expectedPos = str.length - suffix.length; + return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; + } +} + /* @internal */ namespace ts { /** @@ -178,6 +189,26 @@ namespace ts { return array1.concat(array2); } + export function flatten(array1: T[][]): T[] { + if (!array1 || !array1.length) return array1; + return [].concat(...array1); + } + + export function groupBy(array: T[], classifier: (item: T) => string): {[index: string]: T[]}; + export function groupBy(array: T[], classifier: (item: T) => number): {[index: number]: T[]}; + export function groupBy(array: T[], classifier: (item: T) => (string | number)): {[index: string]: T[], [index: number]: T[]} { + if (!array || !array.length) return undefined; + const ret: {[index: string]: T[], [index: number]: T[]} = {}; + for (const elem of array) { + const key = classifier(elem); + if (!ret[key]) { + ret[key] = []; + } + ret[key].push(elem); + } + return ret; + } + export function deduplicate(array: T[], areEqual?: (a: T, b: T) => boolean): T[] { let result: T[]; if (array) { @@ -904,17 +935,6 @@ namespace ts { return true; } - /* @internal */ - export function startsWith(str: string, prefix: string): boolean { - return str.lastIndexOf(prefix, 0) === 0; - } - - /* @internal */ - export function endsWith(str: string, suffix: string): boolean { - const expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - export function fileExtensionIs(path: string, extension: string): boolean { return path.length > extension.length && endsWith(path, extension); } @@ -1191,7 +1211,8 @@ namespace ts { export const supportedJavascriptExtensions = [".js", ".jsx"]; const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions); - export function getSupportedExtensions(options?: CompilerOptions): string[] { + export function getSupportedExtensions(options?: CompilerOptions, loadJS?: boolean): string[] { + if (loadJS) return supportedJavascriptExtensions; return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions; } @@ -1369,4 +1390,49 @@ namespace ts { : ((fileName) => fileName.toLowerCase()); } + /** + * This isn't the strictest deep equal, but it's good enough for us + * - +0 === -0 (though who really wants to consider them different?) + * - arguments and arrays can be equal (both typeof === object, both have enumerable keys) + * - doesn't inspect es6 iterables (not that they're used in this code base) + * - doesn't inspect regex toString value (so only references to the same regex are equal) + * - doesn't inspect date primitive number value (so only references to the same date are equal) + */ + export function deepEqual(a: any, b: any, memo?: [any, any][]): boolean { + if (a === b) return true; + if (typeof a !== typeof b) return false; + // Special case NaN + if (typeof a === "number" && isNaN(a) && isNaN(b)) return true; + // We can't know if function arguments are deep equal, so we say they're equal if they look alike + if (typeof a === "object" || typeof a === "function") { + if (memo) { + for (let i = 0; i < memo.length; i++) { + if (memo[i][0] === a && memo[i][1] === b) return true; + if (memo[i][0] === b && memo[i][1] === a) return true; + } + } + else { + memo = []; + } + + const aKeys = ts.getKeys(a); + const bKeys = ts.getKeys(b); + aKeys.sort(); + bKeys.sort(); + + if (aKeys.length !== bKeys.length) return false; + + for (let i = 0; i < aKeys.length; i++) { + if (aKeys[i] !== bKeys[i]) return false; + } + + memo.push([a, b]); + + for (const key of aKeys) { + if (!deepEqual(a[key], b[key], memo)) return false; + } + return true; + } + return false; + } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8126d5c605ea7..623acb8a5ee54 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2676,7 +2676,7 @@ "category": "Message", "code": 6099 }, - "'package.json' does not have 'types' field.": { + "'package.json' does not have '{0}' field.": { "category": "Message", "code": 6100 }, @@ -2696,7 +2696,7 @@ "category": "Message", "code": 6104 }, - "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.": { + "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": { "category": "Message", "code": 6105 }, @@ -2824,10 +2824,20 @@ "category": "Message", "code": 6136 }, - "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'": { + + "List of compiler extensions to require.": { "category": "Message", - "code": 6137 + "code": 6150 + }, + "Extension loading failed with error '{0}'.": { + "category": "Error", + "code": 6151 }, + "Extension '{0}' exported member '{1}' has extension kind '{2}', but was type '{3}' when type '{4}' was expected.": { + "category": "Error", + "code": 6152 + }, + "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/extensions.ts b/src/compiler/extensions.ts new file mode 100644 index 0000000000000..a458b0a247a4f --- /dev/null +++ b/src/compiler/extensions.ts @@ -0,0 +1,342 @@ +namespace ts { + export type LintErrorMethod = { + /** + * @param {string} err The error message to report + */ + (err: string): void; + /** + * @param {string} err The error message to report + * @param {Node} span The node on which to position the error + */ + (err: string, span: Node): void; + /** + * @param {string} err The error message to report + * @param {number} start The start position of the error span + * @param {number} length The length of the error span + */ + (err: string, start: number, length: number): void; + /** + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + */ + (shortname: string, err: string): void; + /** + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + * @param {Node} span The node on which to position the error + */ + (shortname: string, err: string, span: Node): void; + /** + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + * @param {number} start The start position of the error span + * @param {number} length The length of the error span + */ + (shortname: string, err: string, start: number, length: number): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} err The error message to report + */ + (level: DiagnosticCategory, err: string): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} err The error message to report + * @param {Node} span The node on which to position the error + */ + (level: DiagnosticCategory, err: string, span: Node): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} err The error message to report + * @param {number} start The start position of the error span + * @param {number} length The length of the error span + */ + (level: DiagnosticCategory, err: string, start: number, length: number): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + */ + (level: DiagnosticCategory, shortname: string, err: string): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + * @param {Node} span The node on which to position the error + */ + (level: DiagnosticCategory, shortname: string, err: string, span: Node): void; + /** + * @param {DiagnosticCategory} level The error level to report this error as (Message, Warning, or Error) + * @param {string} shortname A short code uniquely identifying the error within the lint + * @param {string} err The error message to report + * @param {number} start The start position of the error span + * @param {number} length The length of the error span + */ + (level: DiagnosticCategory, shortname: string, err: string, start: number, length: number): void; + }; + + /* + * Walkers call stop to halt recursion into the node's children + * Walkers call error to add errors to the output. + */ + export interface LintWalker { + /** + * @param {Node} node The current node being visited (starts at every SourceFile and recurs into their children) + * @param {LintErrorMethod} error A callback to add errors to the output + * @returns boolean true if this lint no longer needs to recur into the active node + */ + visit(node: Node, error: LintErrorMethod): boolean | void; + /** + * Yar + * @param {Node} node The current node which has just finished being visited + * @param {LintErrorMethod} error A callback to add errors to the output + */ + afterVisit?(node: Node, error: LintErrorMethod): void; + } + + export interface BaseProviderStatic { + readonly ["extension-kind"]: ExtensionKind; + new (state: {ts: typeof ts, args: any}): any; + } + + export interface SyntacticLintProviderStatic extends BaseProviderStatic { + readonly ["extension-kind"]: ExtensionKind.SyntacticLint; + new (state: {ts: typeof ts, args: any, host: CompilerHost, program: Program}): LintWalker; + } + + export interface SemanticLintProviderStatic extends BaseProviderStatic { + readonly ["extension-kind"]: ExtensionKind.SemanticLint; + new (state: {ts: typeof ts, args: any, host: CompilerHost, program: Program, checker: TypeChecker}): LintWalker; + } + + export interface LanguageServiceHost {} // The members for these interfaces are provided in the services layer + export interface LanguageService {} + export interface LanguageServiceProvider {} + export interface DocumentRegistry {} + + export interface LanguageServiceProviderStatic extends BaseProviderStatic { + readonly ["extension-kind"]: ExtensionKind.LanguageService; + new (state: { ts: typeof ts, args: any, host: LanguageServiceHost, service: LanguageService, registry: DocumentRegistry }): LanguageServiceProvider; + } + + export namespace ExtensionKind { + export const SemanticLint: "semantic-lint" = "semantic-lint"; + export type SemanticLint = "semantic-lint"; + export const SyntacticLint: "syntactic-lint" = "syntactic-lint"; + export type SyntacticLint = "syntactic-lint"; + export const LanguageService: "language-service" = "language-service"; + export type LanguageService = "language-service"; + } + export type ExtensionKind = ExtensionKind.SemanticLint | ExtensionKind.SyntacticLint | ExtensionKind.LanguageService; + + export interface ExtensionCollectionMap { + "syntactic-lint"?: SyntacticLintExtension[]; + "semantic-lint"?: SemanticLintExtension[]; + "language-service"?: LanguageServiceExtension[]; + [index: string]: Extension[] | undefined; + } + + export interface ExtensionBase { + name: string; + args: any; + kind: ExtensionKind; + } + + export interface ProfileData { + globalBucket: string; + task: string; + start: number; + length?: number; + } + + export interface SyntacticLintExtension extends ExtensionBase { + kind: ExtensionKind.SyntacticLint; + ctor: SyntacticLintProviderStatic; + } + + export interface SemanticLintExtension extends ExtensionBase { + kind: ExtensionKind.SemanticLint; + ctor: SemanticLintProviderStatic; + } + + export interface LanguageServiceExtension extends ExtensionBase { + kind: ExtensionKind.LanguageService; + ctor: LanguageServiceProviderStatic; + } + + export type Extension = SyntacticLintExtension | SemanticLintExtension | LanguageServiceExtension; + + export interface ExtensionCache { + getCompilerExtensions(): ExtensionCollectionMap; + getExtensionLoadingDiagnostics(): Diagnostic[]; + } + + export interface ExtensionHost extends ModuleResolutionHost { + loadExtension?(name: string): any; + } + + export interface Program { + /** + * Gets a map of loaded compiler extensions + */ + getCompilerExtensions(): ExtensionCollectionMap; + } + + /* @internal */ + export interface TypeCheckerHost { + getCompilerExtensions(): ExtensionCollectionMap; + } + + export const perfTraces: Map = {}; + + function getExtensionRootName(qualifiedName: string) { + return qualifiedName.substring(0, qualifiedName.indexOf("[")) || qualifiedName; + } + + function createTaskName(qualifiedName: string, task: string) { + return `${task}|${qualifiedName}`; + } + + export function startProfile(enabled: boolean, key: string, bucket?: string) { + if (!enabled) return; + performance.emit(`start|${key}`); + perfTraces[key] = { + task: key, + start: performance.mark(), + length: undefined, + globalBucket: bucket + }; + } + + export function completeProfile(enabled: boolean, key: string) { + if (!enabled) return; + Debug.assert(!!perfTraces[key], "Completed profile did not have a corresponding start."); + perfTraces[key].length = performance.measure(perfTraces[key].globalBucket, perfTraces[key].start); + performance.emit(`end|${key}`); + } + + export function startExtensionProfile(enabled: boolean, qualifiedName: string, task: string) { + if (!enabled) return; + const longTask = createTaskName(qualifiedName, task); + startProfile(/*enabled*/true, longTask, getExtensionRootName(qualifiedName)); + } + + export function completeExtensionProfile(enabled: boolean, qualifiedName: string, task: string) { + if (!enabled) return; + const longTask = createTaskName(qualifiedName, task); + completeProfile(/*enabled*/true, longTask); + } + + export function createExtensionCache(options: CompilerOptions, host: ExtensionHost, resolvedExtensionNames?: Map): ExtensionCache { + + const diagnostics: Diagnostic[] = []; + const extOptions = options.extensions; + const extensionNames = (extOptions instanceof Array) ? extOptions : getKeys(extOptions); + // Eagerly evaluate extension paths, but lazily execute their contents + resolvedExtensionNames = resolvedExtensionNames || resolveExtensionNames(); + let extensions: ExtensionCollectionMap; + + const cache: ExtensionCache = { + getCompilerExtensions: () => { + if (!extensions) { + extensions = collectCompilerExtensions(); + } + return extensions; + }, + getExtensionLoadingDiagnostics: () => { + // To get extension loading diagnostics, we need to make sure we've actually loaded them + cache.getCompilerExtensions(); + return diagnostics; + }, + }; + return cache; + + function resolveExtensionNames(): Map { + const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : ""; + const extMap: Map = {}; + forEach(extensionNames, name => { + const resolved = resolveModuleName(name, combinePaths(currentDirectory, "tsconfig.json"), options, host, /*loadJs*/true).resolvedModule; + if (resolved) { + extMap[name] = resolved.resolvedFileName; + } + }); + return extMap; + } + + function collectCompilerExtensions(): ExtensionCollectionMap { + const profilingEnabled = options.extendedDiagnostics; + const extensionLoadResults = map(extensionNames, (name) => { + const resolved = resolvedExtensionNames[name]; + let result: any; + let error: any; + if (!resolved) { + error = new Error(`Host could not locate extension '${name}'.`); + } + if (resolved && host.loadExtension) { + try { + startProfile(profilingEnabled, name, name); + result = host.loadExtension(resolved); + completeProfile(profilingEnabled, name); + } + catch (e) { + error = e; + } + } + else if (!host.loadExtension) { + error = new Error("Extension loading not implemented in host!"); + } + if (error) { + diagnostics.push(createCompilerDiagnostic(Diagnostics.Extension_loading_failed_with_error_0, error)); + } + return { name, result, error }; + }); + const successfulExtensionLoadResults = filter(extensionLoadResults, res => !res.error); + const preparedExtensionObjects = map(successfulExtensionLoadResults, res => { + if (!res.result) { + return []; + } + const aggregate: Extension[] = []; + forEachKey(res.result, key => { + const potentialExtension = res.result[key] as BaseProviderStatic; + if (!potentialExtension) { + return; // Avoid errors on explicitly exported null/undefined (why would someone do that, though?) + } + const annotatedKind = potentialExtension["extension-kind"]; + if (typeof annotatedKind !== "string") { + return; + } + const ext: ExtensionBase = { + name: key !== "default" ? `${res.name}[${key}]` : res.name, + args: extensionNames === extOptions ? undefined : (extOptions as Map)[res.name], + kind: annotatedKind, + }; + switch (ext.kind) { + case ExtensionKind.SemanticLint: + case ExtensionKind.SyntacticLint: + case ExtensionKind.LanguageService: + if (typeof potentialExtension !== "function") { + diagnostics.push(createCompilerDiagnostic( + Diagnostics.Extension_0_exported_member_1_has_extension_kind_2_but_was_type_3_when_type_4_was_expected, + res.name, + key, + (ts as any).ExtensionKind[annotatedKind], + typeof potentialExtension, + "function" + )); + return; + } + (ext as (SemanticLintExtension | SyntacticLintExtension | LanguageServiceExtension)).ctor = potentialExtension as (SemanticLintProviderStatic | SyntacticLintProviderStatic | LanguageServiceProviderStatic); + break; + default: + // Include a default case which just puts the extension unchecked onto the base extension + // This can allow language service extensions to query for custom extension kinds + (ext as any).__extension = potentialExtension; + break; + } + aggregate.push(ext as Extension); + }); + return aggregate; + }); + return groupBy(flatten(preparedExtensionObjects), elem => elem.kind) || {}; + } + } +} \ No newline at end of file diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 89db876ae5e48..71f3dbd74854d 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -58,10 +58,11 @@ namespace ts.performance { * @param measureName The name of the performance measurement. * @param marker The timestamp of the starting mark. */ - export function measure(measureName: string, marker: number) { + export function measure(measureName: string, marker: number): number { if (measures) { - measures[measureName] = (getProperty(measures, measureName) || 0) + (timestamp() - marker); + return measures[measureName] = (getProperty(measures, measureName) || 0) + (timestamp() - marker); } + return 0; } /** diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 4b9948c3ba0b4..38d9a91894f3e 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,6 +1,8 @@ /// /// /// +/// + namespace ts { /** The version of the TypeScript compiler release */ @@ -118,57 +120,51 @@ namespace ts { skipTsx: boolean; } - function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string { - let jsonContent: { typings?: string, types?: string, main?: string }; - try { - const jsonText = state.host.readFile(packageJsonPath); - jsonContent = jsonText ? <{ typings?: string, types?: string, main?: string }>JSON.parse(jsonText) : {}; + function getPackageEntry(packageJson: any, key: string, tag: string, state: ModuleResolutionState) { + const value = packageJson[key]; + if (typeof value === tag) { + return value; } - catch (e) { - // gracefully handle if readFile fails or returns not JSON - jsonContent = {}; + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, key, tag, typeof value); } + return undefined; + } - let typesFile: string; - let fieldName: string; - // first try to read content of 'typings' section (backward compatibility) - if (jsonContent.typings) { - if (typeof jsonContent.typings === "string") { - fieldName = "typings"; - typesFile = jsonContent.typings; - } - else { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "typings", typeof jsonContent.typings); - } - } + function getPackageEntryAsPath(packageJson: any, packageJsonPath: string, key: string, state: ModuleResolutionState) { + const value = getPackageEntry(packageJson, key, "string", state); + const path = value ? normalizePath(combinePaths(getDirectoryPath(packageJsonPath), value)) : undefined; + if (path && state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, key, value, path); } - // then read 'types' - if (!typesFile && jsonContent.types) { - if (typeof jsonContent.types === "string") { - fieldName = "types"; - typesFile = jsonContent.types; - } - else { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "types", typeof jsonContent.types); - } - } + return path; + } + + function getPackageTypes(packageJsonPath: string, state: ModuleResolutionState) { + const { config } = readConfigFile(packageJsonPath, state.host.readFile); + if (config) { + return getPackageEntryAsPath(config, packageJsonPath, "typings", state) + || getPackageEntryAsPath(config, packageJsonPath, "types", state) + // Use the main module for inferring types if no types package specified and the allowJs is set + || (state.compilerOptions.allowJs && getPackageEntryAsPath(config, packageJsonPath, "main", state)); } - if (typesFile) { - const typesFilePath = normalizePath(combinePaths(baseDirectory, typesFile)); + else { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, typesFile, typesFilePath); + trace(state.host, Diagnostics.package_json_does_not_have_0_field, "types"); } - return typesFilePath; } - // Use the main module for inferring types if no types package specified and the allowJs is set - if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") { + return undefined; + } + + function getPackageMain(packageJsonPath: string, state: ModuleResolutionState) { + const { config } = readConfigFile(packageJsonPath, state.host.readFile); + if (config) { + return getPackageEntryAsPath(config, packageJsonPath, "main", state); + } + else { if (state.traceEnabled) { - trace(state.host, Diagnostics.No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0, jsonContent.main); + trace(state.host, Diagnostics.package_json_does_not_have_0_field, "main"); } - const mainFilePath = normalizePath(combinePaths(baseDirectory, jsonContent.main)); - return mainFilePath; } return undefined; } @@ -293,7 +289,7 @@ namespace ts { }; } - export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, loadJs?: boolean): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile); @@ -315,7 +311,7 @@ namespace ts { let result: ResolvedModuleWithFailedLookupLocations; switch (moduleResolution) { case ModuleResolutionKind.NodeJs: - result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host); + result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, loadJs); break; case ModuleResolutionKind.Classic: result = classicNameResolver(moduleName, containingFile, compilerOptions, host); @@ -610,7 +606,7 @@ namespace ts { }; } - export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, loadJs?: boolean): ResolvedModuleWithFailedLookupLocations { const containingDirectory = getDirectoryPath(containingFile); const supportedExtensions = getSupportedExtensions(compilerOptions); const traceEnabled = isTraceEnabled(compilerOptions, host); @@ -626,7 +622,7 @@ namespace ts { if (traceEnabled) { trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName); } - resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state); + resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state, loadJs); isExternalLibraryImport = resolvedFileName !== undefined; } else { @@ -716,25 +712,20 @@ namespace ts { } } - function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string { + function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState, loadJS?: boolean): string { const packageJsonPath = combinePaths(candidate, "package.json"); const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); if (directoryExists && state.host.fileExists(packageJsonPath)) { if (state.traceEnabled) { trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath); } - const typesFile = tryReadTypesSection(packageJsonPath, candidate, state); + const typesFile = loadJS ? getPackageMain(packageJsonPath, state) : getPackageTypes(packageJsonPath, state); if (typesFile) { const result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(getDirectoryPath(typesFile), state.host), state); if (result) { return result; } } - else { - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_types_field); - } - } } else { if (state.traceEnabled) { @@ -747,30 +738,31 @@ namespace ts { return loadModuleFromFile(combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state); } - function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string { + function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, loadJS?: boolean): string { const nodeModulesFolder = combinePaths(directory, "node_modules"); const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host); const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); - const supportedExtensions = getSupportedExtensions(state.compilerOptions); + + const supportedExtensions = getSupportedExtensions(state.compilerOptions, loadJS); let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state); if (result) { return result; } - result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); + result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, loadJS); if (result) { return result; } } - function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string { + function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, loadJS?: boolean): string { directory = normalizeSlashes(directory); while (true) { const baseName = getBaseFileName(directory); if (baseName !== "node_modules") { // Try to load source from the package - const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state); - if (packageResult && hasTypeScriptFileExtension(packageResult)) { + const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state, loadJS); + if (packageResult && (hasTypeScriptFileExtension(packageResult) || loadJS)) { // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package return packageResult; } @@ -954,6 +946,7 @@ namespace ts { const newLine = getNewLineCharacter(options); const realpath = sys.realpath && ((path: string) => sys.realpath(path)); + const loadExtension = sys.loadExtension && ((name: string) => sys.loadExtension(name)); return { getSourceFile, @@ -969,7 +962,8 @@ namespace ts { trace: (s: string) => sys.write(s + newLine), directoryExists: directoryName => sys.directoryExists(directoryName), getDirectories: (path: string) => sys.getDirectories(path), - realpath + realpath, + loadExtension }; } @@ -1004,7 +998,8 @@ namespace ts { } const category = DiagnosticCategory[diagnostic.category].toLowerCase(); - output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`; + const code = typeof diagnostic.code === "string" ? diagnostic.code : `TS${ diagnostic.code }`; + output += `${ category } ${ code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`; } return output; } @@ -1088,7 +1083,7 @@ namespace ts { return result; } - export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program { + export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, extensionCache?: ExtensionCache): Program { let program: Program; let files: SourceFile[] = []; let commonSourceDirectory: string; @@ -1188,6 +1183,8 @@ namespace ts { // unconditionally set oldProgram to undefined to prevent it from being captured in closure oldProgram = undefined; + extensionCache = extensionCache || createExtensionCache(options, host); + program = { getRootFileNames: () => rootNames, getSourceFile, @@ -1210,7 +1207,13 @@ namespace ts { getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(), getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(), getFileProcessingDiagnostics: () => fileProcessingDiagnostics, - getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives + getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives, + getCompilerExtensions() { + return extensionCache.getCompilerExtensions(); + }, + getExtensionLoadingDiagnostics() { + return extensionCache.getExtensionLoadingDiagnostics(); + }, }; verifyCompilerOptions(); @@ -1515,7 +1518,264 @@ namespace ts { } } + /** + * ExtensionKind.SyntacticLint or ExtensionKind.SemanticLint only + */ + function performLintPassOnFile(sourceFile: SourceFile, kind: ExtensionKind): Diagnostic[] | undefined { + const lints = extensionCache.getCompilerExtensions()[kind]; + if (!lints || !lints.length) { + return; + } + type UniqueLint = {name: string, walker: LintWalker, accepted: boolean, errored: boolean}; + const initializedLints: UniqueLint[] = []; + const diagnostics: Diagnostic[] = []; + let activeLint: UniqueLint; + let parent: Node | undefined = undefined; + const profilingEnabled = options.extendedDiagnostics; + for (const {name, args, ctor} of lints) { + let walker: LintWalker; + if (kind === ExtensionKind.SemanticLint) { + const checker = getTypeChecker(); + startExtensionProfile(profilingEnabled, name, "construct"); + try { + walker = new (ctor as SemanticLintProviderStatic)({ ts, checker, args, host, program }); + } + catch (e) { + diagnostics.push(createExtensionDiagnostic(name, `Lint construction failed: ${(e as Error).message}`, sourceFile, /*start*/undefined, /*length*/undefined, DiagnosticCategory.Error)); + } + completeExtensionProfile(profilingEnabled, name, "construct"); + } + else if (kind === ExtensionKind.SyntacticLint) { + startExtensionProfile(profilingEnabled, name, "construct"); + try { + walker = new (ctor as SyntacticLintProviderStatic)({ ts, args, host, program }); + } + catch (e) { + diagnostics.push(createExtensionDiagnostic(name, `Lint construction failed: ${(e as Error).message}`, /*sourceFile*/undefined, /*start*/undefined, /*length*/undefined, DiagnosticCategory.Error)); + } + completeExtensionProfile(profilingEnabled, name, "construct"); + } + if (walker) initializedLints.push({ name, walker, accepted: true, errored: false }); + } + + function visitNode(node: Node) { + let oneAccepted = false; + const needsReset: Map = {}; + + // Ensure parent pointer is set + node.parent = parent; + + // For each lint, except those which have errored or have not accepted a parental node, call its rule + for (let i = 0; i < initializedLints.length; i++) { + activeLint = initializedLints[i]; + if (activeLint.errored || !activeLint.accepted) { + continue; + } + + startExtensionProfile(profilingEnabled, activeLint.name, "visit"); + try { + activeLint.accepted = !activeLint.walker.visit(node, error); + } + catch (e) { + activeLint.errored = true; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName("!!!"), `visit failed with error: ${e}`, /*sourceFile*/undefined, /*start*/undefined, /*length*/undefined, DiagnosticCategory.Error)); + } + completeExtensionProfile(profilingEnabled, activeLint.name, "visit"); + + if (activeLint.accepted) { + oneAccepted = true; + } + else { + needsReset[i] = true; + } + } + + // Save the parent, then recur into the child nodes + const oldParent = parent; + parent = node; + if (oneAccepted) { + forEachChild(node, visitNode); + } + parent = oldParent; + + // All this node's children have been processed, for each lint + // - If it set accepted to false during this node (needsReset), set it back to true + // - If it has an afterVisit method, call it + for (let i = 0; i < initializedLints.length; i++) { + activeLint = initializedLints[i]; + if (activeLint.errored) { + continue; + } + if (!needsReset[i]) { + activeLint.accepted = true; + needsReset[i] = false; + } + if (!activeLint.walker.afterVisit) { + continue; + } + startExtensionProfile(profilingEnabled, activeLint.name, "afterVisit"); + try { + activeLint.walker.afterVisit(node, error); + } + catch (e) { + activeLint.errored = true; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName("!!!"), `afterVisit failed with error: ${e}`, /*sourceFile*/undefined, /*start*/undefined, /*length*/undefined, DiagnosticCategory.Error)); + } + completeExtensionProfile(profilingEnabled, activeLint.name, "afterVisit"); + } + } + + function errorQualifiedName(shortname?: string) { + if (!shortname) return activeLint.name; + return `${activeLint.name}(${shortname})`; + } + + function ensure(param: any, paramName: string, istype: string) { + if (typeof param !== istype) { + Debug.fail(`${paramName} must be a ${istype}.`); + } + } + + const errorOverloads: ((...args: any[]) => void)[] = [() => { + Debug.fail("You must at least provide an error message to the error function."); + }, + (err: string) => { + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(), err)); + }, + (errShortnameOrLevel: string | DiagnosticCategory, spanOrErr: Node | string | number) => { + if (typeof errShortnameOrLevel === "string") { + if (typeof spanOrErr === "string") { + // error(shortname: string, err: string): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(errShortnameOrLevel), spanOrErr)); + } + else if (typeof spanOrErr === "object") { + // error(err: string, node: Node): void; + diagnostics.push(createExtensionDiagnosticForNode(spanOrErr, errorQualifiedName(), errShortnameOrLevel)); + } + else { + Debug.fail("When two arguments are passed to error and the first argument is either the error message or error shortname, the second argument must either be an error message string or the node the error is on."); + } + } + else if (typeof errShortnameOrLevel === "number") { + ensure(spanOrErr, "Error message", "string"); + + // error(level: DiagnosticCategory, err: string): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(), spanOrErr as string, /*sourceFile*/undefined, /*start*/undefined, /*length*/undefined, errShortnameOrLevel)); + } + else { + Debug.fail("When two arguments are passed to error, the first argument must be either the error message, the error shortname, or the DiagnosticCategory of the error."); + } + }, + (errShortnameOrLevel: string | DiagnosticCategory, startErrOrShortname: number | string | Node, lengthSpanOrErr: number | Node | string) => { + if (typeof errShortnameOrLevel === "number") { + ensure(startErrOrShortname, "Error message or error shortcode", "string"); + + if (typeof lengthSpanOrErr === "string") { + // error(level: DiagnosticCategory, shortname: string, err: string): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(startErrOrShortname as string), lengthSpanOrErr, /*sourceFile*/undefined, /*start*/undefined, /*length*/undefined, errShortnameOrLevel)); + } + else if (typeof lengthSpanOrErr === "object") { + // error(level: DiagnosticCategory, err: string, node: Node): void; + diagnostics.push(createExtensionDiagnosticForNode(lengthSpanOrErr, errorQualifiedName(), startErrOrShortname as string, errShortnameOrLevel)); + } + else { + Debug.fail("When three arguments are passed to error and the first is a diagnostic category, the third argument must either be an error message or the node errored on."); + } + } + else if (typeof errShortnameOrLevel === "string") { + if (typeof startErrOrShortname === "number") { + ensure(lengthSpanOrErr, "Error span length", "number"); + + // error(err: string, start: number, length: number): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(), errShortnameOrLevel, sourceFile, startErrOrShortname, lengthSpanOrErr as number)); + } + else if (typeof startErrOrShortname === "string") { + ensure(lengthSpanOrErr, "Error node", "object"); + + // error(shortname: string, err: string, span: Node): void; + diagnostics.push(createExtensionDiagnosticForNode(lengthSpanOrErr as Node, errorQualifiedName(errShortnameOrLevel), startErrOrShortname)); + } + else { + Debug.fail("When three arguments are passed to error and the first is an error shortcode or message, the second must be either an error message or a span start number, respectively."); + } + } + else { + Debug.fail("When three arguments are passed to error, the first argument must be either a diagnostic category, a error shortname, or an error message."); + } + }, + (levelOrShortname: DiagnosticCategory | string, errOrShortname: string | number | Node, startOrErr: string | number | Node, lengthOrSpan: number | Node) => { + ensure(errOrShortname, "Error message or error shortcode", "string"); + + if (typeof levelOrShortname === "number") { + if (typeof startOrErr === "string") { + ensure(lengthOrSpan, "Error node", "object"); + + // error(level: DiagnosticCategory, shortname: string, err: string, span: Node): void; + diagnostics.push(createExtensionDiagnosticForNode(lengthOrSpan as Node, errorQualifiedName(errOrShortname as string), startOrErr, levelOrShortname)); + } + else if (typeof startOrErr === "number") { + ensure(lengthOrSpan, "Error span length", "number"); + + // error(level: DiagnosticCategory, err: string, start: number, length: number): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(), errOrShortname as string, sourceFile, startOrErr, lengthOrSpan as number, levelOrShortname)); + } + else { + Debug.fail("When four arguments are passed to error and the first is a DiagnosticCategory, the third argument must be the error message."); + return; + } + } + else if (typeof levelOrShortname === "string") { + ensure(startOrErr, "Error span start", "number"); + ensure(lengthOrSpan, "Error span length", "number"); + + // error(shortname: string, err: string, start: number, length: number): void; + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(levelOrShortname), errOrShortname as string, sourceFile, startOrErr as number, lengthOrSpan as number)); + } + else { + Debug.fail("When four arguments are passed to error, the first argument must be either a DiagnosticCategory or a error shortname string."); + } + }, + (level: DiagnosticCategory, shortname: string, err: string, start: number, length: number) => { + ensure(level, "Diagnostic level", "number"); + ensure(shortname, "Error shortcode", "string"); + ensure(err, "Error message", "string"); + ensure(start, "Error span start", "number"); + ensure(length, "Error span length", "number"); + + diagnostics.push(createExtensionDiagnostic(errorQualifiedName(shortname), err, sourceFile, start, length, level)); + }]; + + function tooManyArguments(length: number, found: number) { + return () => Debug.fail(`Too many arguments provided to error (Expected up to ${length}, but found ${found}).`); + } + + function error(err: string): void; + function error(err: string, node: Node): void; + function error(err: string, start: number, length: number): void; + function error(shortname: string, err: string): void; + function error(shortname: string, err: string, span: Node): void; + function error(shortname: string, err: string, start: number, length: number): void; + function error(level: DiagnosticCategory, err: string): void; + function error(level: DiagnosticCategory, err: string, node: Node): void; + function error(level: DiagnosticCategory, err: string, start: number, length: number): void; + function error(level: DiagnosticCategory, shortname: string, err: string): void; + function error(level: DiagnosticCategory, shortname: string, err: string, span: Node): void; + function error(level: DiagnosticCategory, shortname: string, err: string, start: number, length: number): void; + function error(): void { + (errorOverloads[arguments.length] || tooManyArguments(errorOverloads.length - 1, arguments.length)).apply(/*thisArg*/undefined, arguments); + } + + visitNode(sourceFile); + return diagnostics; + } + function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + if (!sourceFile.isDeclarationFile) { + const lintDiagnostics = performLintPassOnFile(sourceFile, ExtensionKind.SyntacticLint); + if (lintDiagnostics && lintDiagnostics.length) { + return sourceFile.parseDiagnostics.concat(lintDiagnostics); + } + } return sourceFile.parseDiagnostics; } @@ -1556,8 +1816,9 @@ namespace ts { typeChecker.getDiagnostics(sourceFile, cancellationToken); const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); + const lintDiagnostics = (!sourceFile.isDeclarationFile) ? (performLintPassOnFile(sourceFile, ExtensionKind.SemanticLint) || []) : []; - return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile); + return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile).concat(lintDiagnostics); }); } @@ -1754,6 +2015,7 @@ namespace ts { const allDiagnostics: Diagnostic[] = []; addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics()); addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics()); + allDiagnostics.push(...extensionCache.getExtensionLoadingDiagnostics()); return sortAndDeduplicateDiagnostics(allDiagnostics); } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 29ae2c60af165..251c22fd43ade 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -32,6 +32,7 @@ namespace ts { getMemoryUsage?(): number; exit(exitCode?: number): void; realpath?(path: string): string; + loadExtension?(name: string): any; } export interface FileWatcher { @@ -548,6 +549,9 @@ namespace ts { }, realpath(path: string): string { return _fs.realpathSync(path); + }, + loadExtension(name) { + return require(name); } }; return nodeSystem; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 10538d0c009ee..ae48d689dc120 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -599,6 +599,19 @@ namespace ts { performance.disable(); } + const perfTotals: Map = {}; + for (const key of getKeys(perfTraces)) { + const value = perfTraces[key]; + if (!value) continue; + if (typeof perfTotals[value.globalBucket] !== "number") { + perfTotals[value.globalBucket] = 0; + } + perfTotals[value.globalBucket] += value.length; + } + forEachKey(perfTotals, (key) => { + reportTimeStatistic(`'${key}' time`, perfTotals[key]); + }); + return { program, exitStatus }; function compileProgram(): ExitStatus { @@ -607,13 +620,18 @@ namespace ts { // First get and report any syntactic errors. diagnostics = program.getSyntacticDiagnostics(); + // Count warnings and ignore them for determining continued error reporting + const warningsCount = countWhere(diagnostics, d => d.category === DiagnosticCategory.Warning); + // If we didn't have any syntactic errors, then also try getting the global and // semantic errors. - if (diagnostics.length === 0) { - diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics()); + if (diagnostics.length === warningsCount) { + diagnostics = diagnostics.concat(program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics())); + + const warningsCount = countWhere(diagnostics, d => d.category === DiagnosticCategory.Warning); - if (diagnostics.length === 0) { - diagnostics = program.getSemanticDiagnostics(); + if (diagnostics.length === warningsCount) { + diagnostics = diagnostics.concat(program.getSemanticDiagnostics()); } } diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index cc9bfddcece78..5f751856bfb13 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -24,6 +24,7 @@ "declarationEmitter.ts", "emitter.ts", "program.ts", + "extensions.ts", "commandLineParser.ts", "tsc.ts", "diagnosticInformationMap.generated.ts" diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 072209aa49640..6967893954f9a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,4 +1,3 @@ - namespace ts { export interface Map { [index: string]: T; @@ -1743,6 +1742,11 @@ namespace ts { */ getTypeChecker(): TypeChecker; + /** + * Gets only diagnostics reported while loading extensions + */ + getExtensionLoadingDiagnostics(): Diagnostic[]; + /* @internal */ getCommonSourceDirectory(): string; // For testing purposes only. Should not be used by any other consumers (including the @@ -2530,7 +2534,7 @@ namespace ts { length: number; messageText: string | DiagnosticMessageChain; category: DiagnosticCategory; - code: number; + code: number | string; } export enum DiagnosticCategory { @@ -2623,6 +2627,7 @@ namespace ts { typeRoots?: string[]; /*@internal*/ version?: boolean; /*@internal*/ watch?: boolean; + extensions?: string[] | Map; [option: string]: CompilerOptionsValue | undefined; } @@ -2955,6 +2960,14 @@ namespace ts { * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + + /** + * Delegates the loading of compiler extensions to the compiler host. + * The function should return the result of executing the code of an extension + * - its exported members. These members will be searched for objects who have been decorated with + * specific flags. + */ + loadExtension?(extension: string): any; } export interface TextSpan { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4ae0005e9c5e7..c143aa69906a0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -456,6 +456,24 @@ namespace ts { return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2); } + export function createExtensionDiagnosticForNode(node: Node, extension: string, message: string, category?: DiagnosticCategory): Diagnostic { + const sourceFile = getSourceFileOfNode(node); + const span = getErrorSpanForNode(sourceFile, node); + return createExtensionDiagnostic(extension, message, sourceFile, span.start, span.length, category); + } + + export function createExtensionDiagnostic(extension: string, message: string, file?: SourceFile, start?: number, length?: number, category?: DiagnosticCategory): Diagnostic { + Debug.assert(file ? typeof start === "number" && typeof length === "number" : true, "File, start, and length must all be specified or unspecified."); + return { + file: file, + messageText: message, + code: extension, + start: start, + length: length, + category: typeof category !== "undefined" ? category : DiagnosticCategory.Warning + }; + } + export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic { const sourceFile = getSourceFileOfNode(node); const span = getErrorSpanForNode(sourceFile, node); diff --git a/src/harness/extensionRunner.ts b/src/harness/extensionRunner.ts new file mode 100644 index 0000000000000..ca7ab8c4a6d9b --- /dev/null +++ b/src/harness/extensionRunner.ts @@ -0,0 +1,492 @@ +/// +/// +/// + +interface ExtensionTestConfig { + inputFiles: string[]; // Files from the source directory to include in the compilation + fourslashTest?: string; // File from the fourslash directory to test this compilation with + availableExtensions: string[]; // Extensions from the available directory to make available to the test + compilerOptions?: ts.CompilerOptions; // Optional compiler options to run with (usually at least "extensions" is specified) +} + +type VirtualCompilationFunction = (files: string[], options: ts.CompilerOptions) => Harness.Compiler.CompilerResult; + +class ExtensionRunner extends RunnerBase { + private basePath = "tests/cases/extensions"; + private scenarioPath = ts.combinePaths(this.basePath, "scenarios"); + private extensionPath = ts.combinePaths(this.basePath, "available"); + private sourcePath = ts.combinePaths(this.basePath, "source"); + private fourslashPath = ts.combinePaths(this.basePath, "fourslash"); + private extensionAPI: ts.Map = {}; + private extensions: ts.Map> = {}; + private virtualLib: ts.Map = {}; + private virtualFs: ts.Map = {}; + + prettyPrintDiagnostic(diagnostic: ts.Diagnostic): string { + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + return `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`; + } + else { + return `!!!${message}`; + } + } + + private innerCanonicalName = ts.createGetCanonicalFileName(true); + private getCanonicalFileName = (fileName: string) => ts.toPath(fileName, "/", this.innerCanonicalName); + + loadSetIntoFsAt(set: ts.Map, prefix: string) { + ts.Debug.assert(!!prefix, "Prefix must exist"); + ts.Debug.assert(set !== this.virtualFs, "You cannot try to load the fs into itself."); + + // Load a fileset at the given location, but exclude the 'lib' kind files from the added set (they'll be reloaded at the top level before compilation) + ts.forEachKey(set, key => ts.forEachKey(this.virtualLib, path => key === path) ? void 0 : void (this.virtualFs[this.getCanonicalFileName(`${prefix}/${key}`)] = set[key])); + } + + loadSetIntoFs(set: ts.Map) { + ts.Debug.assert(set !== this.virtualFs, "You cannot try to load the fs into itself."); + ts.forEachKey(set, key => void (this.virtualFs[this.getCanonicalFileName(key)] = set[key])); + } + + private traces: string[] = []; + private mockHost: ts.CompilerHost = { + useCaseSensitiveFileNames: () => true, + getNewLine: () => "\n", + readFile: (path) => this.virtualFs[this.mockHost.getCanonicalFileName(path)], + writeFile: (path, content, foo, bar, baz) => { + this.virtualFs[this.mockHost.getCanonicalFileName(path)] = content; + }, + fileExists: (path) => { + return !!this.virtualFs[this.mockHost.getCanonicalFileName(path)]; + }, + directoryExists: (path) => { + const fullPath = this.mockHost.getCanonicalFileName(path); + return ts.forEach(ts.getKeys(this.virtualFs), key => ts.startsWith(key, fullPath)); + }, + getCurrentDirectory(): string { return "/"; }, + getSourceFile: (path, languageVersion, onError): ts.SourceFile => { + const fullPath = this.mockHost.getCanonicalFileName(path); + return ts.createSourceFile(fullPath, this.virtualFs[fullPath], languageVersion); + }, + getDefaultLibLocation: () => "/lib/", + getDefaultLibFileName: (options) => { + return ts.combinePaths(this.mockHost.getDefaultLibLocation(), ts.getDefaultLibFileName(options)); + }, + getCanonicalFileName: this.getCanonicalFileName, + getDirectories: (path) => { + path = this.mockHost.getCanonicalFileName(path); + return ts.filter(ts.map(ts.filter(ts.getKeys(this.virtualFs), + fullpath => ts.startsWith(fullpath, path) && fullpath.substr(path.length, 1) === "/"), + fullpath => fullpath.substr(path.length + 1).indexOf("/") >= 0 ? fullpath.substr(0, 1 + path.length + fullpath.substr(path.length + 1).indexOf("/")) : fullpath), + fullpath => fullpath.lastIndexOf(".") === -1); + }, + loadExtension: (path) => this.mockLoadExtension(path), + trace: (s) => { + this.traces.push(s); + } + }; + + mockLoadExtension(path: string) { + const fullPath = this.getCanonicalFileName(path); + const m = { exports: {} }; + ((module, exports, require) => { eval(this.virtualFs[fullPath]); })( + m, + m.exports, + (name: string) => { + return this.mockLoadExtension( + this.getCanonicalFileName( + ts.resolveModuleName(name, fullPath, { module: ts.ModuleKind.CommonJS, moduleResolution: ts.ModuleResolutionKind.NodeJs }, this.mockHost, true).resolvedModule.resolvedFileName + ) + ); + } + ); + return m.exports; + } + + makeLSMockAdapter(files: string[], options: ts.CompilerOptions, token?: ts.HostCancellationToken) { + const adapter = new Harness.LanguageService.NativeLanguageServiceAdapter(token, options); + // The host returned by the harness is _mostly_ suitable for use here + // it just needs to be monkeypatched to load extensions, report directories, and canonicalize script paths + const host = adapter.getHost(); + host.getDefaultLibFileName = () => "/lib/lib.d.ts"; + host.getCurrentDirectory = () => "/"; + (host as ts.LanguageServiceHost).loadExtension = (path) => this.mockLoadExtension(path); + (host as ts.LanguageServiceHost).useCaseSensitiveFileNames = () => true; + host.trace = (s) => { + this.traces.push(s); + }; + host.getScriptInfo = (fileName: string) => { + fileName = this.getCanonicalFileName(fileName); + return ts.lookUp(host.fileNameToScript, fileName); + }; + host.getDirectories = (s: string) => this.mockHost.getDirectories(s); + host.addScript = (fileName: string, content: string, isRootFile: boolean): void => { + const canonical = this.getCanonicalFileName(fileName); + host.fileNameToScript[canonical] = new Harness.LanguageService.ScriptInfo(canonical, content, isRootFile); + }; + ts.forEach(files, file => { + host.addScript(file, this.virtualFs[file], looksLikeRootFile(file)); + }); + + return adapter; + + function looksLikeRootFile(file: string) { + return ts.endsWith(file, ".ts") && !ts.endsWith(file, ".d.ts") && (file.indexOf("node_modules") === -1); + } + } + + makeMockLSHost(files: string[], options: ts.CompilerOptions) { + const adapter = this.makeLSMockAdapter(files, options); + return adapter.getHost(); + }; + + getTraces(): string[] { + const traces = this.traces; + this.traces = []; + return traces.map(t => t.replace(/\([0-9\.e\+\-]+ ms\)$/, "(REDACTED ms)")); + } + + languageServiceCompile(typescriptFiles: string[], options: ts.CompilerOptions): Harness.Compiler.CompilerResult { + const self = this; + const host = this.makeMockLSHost(ts.getKeys(this.virtualFs), options); + const service = ts.createLanguageService(host); + const fileResults: Harness.Compiler.GeneratedFile[] = []; + + const diagnostics = ts.concatenate(ts.concatenate( + service.getProgramDiagnostics(), + ts.flatten(ts.map(typescriptFiles, fileName => service.getSyntacticDiagnostics(this.getCanonicalFileName(fileName))))), + ts.flatten(ts.map(typescriptFiles, fileName => service.getSemanticDiagnostics(this.getCanonicalFileName(fileName))))); + + const emitResult = service.getProgram().emit(/*targetSourceFile*/undefined, writeFile); + + const allDiagnostics = ts.sortAndDeduplicateDiagnostics(ts.concatenate(diagnostics, emitResult.diagnostics)); + + return new Harness.Compiler.CompilerResult(fileResults, allDiagnostics, /*program*/undefined, host.getCurrentDirectory(), emitResult.sourceMaps, this.getTraces()); + + function writeFile(fileName: string, code: string, writeByteOrderMark: boolean, onError: (message: string) => void, sourceFiles: ts.SourceFile[]) { + fileResults.push({ + fileName, + writeByteOrderMark, + code + }); + self.mockHost.writeFile(fileName, code, writeByteOrderMark, onError, sourceFiles); + } + } + + programCompile(typescriptFiles: string[], options: ts.CompilerOptions): Harness.Compiler.CompilerResult { + const self = this; + const program = ts.createProgram(typescriptFiles, options, this.mockHost); + const fileResults: Harness.Compiler.GeneratedFile[] = []; + const diagnostics = ts.getPreEmitDiagnostics(program); + const emitResult = program.emit(/*targetSourceFile*/undefined, writeFile); + + const allDiagnostics = ts.sortAndDeduplicateDiagnostics(ts.concatenate(diagnostics, emitResult.diagnostics)); + + return new Harness.Compiler.CompilerResult(fileResults, allDiagnostics, /*program*/undefined, this.mockHost.getCurrentDirectory(), emitResult.sourceMaps, this.getTraces()); + function writeFile(fileName: string, code: string, writeByteOrderMark: boolean, onError: (message: string) => void, sourceFiles: ts.SourceFile[]) { + fileResults.push({ + fileName, + writeByteOrderMark, + code + }); + self.mockHost.writeFile(fileName, code, writeByteOrderMark, onError, sourceFiles); + } + } + + compile(fileset: ts.Map, options: ts.CompilerOptions, compileFunc: VirtualCompilationFunction): Harness.Compiler.CompilerResult { + this.loadSetIntoFs(this.virtualLib); + this.loadSetIntoFs(fileset); + + // Consider all TS files in the passed fileset as the root files, but not any under a node_modules folder + const typescriptFiles = ts.filter(ts.getKeys(fileset), name => ts.endsWith(name, ".ts") && !(name.indexOf("node_modules") >= 0)); + return compileFunc(typescriptFiles, options); + } + + buildMap(compileFunc: VirtualCompilationFunction, map: ts.Map, out: ts.Map, compilerOptions?: ts.CompilerOptions, shouldError?: boolean): Harness.Compiler.CompilerResult { + const results = this.compile(map, compilerOptions ? compilerOptions : { module: ts.ModuleKind.CommonJS, declaration: true }, compileFunc); + const diagnostics = results.errors; + if (shouldError && diagnostics && diagnostics.length) { + for (let i = 0; i < diagnostics.length; i++) { + console.log(this.prettyPrintDiagnostic(diagnostics[i])); + } + throw new Error("Compiling test harness extension API code resulted in errors."); + } + ts.copyMap(this.virtualFs, out); + this.virtualFs = {}; + return results; + } + + private loadExtensions() { + this.extensionAPI = { + "package.json": Harness.IO.readFile(ts.combinePaths(this.extensionPath, "extension-api/package.json")), + "index.ts": Harness.IO.readFile(ts.combinePaths(this.extensionPath, "extension-api/index.ts")), + }; + this.buildMap((str, opts) => this.programCompile(str, opts), this.extensionAPI, this.extensionAPI, { module: ts.ModuleKind.CommonJS, declaration: true }, /*shouldError*/true); + + ts.forEach(Harness.IO.getDirectories(this.extensionPath), path => { + if (path === "extension-api" || path === "typescript") return; // Since these are dependencies of every actual test extension, we handle them specially + const packageDir = ts.combinePaths(this.extensionPath, path); + const extensionFileset: ts.Map = {}; + const extensionFiles = this.enumerateFiles(packageDir, /*regex*/ undefined, { recursive: true }); + ts.forEach(extensionFiles, name => { + const shortName = name.substring(packageDir.length + 1); + extensionFileset[shortName] = Harness.IO.readFile(name); + }); + this.loadSetIntoFsAt(this.extensionAPI, "/node_modules/extension-api"); + + this.buildMap((str, opts) => this.programCompile(str, opts), extensionFileset, extensionFileset, { module: ts.ModuleKind.CommonJS, declaration: true }, /*shouldError*/true); + this.extensions[path] = extensionFileset; + }); + } + + constructor() { + super(); + const {content: libContent} = Harness.getDefaultLibraryFile(Harness.IO); + const tsLibContents = Harness.IO.readFile("built/local/typescript.d.ts"); + this.virtualLib = { + "/lib/lib.d.ts": libContent, + "/node_modules/typescript/index.d.ts": tsLibContents + }; + this.loadExtensions(); + } + + kind(): "extension" { + return "extension"; + } + + enumerateTestFiles(): string[] { + return this.enumerateFiles(this.scenarioPath, /\.json$/, { recursive: true }); + } + + /** Setup the runner's tests so that they are ready to be executed by the harness + * The first test should be a describe/it block that sets up the harness's compiler instance appropriately + */ + public initializeTests(): void { + describe("Compiler Extensions", () => { + if (this.tests.length === 0) { + const testFiles = this.enumerateTestFiles(); + testFiles.forEach(fn => { + this.runTest(fn); + }); + } + else { + this.tests.forEach(test => this.runTest(test)); + } + }); + } + + getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string { + return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : ""; + } + + private compileTargets: [string, VirtualCompilationFunction][] = [["CompilerHost", (str, opts) => this.programCompile(str, opts)], ["LanguageServiceHost", (str, opts) => this.languageServiceCompile(str, opts)]]; + /** + * Extensions tests are complete end-to-end tests with multiple compilations to prepare a test + * + * Tests need to be: + * Run under both `compilerHost` and `languageServiceHost` environments + * - When under LSHost, verify all fourslash test-type results included in the test + * - Verify output baseline + * - Verify error baseline + * - Verify sourcemaps if need be + * - Verify traces if need be + */ + private runTest(caseName: string) { + const caseNameNoExtension = caseName.replace(/\.json$/, ""); + describe(caseNameNoExtension, () => { + let shortCasePath: string; + let testConfigText: string; + let testConfig: ExtensionTestConfig; + let inputSources: ts.Map; + let inputTestFiles: Harness.Compiler.TestFile[]; + before(() => { + shortCasePath = caseName.substring(this.scenarioPath.length + 1).replace(/\.json$/, ""); + testConfigText = Harness.IO.readFile(caseName); + testConfig = JSON.parse(testConfigText); + inputSources = {}; + inputTestFiles = []; + ts.forEach(testConfig.inputFiles, name => { + inputSources[name] = Harness.IO.readFile(ts.combinePaths(this.sourcePath, name)); + inputTestFiles.push({ + unitName: this.getCanonicalFileName(name), + content: inputSources[name] + }); + }); + }); + + after(() => { + shortCasePath = undefined; + testConfigText = undefined; + testConfig = undefined; + inputSources = undefined; + inputTestFiles = undefined; + }); + + ts.forEach(this.compileTargets, ([name, compileCb]) => { + describe(`${name}`, () => { + let sources: ts.Map; + let result: Harness.Compiler.CompilerResult; + before(() => { + this.traces = []; // Clear out any traces from tests which made traces, but didn't specify traceResolution + this.virtualFs = {}; // In case a fourslash test was run last (which doesn't clear FS on end like buildMap does), clear the FS + sources = {}; + ts.copyMap(inputSources, sources); + ts.forEach(testConfig.availableExtensions, ext => this.loadSetIntoFsAt(this.extensions[ext], `/node_modules/${ext}`)); + result = this.buildMap(compileCb, sources, sources, testConfig.compilerOptions, /*shouldError*/false); + }); + + after(() => { + sources = undefined; + result = undefined; + }); + + const errorsTestName = `Correct errors`; + it(errorsTestName, () => { + Harness.Baseline.runBaseline(errorsTestName, `${name}/${shortCasePath}.errors.txt`, () => { + /* tslint:disable:no-null-keyword */ + if (result.errors.length === 0) return null; + /* tslint:enable:no-null-keyword */ + return Harness.Compiler.getErrorBaseline(inputTestFiles, result.errors); + }); + }); + + const traceTestName = `Correct traces`; + it(traceTestName, () => { + if (!(testConfig.compilerOptions.traceResolution)) { + return; + } + Harness.Baseline.runBaseline(traceTestName, `${name}/${shortCasePath}.trace.txt`, (): string => { + return (result.traceResults || []).join("\n"); + }); + }); + + const sourcemapTestName = `Correct sourcemap content`; + it(sourcemapTestName, () => { + if (!(testConfig.compilerOptions.sourceMap || testConfig.compilerOptions.inlineSourceMap)) { + return; + } + Harness.Baseline.runBaseline(sourcemapTestName, `${name}/${shortCasePath}.sourcemap.txt`, () => { + const record = result.getSourceMapRecord(); + if (testConfig.compilerOptions.noEmitOnError && result.errors.length !== 0 && record === undefined) { + // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required. + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ + } + return record; + }); + }); + + const sourcemapOutputTestName = `Correct sourcemap output`; + it(sourcemapOutputTestName, () => { + if (testConfig.compilerOptions.inlineSourceMap) { + if (result.sourceMaps.length > 0) { + throw new Error("No sourcemap files should be generated if inlineSourceMaps was set."); + } + return; + } + else if (!testConfig.compilerOptions.sourceMap) { + return; + } + if (result.sourceMaps.length !== result.files.length) { + throw new Error("Number of sourcemap files should be same as js files."); + } + + Harness.Baseline.runBaseline(sourcemapOutputTestName, `${name}/${shortCasePath}.js.map`, () => { + if (testConfig.compilerOptions.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) { + // We need to return null here or the runBaseLine will actually create a empty file. + // Baselining isn't required here because there is no output. + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ + } + + let sourceMapCode = ""; + for (let i = 0; i < result.sourceMaps.length; i++) { + sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n"; + sourceMapCode += this.getByteOrderMarkText(result.sourceMaps[i]); + sourceMapCode += result.sourceMaps[i].code; + } + + return sourceMapCode; + }); + }); + + const emitOutputTestName = `Correct emit (JS/DTS)`; + it(emitOutputTestName, () => { + if (!ts.forEach(testConfig.inputFiles, name => !ts.endsWith(name, ".d.ts"))) { + return; + } + if (!testConfig.compilerOptions.noEmit && result.files.length === 0 && result.errors.length === 0) { + throw new Error("Expected at least one js file to be emitted or at least one error to be created."); + } + + // check js output + Harness.Baseline.runBaseline(emitOutputTestName, `${name}/${shortCasePath}.js`, () => { + let tsCode = ""; + const tsSources = inputTestFiles; + if (tsSources.length > 1) { + tsCode += "//// [" + caseNameNoExtension + "] ////\r\n\r\n"; + } + for (let i = 0; i < tsSources.length; i++) { + tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n"; + tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : ""); + } + + let jsCode = ""; + for (let i = 0; i < result.files.length; i++) { + jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n"; + jsCode += this.getByteOrderMarkText(result.files[i]); + jsCode += result.files[i].code; + } + + if (result.declFilesCode.length > 0) { + jsCode += "\r\n\r\n"; + for (let i = 0; i < result.declFilesCode.length; i++) { + jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n"; + jsCode += this.getByteOrderMarkText(result.declFilesCode[i]); + jsCode += result.declFilesCode[i].code; + } + } + + if (jsCode.length > 0) { + return tsCode + "\r\n\r\n" + jsCode; + } + else { + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ + } + }); + }); + }); + }); + + it("passes fourslash verification", () => { + if (testConfig.fourslashTest) { + this.virtualFs = {}; + const testFile = `${this.fourslashPath}/${testConfig.fourslashTest}`; + let testFileContents = Harness.IO.readFile(testFile); + testFileContents = testFileContents.replace(`/// `, ""); + const testContent = [`/// `, ""]; + ts.forEach(inputTestFiles, testFile => { + testContent.push(`// @Filename: ${testFile.unitName.substring(1)}`); // Drop leading / + testContent.push(...testFile.content.split("\n").map(s => `////${s}`)); + }); + testContent.push("// @Filename: tsconfig.json"); + testContent.push(`////${JSON.stringify(testConfig.compilerOptions)}`); + testContent.push(testFileContents); + const finishedTestContent = testContent.join("\n"); + + this.loadSetIntoFs(this.virtualLib); + ts.forEach(testConfig.availableExtensions, ext => this.loadSetIntoFsAt(this.extensions[ext], `/node_modules/${ext}`)); + + const adapterFactory = (token: ts.HostCancellationToken) => this.makeLSMockAdapter(ts.getKeys(this.virtualFs), testConfig.compilerOptions, token); + + FourSlash.runFourSlashTestContent(shortCasePath, adapterFactory, finishedTestContent, testFile); + } + }); + }); + } +} \ No newline at end of file diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index a42abbbc60909..14f16eb09f2d6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -242,7 +242,7 @@ namespace FourSlash { } } - constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) { + constructor(private basePath: string, private testType: FourSlashTestType | ((token: ts.HostCancellationToken) => Harness.LanguageService.LanguageServiceAdapter), public testData: FourSlashData) { // Create a new Services Adapter this.cancellationToken = new TestCancellationToken(); const compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); @@ -250,7 +250,13 @@ namespace FourSlash { compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath)); } - const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); + let languageServiceAdapter: Harness.LanguageService.LanguageServiceAdapter; + if (typeof testType === "number") { + languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); + } + else { + languageServiceAdapter = testType(this.cancellationToken); + } this.languageServiceAdapterHost = languageServiceAdapter.getHost(); this.languageService = languageServiceAdapter.getLanguageService(); @@ -2266,7 +2272,7 @@ namespace FourSlash { runFourSlashTestContent(basePath, testType, content, fileName); } - export function runFourSlashTestContent(basePath: string, testType: FourSlashTestType, content: string, fileName: string): void { + export function runFourSlashTestContent(basePath: string, testType: FourSlashTestType | ((token: ts.HostCancellationToken) => Harness.LanguageService.LanguageServiceAdapter), content: string, fileName: string): void { // Parse out the files and their metadata const testData = parseTestData(basePath, content, fileName); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index f27e7e1c1749a..877e807ec1b7f 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1209,6 +1209,11 @@ namespace Harness { return normalized; } + function getDiagnosticCodeString(code: string | number) { + if (typeof code === "number") return `TS${code}`; + return code; + } + export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) { return ts.formatDiagnostics(diagnostics, { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() }); } @@ -1226,7 +1231,7 @@ namespace Harness { .split("\n") .map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s) .filter(s => s.length > 0) - .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); + .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " " + getDiagnosticCodeString(error.code) + ": " + s); errLines.forEach(e => outputLines.push(e)); // do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d7ed04b627f4f..fdd2f6602ecb5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -123,7 +123,7 @@ namespace Harness.LanguageService { } export class LanguageServiceAdapterHost { - protected fileNameToScript: ts.Map = {}; + public fileNameToScript: ts.Map = {}; constructor(protected cancellationToken = DefaultHostCancellationToken.Instance, protected settings = ts.getDefaultCompilerOptions()) { @@ -366,6 +366,9 @@ namespace Harness.LanguageService { getCompilerOptionsDiagnostics(): ts.Diagnostic[] { return unwrapJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); } + getProgramDiagnostics(): ts.Diagnostic[] { + return unwrapJSONCallResult(this.shim.getProgramDiagnostics()); + } getSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { return unwrapJSONCallResult(this.shim.getSyntacticClassifications(fileName, span.start, span.length)); } diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 4b1945f5baa33..942ee516e9476 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -17,6 +17,7 @@ /// /// /// +/// /// /// @@ -58,6 +59,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase { return new RWCRunner(); case "test262": return new Test262BaselineRunner(); + case "extension": + return new ExtensionRunner(); } } @@ -155,6 +158,9 @@ if (testConfigContent !== "") { case "test262": runners.push(new Test262BaselineRunner()); break; + case "extension": + runners.push(new ExtensionRunner()); + break; } } } @@ -176,6 +182,9 @@ if (runners.length === 0) { runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess)); runners.push(new FourSlashRunner(FourSlashTestType.Server)); // runners.push(new GeneratedFourslashRunner()); + + // extension + runners.push(new ExtensionRunner()); } if (taskConfigsFolder) { diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 346382b7a5721..35d345463fde7 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -1,7 +1,7 @@ /// -type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262"; +type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "extension"; type CompilerTestKind = "conformance" | "compiler"; type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; diff --git a/src/server/client.ts b/src/server/client.ts index f04dbd8dc0253..d12c50459b6fe 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -395,6 +395,10 @@ namespace ts.server { } getCompilerOptionsDiagnostics(): Diagnostic[] { + return this.getProgramDiagnostics(); + } + + getProgramDiagnostics(): Diagnostic[] { throw new Error("Not Implemented Yet."); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 6e9adad7f472f..acc12116ecb57 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1150,7 +1150,7 @@ namespace ts.server { info.setFormatOptions(this.getFormatCodeOptions()); this.filenameToScriptInfo[fileName] = info; if (!info.isOpen) { - info.fileWatcher = this.host.watchFile(fileName, _ => { this.watchedFileChanged(fileName); }); + info.fileWatcher = this.host.watchFile && this.host.watchFile(fileName, _ => { this.watchedFileChanged(fileName); }); } } } diff --git a/src/services/services.ts b/src/services/services.ts index ad630fd444e67..c245be0fedca0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1167,6 +1167,8 @@ namespace ts { resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; directoryExists?(directoryName: string): boolean; getDirectories?(directoryName: string): string[]; + + loadExtension?(path: string): any; } // @@ -1179,10 +1181,13 @@ namespace ts { getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; - // TODO: Rename this to getProgramDiagnostics to better indicate that these are any - // diagnostics present for the program level, and not just 'options' diagnostics. + /** + * @deprecated Use getProgramDiagnostics instead. + */ getCompilerOptionsDiagnostics(): Diagnostic[]; + getProgramDiagnostics(): Diagnostic[]; + /** * @deprecated Use getEncodedSyntacticClassifications instead. */ @@ -1246,6 +1251,86 @@ namespace ts { dispose(): void; } + export interface LanguageServiceProvider { + // Overrides + + // A plugin can implement one of the override methods to replace the results that would + // be returned by the TypeScript language service. If a plugin returns a defined result + // (that is, is not undefined) then that result is used instead of invoking the + // corresponding TypeScript method. If multiple plugins are registered, they are + // consulted in the order they are returned from the program. The first defined result + // returned by a plugin is used and no other plugin overrides are consulted. + + getProgramDiagnostics?(): Diagnostic[]; + getSyntacticDiagnostics?(fileName: string): Diagnostic[]; + getSemanticDiagnostics?(fileName: string): Diagnostic[]; + getEncodedSyntacticClassifications?(fileName: string, span: TextSpan): Classifications; + getEncodedSemanticClassifications?(fileName: string, span: TextSpan): Classifications; + getCompletionsAtPosition?(fileName: string, position: number): CompletionInfo; + getCompletionEntryDetails?(fileName: string, position: number, entryName: string): CompletionEntryDetails; + getQuickInfoAtPosition?(fileName: string, position: number): QuickInfo; + getNameOrDottedNameSpan?(fileName: string, startPos: number, endPos: number): TextSpan; + getBreakpointStatementAtPosition?(fileName: string, position: number): TextSpan; + getSignatureHelpItems?(fileName: string, position: number): SignatureHelpItems; + getRenameInfo?(fileName: string, position: number): RenameInfo; + findRenameLocations?(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; + getDefinitionAtPosition?(fileName: string, position: number): DefinitionInfo[]; + getTypeDefinitionAtPosition?(fileName: string, position: number): DefinitionInfo[]; + getReferencesAtPosition?(fileName: string, position: number): ReferenceEntry[]; + findReferences?(fileName: string, position: number): ReferencedSymbol[]; + getDocumentHighlights?(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[]; + getNavigateToItems?(searchValue: string, maxResultCount: number): NavigateToItem[]; + getNavigationBarItems?(fileName: string): NavigationBarItem[]; + getOutliningSpans?(fileName: string): OutliningSpan[]; + getTodoComments?(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; + getBraceMatchingAtPosition?(fileName: string, position: number): TextSpan[]; + getIndentationAtPosition?(fileName: string, position: number, options: EditorOptions): number; + getFormattingEditsForRange?(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[]; + getFormattingEditsForDocument?(fileName: string, options: FormatCodeOptions): TextChange[]; + getFormattingEditsAfterKeystroke?(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[]; + getDocCommentTemplateAtPosition?(fileName: string, position: number): TextInsertion; + + // Filters + + // A plugin can implement one of the filter methods to augment, extend or modify a result + // prior to the host receiving it. The TypeScript language service is invoked and the + // result is passed to the plugin as the value of the previous parameter. If more than one + // plugin is registered, the plugins are consulted in the order they are returned from the + // program. The value passed in as previous is the result returned by the prior plugin. If a + // plugin returns undefined, the result passed in as previous is used and the undefined + // result is ignored. All plugins are consulted before the result is returned to the host. + // If a plugin overrides behavior of the method, no filter methods are consulted. + + getProgramDiagnosticsFilter?(previous: Diagnostic[]): Diagnostic[]; + getSyntacticDiagnosticsFilter?(fileName: string, previous: Diagnostic[]): Diagnostic[]; + getSemanticDiagnosticsFilter?(fileName: string, previous: Diagnostic[]): Diagnostic[]; + getEncodedSyntacticClassificationsFilter?(fileName: string, span: TextSpan, previous: Classifications): Classifications; + getEncodedSemanticClassificationsFilter?(fileName: string, span: TextSpan, previous: Classifications): Classifications; + getCompletionsAtPositionFilter?(fileName: string, position: number, previous: CompletionInfo): CompletionInfo; + getCompletionEntryDetailsFilter?(fileName: string, position: number, entryName: string, previous: CompletionEntryDetails): CompletionEntryDetails; + getQuickInfoAtPositionFilter?(fileName: string, position: number, previous: QuickInfo): QuickInfo; + getNameOrDottedNameSpanFilter?(fileName: string, startPos: number, endPos: number, previous: TextSpan): TextSpan; + getBreakpointStatementAtPositionFilter?(fileName: string, position: number, previous: TextSpan): TextSpan; + getSignatureHelpItemsFilter?(fileName: string, position: number, previous: SignatureHelpItems): SignatureHelpItems; + getRenameInfoFilter?(fileName: string, position: number, previous: RenameInfo): RenameInfo; + findRenameLocationsFilter?(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, previous: RenameLocation[]): RenameLocation[]; + getDefinitionAtPositionFilter?(fileName: string, position: number, previous: DefinitionInfo[]): DefinitionInfo[]; + getTypeDefinitionAtPositionFilter?(fileName: string, position: number, previous: DefinitionInfo[]): DefinitionInfo[]; + getReferencesAtPositionFilter?(fileName: string, position: number, previous: ReferenceEntry[]): ReferenceEntry[]; + findReferencesFilter?(fileName: string, position: number, previous: ReferencedSymbol[]): ReferencedSymbol[]; + getDocumentHighlightsFilter?(fileName: string, position: number, filesToSearch: string[], previous: DocumentHighlights[]): DocumentHighlights[]; + getNavigateToItemsFilter?(searchValue: string, maxResultCount: number, previous: NavigateToItem[]): NavigateToItem[]; + getNavigationBarItemsFilter?(fileName: string, previous: NavigationBarItem[]): NavigationBarItem[]; + getOutliningSpansFilter?(fileName: string, previous: OutliningSpan[]): OutliningSpan[]; + getTodoCommentsFilter?(fileName: string, descriptors: TodoCommentDescriptor[], previous: TodoComment[]): TodoComment[]; + getBraceMatchingAtPositionFilter?(fileName: string, position: number, previous: TextSpan[]): TextSpan[]; + getIndentationAtPositionFilter?(fileName: string, position: number, options: EditorOptions, previous: number): number; + getFormattingEditsForRangeFilter?(fileName: string, start: number, end: number, options: FormatCodeOptions, previous: TextChange[]): TextChange[]; + getFormattingEditsForDocumentFilter?(fileName: string, options: FormatCodeOptions, previous: TextChange[]): TextChange[]; + getFormattingEditsAfterKeystrokeFilter?(fileName: string, position: number, key: string, options: FormatCodeOptions, previous: TextChange[]): TextChange[]; + getDocCommentTemplateAtPositionFilter?(fileName: string, position: number, previous: TextInsertion): TextInsertion; + } + export interface Classifications { spans: number[]; endOfLineState: EndOfLineState; @@ -1826,6 +1911,7 @@ namespace ts { version: string; scriptSnapshot: IScriptSnapshot; scriptKind: ScriptKind; + isRoot: boolean; } interface DocumentRegistryEntry { @@ -1902,7 +1988,7 @@ namespace ts { // Initialize the list with the root file names const rootFileNames = host.getScriptFileNames(); for (const fileName of rootFileNames) { - this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); + this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName), /*isRoot*/true); } // store the compilation settings @@ -1913,7 +1999,7 @@ namespace ts { return this._compilationSettings; } - private createEntry(fileName: string, path: Path) { + private createEntry(fileName: string, path: Path, isRoot: boolean) { let entry: HostFileInformation; const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { @@ -1921,7 +2007,8 @@ namespace ts { hostFileName: fileName, version: this.host.getScriptVersion(fileName), scriptSnapshot: scriptSnapshot, - scriptKind: getScriptKind(fileName, this.host) + scriptKind: getScriptKind(fileName, this.host), + isRoot }; } @@ -1945,14 +2032,14 @@ namespace ts { public getOrCreateEntryByPath(fileName: string, path: Path): HostFileInformation { return this.contains(path) ? this.getEntry(path) - : this.createEntry(fileName, path); + : this.createEntry(fileName, path, /*isRoot*/false); } public getRootFileNames(): string[] { const fileNames: string[] = []; this.fileNameToEntry.forEachValue((path, value) => { - if (value) { + if (value && value.isRoot) { fileNames.push(value.hostFileName); } }); @@ -3019,11 +3106,84 @@ namespace ts { } export function createLanguageService(host: LanguageServiceHost, + documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { + const baseService = createUnextendedLanguageService(host, documentRegistry); + const extensions = baseService.getProgram().getCompilerExtensions()["language-service"]; + const instantiatedExtensions = map(extensions, extension => new extension.ctor({ ts, host, service: baseService, registry: documentRegistry, args: extension.args })); + const extensionCount = instantiatedExtensions && instantiatedExtensions.length; + + function wrap(key: string): Function { + if (extensionCount) { + return (...args: any[]) => { + let result: any; + for (let i = 0; i < extensionCount; i++) { + const extension = instantiatedExtensions[i]; + if ((extension as any)[key]) { + const temp = (extension as any)[key](...args); + if (temp !== undefined) { + result = temp; + break; + } + } + } + result = result !== undefined ? result : (baseService as any)[key](...args); + const filterKey = `${key}Filter`; + for (let i = 0; i < extensionCount; i++) { + const extension = instantiatedExtensions[i]; + if ((extension as any)[filterKey]) { + const temp = (extension as any)[filterKey](...args, result); + if (temp !== undefined) { + result = temp; + } + } + } + return result; + }; + } + return (baseService as any)[key]; + } + + function buildWrappedService(underlyingMembers: Map, wrappedMembers: string[]): LanguageService { + // Add wrapped members to map + forEach(wrappedMembers, member => { + underlyingMembers[member] = wrap(member); + }); + // Map getProgramDiagnostics to deprecated getCompilerOptionsDiagnostics + underlyingMembers["getCompilerOptionsDiagnostics"] = underlyingMembers["getProgramDiagnostics"]; + return underlyingMembers as LanguageService; + } + + return buildWrappedService({ + cleanupSemanticCache: () => baseService.cleanupSemanticCache(), + getSyntacticClassifications: (fileName: string, span: TextSpan) => baseService.getSyntacticClassifications(fileName, span), + getSemanticClassifications: (fileName: string, span: TextSpan) => baseService.getSemanticClassifications(fileName, span), + getOccurrencesAtPosition: (fileName: string, position: number) => baseService.getOccurrencesAtPosition(fileName, position), + isValidBraceCompletionAtPosition: (fileName: string, pos: number, openingBrace: number) => baseService.isValidBraceCompletionAtPosition(fileName, pos, openingBrace), + getEmitOutput: (fileName: string) => baseService.getEmitOutput(fileName), + getProgram: () => baseService.getProgram(), + getNonBoundSourceFile: (fileName: string) => baseService.getNonBoundSourceFile(fileName), + dispose: () => baseService.dispose(), + }, [ + "getSyntacticDiagnostics", "getSemanticDiagnostics", "getProgramDiagnostics", + "getEncodedSyntacticClassifications", "getEncodedSemanticClassifications", "getCompletionsAtPosition", + "getCompletionEntryDetails", "getQuickInfoAtPosition", "getNameOrDottedNameSpan", + "getBreakpointStatementAtPosition", "getSignatureHelpItems", "getRenameInfo", + "findRenameLocations", "getDefinitionAtPosition", "getTypeDefinitionAtPosition", + "getReferencesAtPosition", "findReferences", "getDocumentHighlights", + "getNavigateToItems", "getNavigationBarItems", "getOutliningSpans", + "getTodoComments", "getBraceMatchingAtPosition", "getIndentationAtPosition", + "getFormattingEditsForRange", "getFormattingEditsForDocument", "getFormattingEditsAfterKeystroke", + "getDocCommentTemplateAtPosition" + ]); + } + + export function createUnextendedLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; + let extensionCache: ExtensionCache; let lastProjectVersion: string; const useCaseSensitivefileNames = false; @@ -3112,11 +3272,13 @@ namespace ts { getCurrentDirectory: () => currentDirectory, fileExists: (fileName): boolean => { // stub missing host functionality + Debug.assert(!!hostCache, "LS CompilerHost may not persist beyond the execution of a synchronize call"); Debug.assert(!host.resolveModuleNames || !host.resolveTypeReferenceDirectives); return hostCache.getOrCreateEntry(fileName) !== undefined; }, readFile: (fileName): string => { // stub missing host functionality + Debug.assert(!!hostCache, "LS CompilerHost may not persist beyond the execution of a synchronize call"); const entry = hostCache.getOrCreateEntry(fileName); return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); }, @@ -3125,6 +3287,9 @@ namespace ts { }, getDirectories: path => { return host.getDirectories ? host.getDirectories(path) : []; + }, + loadExtension: path => { + return host.loadExtension ? host.loadExtension(path) : undefined; } }; if (host.trace) { @@ -3140,8 +3305,13 @@ namespace ts { }; } + const changesInCompilationSettingsAffectExtensions = oldSettings && !deepEqual(oldSettings.extensions, newSettings.extensions); + if (!extensionCache || changesInCompilationSettingsAffectExtensions) { + extensionCache = createExtensionCache(newSettings, compilerHost); + } + const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); - const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); + const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program, extensionCache); // Release any files we have acquired in the old program but are // not part of the new program. @@ -3302,7 +3472,7 @@ namespace ts { return concatenate(semanticDiagnostics, declarationDiagnostics); } - function getCompilerOptionsDiagnostics() { + function getProgramDiagnostics() { synchronizeHostData(); return program.getOptionsDiagnostics(cancellationToken).concat( program.getGlobalDiagnostics(cancellationToken)); @@ -8263,7 +8433,8 @@ namespace ts { cleanupSemanticCache, getSyntacticDiagnostics, getSemanticDiagnostics, - getCompilerOptionsDiagnostics, + getCompilerOptionsDiagnostics: getProgramDiagnostics, + getProgramDiagnostics, getSyntacticClassifications, getSemanticClassifications, getEncodedSyntacticClassifications, diff --git a/src/services/shims.ts b/src/services/shims.ts index 271d6f2d6e205..e3f5c68544125 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -119,6 +119,7 @@ namespace ts { getSyntacticDiagnostics(fileName: string): string; getSemanticDiagnostics(fileName: string): string; getCompilerOptionsDiagnostics(): string; + getProgramDiagnostics(): string; getSyntacticClassifications(fileName: string, start: number, length: number): string; getSemanticClassifications(fileName: string, start: number, length: number): string; @@ -547,11 +548,11 @@ namespace ts { } } - export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; code: number; }[] { + export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; code: number | string; }[] { return diagnostics.map(d => realizeDiagnostic(d, newLine)); } - function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; code: number; } { + function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; code: number | string; } { return { message: flattenDiagnosticMessageText(diagnostic.messageText, newLine), start: diagnostic.start, @@ -684,6 +685,15 @@ namespace ts { }); } + public getProgramDiagnostics(): string { + return this.forwardJSONCall( + "getProgramDiagnostics()", + () => { + const diagnostics = this.languageService.getProgramDiagnostics(); + return this.realizeDiagnostics(diagnostics); + }); + } + /// QUICKINFO /** diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index cfeb7c2fcd582..4167f209f3d18 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -25,6 +25,7 @@ "../compiler/declarationEmitter.ts", "../compiler/emitter.ts", "../compiler/program.ts", + "../compiler/extensions.ts", "../compiler/commandLineParser.ts", "../compiler/diagnosticInformationMap.generated.ts", "breakpoints.ts", diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-add-program-diagnostics.js b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-add-program-diagnostics.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-add-program-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.errors.txt b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.errors.txt new file mode 100644 index 0000000000000..5402510857df8 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.errors.txt @@ -0,0 +1,10 @@ +/hello-error.ts(1,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +/hello-error.ts(1,31): error TS1109: Expression expected. + + +==== /hello-error.ts (2 errors) ==== + console.log("Hello, error!") - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.js b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.js new file mode 100644 index 0000000000000..10802294f21ba --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-chain-services.js @@ -0,0 +1,5 @@ +//// [hello-error.ts] +console.log("Hello, error!") - + +//// [hello-error.js] +console.log("Hello, error!") - ; diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.errors.txt b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.errors.txt new file mode 100644 index 0000000000000..c268502890d90 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.errors.txt @@ -0,0 +1,653 @@ +/atotc.ts(1,1): error TS2304: Cannot find name 'It'. +/atotc.ts(1,4): error TS1005: ';' expected. +/atotc.ts(1,4): error TS2304: Cannot find name 'was'. +/atotc.ts(1,8): error TS1005: ';' expected. +/atotc.ts(1,8): error TS2304: Cannot find name 'the'. +/atotc.ts(1,12): error TS1005: ';' expected. +/atotc.ts(1,12): error TS2304: Cannot find name 'best'. +/atotc.ts(1,17): error TS1005: ';' expected. +/atotc.ts(1,17): error TS2304: Cannot find name 'of'. +/atotc.ts(1,20): error TS1005: ';' expected. +/atotc.ts(1,20): error TS2304: Cannot find name 'times'. +/atotc.ts(1,27): error TS2304: Cannot find name 'it'. +/atotc.ts(1,30): error TS1005: ';' expected. +/atotc.ts(1,30): error TS2304: Cannot find name 'was'. +/atotc.ts(1,34): error TS1005: ';' expected. +/atotc.ts(1,34): error TS2304: Cannot find name 'the'. +/atotc.ts(1,38): error TS1005: ';' expected. +/atotc.ts(1,38): error TS2304: Cannot find name 'worst'. +/atotc.ts(1,44): error TS1005: ';' expected. +/atotc.ts(1,44): error TS2304: Cannot find name 'of'. +/atotc.ts(1,47): error TS1005: ';' expected. +/atotc.ts(1,47): error TS2304: Cannot find name 'times'. +/atotc.ts(2,1): error TS2304: Cannot find name 'it'. +/atotc.ts(2,4): error TS1005: ';' expected. +/atotc.ts(2,4): error TS2304: Cannot find name 'was'. +/atotc.ts(2,8): error TS1005: ';' expected. +/atotc.ts(2,8): error TS2304: Cannot find name 'the'. +/atotc.ts(2,12): error TS1005: ';' expected. +/atotc.ts(2,12): error TS2304: Cannot find name 'age'. +/atotc.ts(2,16): error TS1005: ';' expected. +/atotc.ts(2,16): error TS2304: Cannot find name 'of'. +/atotc.ts(2,19): error TS1005: ';' expected. +/atotc.ts(2,19): error TS2304: Cannot find name 'wisdom'. +/atotc.ts(2,27): error TS2304: Cannot find name 'it'. +/atotc.ts(2,30): error TS1005: ';' expected. +/atotc.ts(2,30): error TS2304: Cannot find name 'was'. +/atotc.ts(2,34): error TS1005: ';' expected. +/atotc.ts(2,34): error TS2304: Cannot find name 'the'. +/atotc.ts(2,38): error TS1005: ';' expected. +/atotc.ts(2,38): error TS2304: Cannot find name 'age'. +/atotc.ts(2,42): error TS1005: ';' expected. +/atotc.ts(2,42): error TS2304: Cannot find name 'of'. +/atotc.ts(2,45): error TS1005: ';' expected. +/atotc.ts(2,45): error TS2304: Cannot find name 'foolishness'. +/atotc.ts(3,1): error TS2304: Cannot find name 'it'. +/atotc.ts(3,4): error TS1005: ';' expected. +/atotc.ts(3,4): error TS2304: Cannot find name 'was'. +/atotc.ts(3,8): error TS1005: ';' expected. +/atotc.ts(3,8): error TS2304: Cannot find name 'the'. +/atotc.ts(3,12): error TS1005: ';' expected. +/atotc.ts(3,12): error TS2304: Cannot find name 'epoch'. +/atotc.ts(3,18): error TS1005: ';' expected. +/atotc.ts(3,18): error TS2304: Cannot find name 'of'. +/atotc.ts(3,21): error TS1005: ';' expected. +/atotc.ts(3,21): error TS2304: Cannot find name 'belief'. +/atotc.ts(3,29): error TS2304: Cannot find name 'it'. +/atotc.ts(3,32): error TS1005: ';' expected. +/atotc.ts(3,32): error TS2304: Cannot find name 'was'. +/atotc.ts(3,36): error TS1005: ';' expected. +/atotc.ts(3,36): error TS2304: Cannot find name 'the'. +/atotc.ts(3,40): error TS1005: ';' expected. +/atotc.ts(3,40): error TS2304: Cannot find name 'epoch'. +/atotc.ts(3,46): error TS1005: ';' expected. +/atotc.ts(3,46): error TS2304: Cannot find name 'of'. +/atotc.ts(3,49): error TS1005: ';' expected. +/atotc.ts(3,49): error TS2304: Cannot find name 'incredulity'. +/atotc.ts(4,1): error TS2304: Cannot find name 'it'. +/atotc.ts(4,4): error TS1005: ';' expected. +/atotc.ts(4,4): error TS2304: Cannot find name 'was'. +/atotc.ts(4,8): error TS1005: ';' expected. +/atotc.ts(4,8): error TS2304: Cannot find name 'the'. +/atotc.ts(4,12): error TS1005: ';' expected. +/atotc.ts(4,12): error TS2304: Cannot find name 'season'. +/atotc.ts(4,19): error TS1005: ';' expected. +/atotc.ts(4,19): error TS2304: Cannot find name 'of'. +/atotc.ts(4,22): error TS1005: ';' expected. +/atotc.ts(4,22): error TS2304: Cannot find name 'Light'. +/atotc.ts(4,29): error TS2304: Cannot find name 'it'. +/atotc.ts(4,32): error TS1005: ';' expected. +/atotc.ts(4,32): error TS2304: Cannot find name 'was'. +/atotc.ts(4,36): error TS1005: ';' expected. +/atotc.ts(4,36): error TS2304: Cannot find name 'the'. +/atotc.ts(4,40): error TS1005: ';' expected. +/atotc.ts(4,40): error TS2304: Cannot find name 'season'. +/atotc.ts(4,47): error TS1005: ';' expected. +/atotc.ts(4,47): error TS2304: Cannot find name 'of'. +/atotc.ts(4,50): error TS1005: ';' expected. +/atotc.ts(4,50): error TS2304: Cannot find name 'Darkness'. +/atotc.ts(5,1): error TS2304: Cannot find name 'it'. +/atotc.ts(5,4): error TS1005: ';' expected. +/atotc.ts(5,4): error TS2304: Cannot find name 'was'. +/atotc.ts(5,8): error TS1005: ';' expected. +/atotc.ts(5,8): error TS2304: Cannot find name 'the'. +/atotc.ts(5,12): error TS1005: ';' expected. +/atotc.ts(5,12): error TS2304: Cannot find name 'spring'. +/atotc.ts(5,19): error TS1005: ';' expected. +/atotc.ts(5,19): error TS2304: Cannot find name 'of'. +/atotc.ts(5,22): error TS1005: ';' expected. +/atotc.ts(5,22): error TS2304: Cannot find name 'hope'. +/atotc.ts(5,28): error TS2304: Cannot find name 'it'. +/atotc.ts(5,31): error TS1005: ';' expected. +/atotc.ts(5,31): error TS2304: Cannot find name 'was'. +/atotc.ts(5,35): error TS1005: ';' expected. +/atotc.ts(5,35): error TS2304: Cannot find name 'the'. +/atotc.ts(5,39): error TS1005: ';' expected. +/atotc.ts(5,39): error TS2304: Cannot find name 'winter'. +/atotc.ts(5,46): error TS1005: ';' expected. +/atotc.ts(5,46): error TS2304: Cannot find name 'of'. +/atotc.ts(5,49): error TS1005: ';' expected. +/atotc.ts(5,49): error TS2304: Cannot find name 'despair'. +/atotc.ts(6,1): error TS2304: Cannot find name 'we'. +/atotc.ts(6,4): error TS1005: ';' expected. +/atotc.ts(6,4): error TS2304: Cannot find name 'had'. +/atotc.ts(6,8): error TS1005: ';' expected. +/atotc.ts(6,8): error TS2304: Cannot find name 'everything'. +/atotc.ts(6,19): error TS1005: ';' expected. +/atotc.ts(6,19): error TS2304: Cannot find name 'before'. +/atotc.ts(6,26): error TS1005: ';' expected. +/atotc.ts(6,26): error TS2304: Cannot find name 'us'. +/atotc.ts(6,30): error TS2304: Cannot find name 'we'. +/atotc.ts(6,33): error TS1005: ';' expected. +/atotc.ts(6,33): error TS2304: Cannot find name 'had'. +/atotc.ts(6,37): error TS1005: ';' expected. +/atotc.ts(6,37): error TS2304: Cannot find name 'nothing'. +/atotc.ts(6,45): error TS1005: ';' expected. +/atotc.ts(6,45): error TS2304: Cannot find name 'before'. +/atotc.ts(6,52): error TS1005: ';' expected. +/atotc.ts(6,52): error TS2304: Cannot find name 'us'. +/atotc.ts(7,1): error TS2304: Cannot find name 'we'. +/atotc.ts(7,4): error TS1005: ';' expected. +/atotc.ts(7,4): error TS2304: Cannot find name 'were'. +/atotc.ts(7,9): error TS1005: ';' expected. +/atotc.ts(7,9): error TS2304: Cannot find name 'all'. +/atotc.ts(7,13): error TS1005: ';' expected. +/atotc.ts(7,13): error TS2304: Cannot find name 'going'. +/atotc.ts(7,19): error TS1005: ';' expected. +/atotc.ts(7,19): error TS2304: Cannot find name 'direct'. +/atotc.ts(7,26): error TS1005: ';' expected. +/atotc.ts(7,26): error TS2304: Cannot find name 'to'. +/atotc.ts(7,29): error TS1005: ';' expected. +/atotc.ts(7,29): error TS2304: Cannot find name 'Heaven'. +/atotc.ts(7,37): error TS2304: Cannot find name 'we'. +/atotc.ts(7,40): error TS1005: ';' expected. +/atotc.ts(7,40): error TS2304: Cannot find name 'were'. +/atotc.ts(7,45): error TS1005: ';' expected. +/atotc.ts(7,45): error TS2304: Cannot find name 'all'. +/atotc.ts(7,49): error TS1005: ';' expected. +/atotc.ts(7,49): error TS2304: Cannot find name 'going'. +/atotc.ts(7,55): error TS1005: ';' expected. +/atotc.ts(7,55): error TS2304: Cannot find name 'direct'. +/atotc.ts(8,1): error TS2304: Cannot find name 'the'. +/atotc.ts(8,5): error TS1005: ';' expected. +/atotc.ts(8,5): error TS2304: Cannot find name 'other'. +/atotc.ts(8,11): error TS1005: ';' expected. +/atotc.ts(8,11): error TS2304: Cannot find name 'way'. +/atotc.ts(8,19): error TS2304: Cannot find name 'short'. +/atotc.ts(8,26): error TS2304: Cannot find name 'the'. +/atotc.ts(8,30): error TS1005: ';' expected. +/atotc.ts(8,30): error TS2304: Cannot find name 'period'. +/atotc.ts(8,37): error TS1005: ';' expected. +/atotc.ts(8,37): error TS2304: Cannot find name 'was'. +/atotc.ts(8,41): error TS1005: ';' expected. +/atotc.ts(8,41): error TS2304: Cannot find name 'so'. +/atotc.ts(8,44): error TS1005: ';' expected. +/atotc.ts(8,44): error TS2304: Cannot find name 'far'. +/atotc.ts(8,48): error TS1005: ';' expected. +/atotc.ts(8,48): error TS2304: Cannot find name 'like'. +/atotc.ts(8,53): error TS1005: ';' expected. +/atotc.ts(8,53): error TS2304: Cannot find name 'the'. +/atotc.ts(8,57): error TS1005: ';' expected. +/atotc.ts(8,57): error TS2304: Cannot find name 'present'. +/atotc.ts(9,1): error TS2304: Cannot find name 'period'. +/atotc.ts(9,9): error TS2304: Cannot find name 'that'. +/atotc.ts(9,14): error TS1005: ';' expected. +/atotc.ts(9,14): error TS2304: Cannot find name 'some'. +/atotc.ts(9,19): error TS1005: ';' expected. +/atotc.ts(9,19): error TS2304: Cannot find name 'of'. +/atotc.ts(9,22): error TS1005: ';' expected. +/atotc.ts(9,22): error TS2304: Cannot find name 'its'. +/atotc.ts(9,26): error TS1005: ';' expected. +/atotc.ts(9,26): error TS2304: Cannot find name 'noisiest'. +/atotc.ts(9,35): error TS1005: ';' expected. +/atotc.ts(9,35): error TS2304: Cannot find name 'authorities'. +/atotc.ts(9,47): error TS1005: ';' expected. +/atotc.ts(9,47): error TS2304: Cannot find name 'insisted'. +/atotc.ts(9,56): error TS1005: ';' expected. +/atotc.ts(9,56): error TS2304: Cannot find name 'on'. +/atotc.ts(9,59): error TS1005: ';' expected. +/atotc.ts(9,59): error TS2304: Cannot find name 'its'. +/atotc.ts(10,1): error TS2304: Cannot find name 'being'. +/atotc.ts(10,7): error TS1005: ';' expected. +/atotc.ts(10,7): error TS2304: Cannot find name 'received'. +/atotc.ts(10,17): error TS1109: Expression expected. +/atotc.ts(10,21): error TS1005: '(' expected. +/atotc.ts(10,21): error TS2304: Cannot find name 'good'. +/atotc.ts(10,26): error TS1005: ';' expected. +/atotc.ts(10,26): error TS2304: Cannot find name 'or'. +/atotc.ts(10,29): error TS1005: ';' expected. +/atotc.ts(10,33): error TS1005: '(' expected. +/atotc.ts(10,33): error TS2304: Cannot find name 'evil'. +/atotc.ts(10,33): error TS2406: Invalid left-hand side in 'for...in' statement. +/atotc.ts(10,39): error TS1109: Expression expected. +/atotc.ts(10,42): error TS2304: Cannot find name 'the'. +/atotc.ts(10,46): error TS1005: ')' expected. +/atotc.ts(10,46): error TS2304: Cannot find name 'superlative'. +/atotc.ts(10,58): error TS1005: ';' expected. +/atotc.ts(10,58): error TS2304: Cannot find name 'degree'. +/atotc.ts(11,1): error TS2304: Cannot find name 'of'. +/atotc.ts(11,4): error TS1005: ';' expected. +/atotc.ts(11,4): error TS2304: Cannot find name 'comparison'. +/atotc.ts(11,15): error TS1005: ';' expected. +/atotc.ts(11,15): error TS2304: Cannot find name 'only'. +/atotc.ts(11,20): error TS1003: Identifier expected. + + +==== /atotc.ts (213 errors) ==== + It was the best of times, it was the worst of times, + ~~ +!!! error TS2304: Cannot find name 'It'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'best'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'times'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'worst'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'times'. + it was the age of wisdom, it was the age of foolishness, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'age'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'wisdom'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'age'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'foolishness'. + it was the epoch of belief, it was the epoch of incredulity, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'epoch'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'belief'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'epoch'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'incredulity'. + it was the season of Light, it was the season of Darkness, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'season'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'Light'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'season'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Darkness'. + it was the spring of hope, it was the winter of despair, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'spring'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'hope'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'winter'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'despair'. + we had everything before us, we had nothing before us, + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'had'. + ~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~ +!!! error TS2304: Cannot find name 'everything'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'before'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'us'. + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'had'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'nothing'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'before'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'us'. + we were all going direct to Heaven, we were all going direct + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'were'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'all'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'going'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'direct'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'to'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'Heaven'. + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'were'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'all'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'going'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'direct'. + the other way--in short, the period was so far like the present + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'other'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'way'. + ~~~~~ +!!! error TS2304: Cannot find name 'short'. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'period'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'so'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'far'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'like'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'present'. + period, that some of its noisiest authorities insisted on its + ~~~~~~ +!!! error TS2304: Cannot find name 'period'. + ~~~~ +!!! error TS2304: Cannot find name 'that'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'some'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'its'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'noisiest'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'authorities'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'insisted'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'on'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'its'. + being received, for good or for evil, in the superlative degree + ~~~~~ +!!! error TS2304: Cannot find name 'being'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'received'. + ~~~ +!!! error TS1109: Expression expected. + ~~~~ +!!! error TS1005: '(' expected. + ~~~~ +!!! error TS2304: Cannot find name 'good'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'or'. + ~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS1005: '(' expected. + ~~~~ +!!! error TS2304: Cannot find name 'evil'. + ~~~~~ +!!! error TS2406: Invalid left-hand side in 'for...in' statement. + ~~ +!!! error TS1109: Expression expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~~~~~~ +!!! error TS1005: ')' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'superlative'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'degree'. + of comparison only. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~ +!!! error TS2304: Cannot find name 'comparison'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'only'. + +!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.js b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.js new file mode 100644 index 0000000000000..30c1de3575183 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-all-functions.js @@ -0,0 +1,117 @@ +//// [atotc.ts] +It was the best of times, it was the worst of times, +it was the age of wisdom, it was the age of foolishness, +it was the epoch of belief, it was the epoch of incredulity, +it was the season of Light, it was the season of Darkness, +it was the spring of hope, it was the winter of despair, +we had everything before us, we had nothing before us, +we were all going direct to Heaven, we were all going direct +the other way--in short, the period was so far like the present +period, that some of its noisiest authorities insisted on its +being received, for good or for evil, in the superlative degree +of comparison only. + +//// [atotc.js] +It; +was; +the; +best; +of; +times, it; +was; +the; +worst; +of; +times, + it; +was; +the; +age; +of; +wisdom, it; +was; +the; +age; +of; +foolishness, + it; +was; +the; +epoch; +of; +belief, it; +was; +the; +epoch; +of; +incredulity, + it; +was; +the; +season; +of; +Light, it; +was; +the; +season; +of; +Darkness, + it; +was; +the; +spring; +of; +hope, it; +was; +the; +winter; +of; +despair, + we; +had; +everything; +before; +us, we; +had; +nothing; +before; +us, + we; +were; +all; +going; +direct; +to; +Heaven, we; +were; +all; +going; +direct; +the; +other; +way-- in short, the; +period; +was; +so; +far; +like; +the; +present; +period, that; +some; +of; +its; +noisiest; +authorities; +insisted; +on; +its; +being; +received, ; +for (good; or; ) + for (evil, in the) + superlative; +degree; +of; +comparison; +only.; diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.errors.txt b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.errors.txt new file mode 100644 index 0000000000000..5402510857df8 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.errors.txt @@ -0,0 +1,10 @@ +/hello-error.ts(1,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +/hello-error.ts(1,31): error TS1109: Expression expected. + + +==== /hello-error.ts (2 errors) ==== + console.log("Hello, error!") - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.js b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.js new file mode 100644 index 0000000000000..10802294f21ba --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-filter-passthru.js @@ -0,0 +1,5 @@ +//// [hello-error.ts] +console.log("Hello, error!") - + +//// [hello-error.js] +console.log("Hello, error!") - ; diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.errors.txt b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.errors.txt new file mode 100644 index 0000000000000..c268502890d90 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.errors.txt @@ -0,0 +1,653 @@ +/atotc.ts(1,1): error TS2304: Cannot find name 'It'. +/atotc.ts(1,4): error TS1005: ';' expected. +/atotc.ts(1,4): error TS2304: Cannot find name 'was'. +/atotc.ts(1,8): error TS1005: ';' expected. +/atotc.ts(1,8): error TS2304: Cannot find name 'the'. +/atotc.ts(1,12): error TS1005: ';' expected. +/atotc.ts(1,12): error TS2304: Cannot find name 'best'. +/atotc.ts(1,17): error TS1005: ';' expected. +/atotc.ts(1,17): error TS2304: Cannot find name 'of'. +/atotc.ts(1,20): error TS1005: ';' expected. +/atotc.ts(1,20): error TS2304: Cannot find name 'times'. +/atotc.ts(1,27): error TS2304: Cannot find name 'it'. +/atotc.ts(1,30): error TS1005: ';' expected. +/atotc.ts(1,30): error TS2304: Cannot find name 'was'. +/atotc.ts(1,34): error TS1005: ';' expected. +/atotc.ts(1,34): error TS2304: Cannot find name 'the'. +/atotc.ts(1,38): error TS1005: ';' expected. +/atotc.ts(1,38): error TS2304: Cannot find name 'worst'. +/atotc.ts(1,44): error TS1005: ';' expected. +/atotc.ts(1,44): error TS2304: Cannot find name 'of'. +/atotc.ts(1,47): error TS1005: ';' expected. +/atotc.ts(1,47): error TS2304: Cannot find name 'times'. +/atotc.ts(2,1): error TS2304: Cannot find name 'it'. +/atotc.ts(2,4): error TS1005: ';' expected. +/atotc.ts(2,4): error TS2304: Cannot find name 'was'. +/atotc.ts(2,8): error TS1005: ';' expected. +/atotc.ts(2,8): error TS2304: Cannot find name 'the'. +/atotc.ts(2,12): error TS1005: ';' expected. +/atotc.ts(2,12): error TS2304: Cannot find name 'age'. +/atotc.ts(2,16): error TS1005: ';' expected. +/atotc.ts(2,16): error TS2304: Cannot find name 'of'. +/atotc.ts(2,19): error TS1005: ';' expected. +/atotc.ts(2,19): error TS2304: Cannot find name 'wisdom'. +/atotc.ts(2,27): error TS2304: Cannot find name 'it'. +/atotc.ts(2,30): error TS1005: ';' expected. +/atotc.ts(2,30): error TS2304: Cannot find name 'was'. +/atotc.ts(2,34): error TS1005: ';' expected. +/atotc.ts(2,34): error TS2304: Cannot find name 'the'. +/atotc.ts(2,38): error TS1005: ';' expected. +/atotc.ts(2,38): error TS2304: Cannot find name 'age'. +/atotc.ts(2,42): error TS1005: ';' expected. +/atotc.ts(2,42): error TS2304: Cannot find name 'of'. +/atotc.ts(2,45): error TS1005: ';' expected. +/atotc.ts(2,45): error TS2304: Cannot find name 'foolishness'. +/atotc.ts(3,1): error TS2304: Cannot find name 'it'. +/atotc.ts(3,4): error TS1005: ';' expected. +/atotc.ts(3,4): error TS2304: Cannot find name 'was'. +/atotc.ts(3,8): error TS1005: ';' expected. +/atotc.ts(3,8): error TS2304: Cannot find name 'the'. +/atotc.ts(3,12): error TS1005: ';' expected. +/atotc.ts(3,12): error TS2304: Cannot find name 'epoch'. +/atotc.ts(3,18): error TS1005: ';' expected. +/atotc.ts(3,18): error TS2304: Cannot find name 'of'. +/atotc.ts(3,21): error TS1005: ';' expected. +/atotc.ts(3,21): error TS2304: Cannot find name 'belief'. +/atotc.ts(3,29): error TS2304: Cannot find name 'it'. +/atotc.ts(3,32): error TS1005: ';' expected. +/atotc.ts(3,32): error TS2304: Cannot find name 'was'. +/atotc.ts(3,36): error TS1005: ';' expected. +/atotc.ts(3,36): error TS2304: Cannot find name 'the'. +/atotc.ts(3,40): error TS1005: ';' expected. +/atotc.ts(3,40): error TS2304: Cannot find name 'epoch'. +/atotc.ts(3,46): error TS1005: ';' expected. +/atotc.ts(3,46): error TS2304: Cannot find name 'of'. +/atotc.ts(3,49): error TS1005: ';' expected. +/atotc.ts(3,49): error TS2304: Cannot find name 'incredulity'. +/atotc.ts(4,1): error TS2304: Cannot find name 'it'. +/atotc.ts(4,4): error TS1005: ';' expected. +/atotc.ts(4,4): error TS2304: Cannot find name 'was'. +/atotc.ts(4,8): error TS1005: ';' expected. +/atotc.ts(4,8): error TS2304: Cannot find name 'the'. +/atotc.ts(4,12): error TS1005: ';' expected. +/atotc.ts(4,12): error TS2304: Cannot find name 'season'. +/atotc.ts(4,19): error TS1005: ';' expected. +/atotc.ts(4,19): error TS2304: Cannot find name 'of'. +/atotc.ts(4,22): error TS1005: ';' expected. +/atotc.ts(4,22): error TS2304: Cannot find name 'Light'. +/atotc.ts(4,29): error TS2304: Cannot find name 'it'. +/atotc.ts(4,32): error TS1005: ';' expected. +/atotc.ts(4,32): error TS2304: Cannot find name 'was'. +/atotc.ts(4,36): error TS1005: ';' expected. +/atotc.ts(4,36): error TS2304: Cannot find name 'the'. +/atotc.ts(4,40): error TS1005: ';' expected. +/atotc.ts(4,40): error TS2304: Cannot find name 'season'. +/atotc.ts(4,47): error TS1005: ';' expected. +/atotc.ts(4,47): error TS2304: Cannot find name 'of'. +/atotc.ts(4,50): error TS1005: ';' expected. +/atotc.ts(4,50): error TS2304: Cannot find name 'Darkness'. +/atotc.ts(5,1): error TS2304: Cannot find name 'it'. +/atotc.ts(5,4): error TS1005: ';' expected. +/atotc.ts(5,4): error TS2304: Cannot find name 'was'. +/atotc.ts(5,8): error TS1005: ';' expected. +/atotc.ts(5,8): error TS2304: Cannot find name 'the'. +/atotc.ts(5,12): error TS1005: ';' expected. +/atotc.ts(5,12): error TS2304: Cannot find name 'spring'. +/atotc.ts(5,19): error TS1005: ';' expected. +/atotc.ts(5,19): error TS2304: Cannot find name 'of'. +/atotc.ts(5,22): error TS1005: ';' expected. +/atotc.ts(5,22): error TS2304: Cannot find name 'hope'. +/atotc.ts(5,28): error TS2304: Cannot find name 'it'. +/atotc.ts(5,31): error TS1005: ';' expected. +/atotc.ts(5,31): error TS2304: Cannot find name 'was'. +/atotc.ts(5,35): error TS1005: ';' expected. +/atotc.ts(5,35): error TS2304: Cannot find name 'the'. +/atotc.ts(5,39): error TS1005: ';' expected. +/atotc.ts(5,39): error TS2304: Cannot find name 'winter'. +/atotc.ts(5,46): error TS1005: ';' expected. +/atotc.ts(5,46): error TS2304: Cannot find name 'of'. +/atotc.ts(5,49): error TS1005: ';' expected. +/atotc.ts(5,49): error TS2304: Cannot find name 'despair'. +/atotc.ts(6,1): error TS2304: Cannot find name 'we'. +/atotc.ts(6,4): error TS1005: ';' expected. +/atotc.ts(6,4): error TS2304: Cannot find name 'had'. +/atotc.ts(6,8): error TS1005: ';' expected. +/atotc.ts(6,8): error TS2304: Cannot find name 'everything'. +/atotc.ts(6,19): error TS1005: ';' expected. +/atotc.ts(6,19): error TS2304: Cannot find name 'before'. +/atotc.ts(6,26): error TS1005: ';' expected. +/atotc.ts(6,26): error TS2304: Cannot find name 'us'. +/atotc.ts(6,30): error TS2304: Cannot find name 'we'. +/atotc.ts(6,33): error TS1005: ';' expected. +/atotc.ts(6,33): error TS2304: Cannot find name 'had'. +/atotc.ts(6,37): error TS1005: ';' expected. +/atotc.ts(6,37): error TS2304: Cannot find name 'nothing'. +/atotc.ts(6,45): error TS1005: ';' expected. +/atotc.ts(6,45): error TS2304: Cannot find name 'before'. +/atotc.ts(6,52): error TS1005: ';' expected. +/atotc.ts(6,52): error TS2304: Cannot find name 'us'. +/atotc.ts(7,1): error TS2304: Cannot find name 'we'. +/atotc.ts(7,4): error TS1005: ';' expected. +/atotc.ts(7,4): error TS2304: Cannot find name 'were'. +/atotc.ts(7,9): error TS1005: ';' expected. +/atotc.ts(7,9): error TS2304: Cannot find name 'all'. +/atotc.ts(7,13): error TS1005: ';' expected. +/atotc.ts(7,13): error TS2304: Cannot find name 'going'. +/atotc.ts(7,19): error TS1005: ';' expected. +/atotc.ts(7,19): error TS2304: Cannot find name 'direct'. +/atotc.ts(7,26): error TS1005: ';' expected. +/atotc.ts(7,26): error TS2304: Cannot find name 'to'. +/atotc.ts(7,29): error TS1005: ';' expected. +/atotc.ts(7,29): error TS2304: Cannot find name 'Heaven'. +/atotc.ts(7,37): error TS2304: Cannot find name 'we'. +/atotc.ts(7,40): error TS1005: ';' expected. +/atotc.ts(7,40): error TS2304: Cannot find name 'were'. +/atotc.ts(7,45): error TS1005: ';' expected. +/atotc.ts(7,45): error TS2304: Cannot find name 'all'. +/atotc.ts(7,49): error TS1005: ';' expected. +/atotc.ts(7,49): error TS2304: Cannot find name 'going'. +/atotc.ts(7,55): error TS1005: ';' expected. +/atotc.ts(7,55): error TS2304: Cannot find name 'direct'. +/atotc.ts(8,1): error TS2304: Cannot find name 'the'. +/atotc.ts(8,5): error TS1005: ';' expected. +/atotc.ts(8,5): error TS2304: Cannot find name 'other'. +/atotc.ts(8,11): error TS1005: ';' expected. +/atotc.ts(8,11): error TS2304: Cannot find name 'way'. +/atotc.ts(8,19): error TS2304: Cannot find name 'short'. +/atotc.ts(8,26): error TS2304: Cannot find name 'the'. +/atotc.ts(8,30): error TS1005: ';' expected. +/atotc.ts(8,30): error TS2304: Cannot find name 'period'. +/atotc.ts(8,37): error TS1005: ';' expected. +/atotc.ts(8,37): error TS2304: Cannot find name 'was'. +/atotc.ts(8,41): error TS1005: ';' expected. +/atotc.ts(8,41): error TS2304: Cannot find name 'so'. +/atotc.ts(8,44): error TS1005: ';' expected. +/atotc.ts(8,44): error TS2304: Cannot find name 'far'. +/atotc.ts(8,48): error TS1005: ';' expected. +/atotc.ts(8,48): error TS2304: Cannot find name 'like'. +/atotc.ts(8,53): error TS1005: ';' expected. +/atotc.ts(8,53): error TS2304: Cannot find name 'the'. +/atotc.ts(8,57): error TS1005: ';' expected. +/atotc.ts(8,57): error TS2304: Cannot find name 'present'. +/atotc.ts(9,1): error TS2304: Cannot find name 'period'. +/atotc.ts(9,9): error TS2304: Cannot find name 'that'. +/atotc.ts(9,14): error TS1005: ';' expected. +/atotc.ts(9,14): error TS2304: Cannot find name 'some'. +/atotc.ts(9,19): error TS1005: ';' expected. +/atotc.ts(9,19): error TS2304: Cannot find name 'of'. +/atotc.ts(9,22): error TS1005: ';' expected. +/atotc.ts(9,22): error TS2304: Cannot find name 'its'. +/atotc.ts(9,26): error TS1005: ';' expected. +/atotc.ts(9,26): error TS2304: Cannot find name 'noisiest'. +/atotc.ts(9,35): error TS1005: ';' expected. +/atotc.ts(9,35): error TS2304: Cannot find name 'authorities'. +/atotc.ts(9,47): error TS1005: ';' expected. +/atotc.ts(9,47): error TS2304: Cannot find name 'insisted'. +/atotc.ts(9,56): error TS1005: ';' expected. +/atotc.ts(9,56): error TS2304: Cannot find name 'on'. +/atotc.ts(9,59): error TS1005: ';' expected. +/atotc.ts(9,59): error TS2304: Cannot find name 'its'. +/atotc.ts(10,1): error TS2304: Cannot find name 'being'. +/atotc.ts(10,7): error TS1005: ';' expected. +/atotc.ts(10,7): error TS2304: Cannot find name 'received'. +/atotc.ts(10,17): error TS1109: Expression expected. +/atotc.ts(10,21): error TS1005: '(' expected. +/atotc.ts(10,21): error TS2304: Cannot find name 'good'. +/atotc.ts(10,26): error TS1005: ';' expected. +/atotc.ts(10,26): error TS2304: Cannot find name 'or'. +/atotc.ts(10,29): error TS1005: ';' expected. +/atotc.ts(10,33): error TS1005: '(' expected. +/atotc.ts(10,33): error TS2304: Cannot find name 'evil'. +/atotc.ts(10,33): error TS2406: Invalid left-hand side in 'for...in' statement. +/atotc.ts(10,39): error TS1109: Expression expected. +/atotc.ts(10,42): error TS2304: Cannot find name 'the'. +/atotc.ts(10,46): error TS1005: ')' expected. +/atotc.ts(10,46): error TS2304: Cannot find name 'superlative'. +/atotc.ts(10,58): error TS1005: ';' expected. +/atotc.ts(10,58): error TS2304: Cannot find name 'degree'. +/atotc.ts(11,1): error TS2304: Cannot find name 'of'. +/atotc.ts(11,4): error TS1005: ';' expected. +/atotc.ts(11,4): error TS2304: Cannot find name 'comparison'. +/atotc.ts(11,15): error TS1005: ';' expected. +/atotc.ts(11,15): error TS2304: Cannot find name 'only'. +/atotc.ts(11,20): error TS1003: Identifier expected. + + +==== /atotc.ts (213 errors) ==== + It was the best of times, it was the worst of times, + ~~ +!!! error TS2304: Cannot find name 'It'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'best'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'times'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'worst'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'times'. + it was the age of wisdom, it was the age of foolishness, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'age'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'wisdom'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'age'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'foolishness'. + it was the epoch of belief, it was the epoch of incredulity, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'epoch'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'belief'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'epoch'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'incredulity'. + it was the season of Light, it was the season of Darkness, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'season'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'Light'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'season'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Darkness'. + it was the spring of hope, it was the winter of despair, + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'spring'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'hope'. + ~~ +!!! error TS2304: Cannot find name 'it'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'winter'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'despair'. + we had everything before us, we had nothing before us, + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'had'. + ~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~ +!!! error TS2304: Cannot find name 'everything'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'before'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'us'. + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'had'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'nothing'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'before'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'us'. + we were all going direct to Heaven, we were all going direct + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'were'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'all'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'going'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'direct'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'to'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'Heaven'. + ~~ +!!! error TS2304: Cannot find name 'we'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'were'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'all'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'going'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'direct'. + the other way--in short, the period was so far like the present + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~ +!!! error TS1005: ';' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'other'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'way'. + ~~~~~ +!!! error TS2304: Cannot find name 'short'. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'period'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'was'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'so'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'far'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'like'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2304: Cannot find name 'present'. + period, that some of its noisiest authorities insisted on its + ~~~~~~ +!!! error TS2304: Cannot find name 'period'. + ~~~~ +!!! error TS2304: Cannot find name 'that'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'some'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'its'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'noisiest'. + ~~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'authorities'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'insisted'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'on'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'its'. + being received, for good or for evil, in the superlative degree + ~~~~~ +!!! error TS2304: Cannot find name 'being'. + ~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'received'. + ~~~ +!!! error TS1109: Expression expected. + ~~~~ +!!! error TS1005: '(' expected. + ~~~~ +!!! error TS2304: Cannot find name 'good'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'or'. + ~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS1005: '(' expected. + ~~~~ +!!! error TS2304: Cannot find name 'evil'. + ~~~~~ +!!! error TS2406: Invalid left-hand side in 'for...in' statement. + ~~ +!!! error TS1109: Expression expected. + ~~~ +!!! error TS2304: Cannot find name 'the'. + ~~~~~~~~~~~ +!!! error TS1005: ')' expected. + ~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'superlative'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'degree'. + of comparison only. + ~~ +!!! error TS2304: Cannot find name 'of'. + ~~~~~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~ +!!! error TS2304: Cannot find name 'comparison'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'only'. + +!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.js b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.js new file mode 100644 index 0000000000000..30c1de3575183 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/languageServiceExtensions/can-override-all-functions.js @@ -0,0 +1,117 @@ +//// [atotc.ts] +It was the best of times, it was the worst of times, +it was the age of wisdom, it was the age of foolishness, +it was the epoch of belief, it was the epoch of incredulity, +it was the season of Light, it was the season of Darkness, +it was the spring of hope, it was the winter of despair, +we had everything before us, we had nothing before us, +we were all going direct to Heaven, we were all going direct +the other way--in short, the period was so far like the present +period, that some of its noisiest authorities insisted on its +being received, for good or for evil, in the superlative degree +of comparison only. + +//// [atotc.js] +It; +was; +the; +best; +of; +times, it; +was; +the; +worst; +of; +times, + it; +was; +the; +age; +of; +wisdom, it; +was; +the; +age; +of; +foolishness, + it; +was; +the; +epoch; +of; +belief, it; +was; +the; +epoch; +of; +incredulity, + it; +was; +the; +season; +of; +Light, it; +was; +the; +season; +of; +Darkness, + it; +was; +the; +spring; +of; +hope, it; +was; +the; +winter; +of; +despair, + we; +had; +everything; +before; +us, we; +had; +nothing; +before; +us, + we; +were; +all; +going; +direct; +to; +Heaven, we; +were; +all; +going; +direct; +the; +other; +way-- in short, the; +period; +was; +so; +far; +like; +the; +present; +period, that; +some; +of; +its; +noisiest; +authorities; +insisted; +on; +its; +being; +received, ; +for (good; or; ) + for (evil, in the) + superlative; +degree; +of; +comparison; +only.; diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.errors.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.errors.txt new file mode 100644 index 0000000000000..1cb72fb0e9434 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.errors.txt @@ -0,0 +1,17 @@ +/foo-interface-const.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. +/foo-interface-const.ts(2,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-interface-const.ts(2,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-interface-const.ts(2,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-interface-const.ts (4 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.js b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.js new file mode 100644 index 0000000000000..09240cac36985 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.js @@ -0,0 +1,6 @@ +//// [foo-interface-const.ts] +interface Foo {a; b;} +const s: "foo" = "foo"; + +//// [foo-interface-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/both-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.js b/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.errors.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.errors.txt new file mode 100644 index 0000000000000..7b4b32f665de6 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.errors.txt @@ -0,0 +1,13 @@ +/foo-const.ts(1,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-const.ts (3 errors) ==== + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.js b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.js new file mode 100644 index 0000000000000..93ea8cd509684 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.js @@ -0,0 +1,5 @@ +//// [foo-const.ts] +const s: "foo" = "foo"; + +//// [foo-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/semantic-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.errors.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.errors.txt new file mode 100644 index 0000000000000..26aff22d2534b --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.errors.txt @@ -0,0 +1,7 @@ +/foo-interface.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. + + +==== /foo-interface.ts (1 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.js b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multiLintLoads/syntactic-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.errors.txt b/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.errors.txt new file mode 100644 index 0000000000000..f2f78f412a2cb --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.errors.txt @@ -0,0 +1,31 @@ +/foo-bar-const-interface.ts(1,11): warning test-multi-extension[IsNamedFoo]: Identifier 'foo' is forbidden. +/foo-bar-const-interface.ts(2,11): warning test-multi-extension[IsNamedBar]: Identifier 'bar' is forbidden. +/foo-bar-const-interface.ts(3,7): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(3,10): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(3,18): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(4,5): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. +/foo-bar-const-interface.ts(4,8): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. +/foo-bar-const-interface.ts(4,16): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + + +==== /foo-bar-const-interface.ts (8 errors) ==== + interface Foo {b;} + ~~~ +!!! warning test-multi-extension[IsNamedFoo]: Identifier 'foo' is forbidden. + interface Bar {a;} + ~~~ +!!! warning test-multi-extension[IsNamedBar]: Identifier 'bar' is forbidden. + const f: "foo" = "foo"; + ~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + let b: "bar" = "bar"; + ~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.js b/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.js new file mode 100644 index 0000000000000..b0cf15485cf35 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/multipleRulesFoundInSingleExtension/test.js @@ -0,0 +1,9 @@ +//// [foo-bar-const-interface.ts] +interface Foo {b;} +interface Bar {a;} +const f: "foo" = "foo"; +let b: "bar" = "bar"; + +//// [foo-bar-const-interface.js] +var f = "foo"; +var b = "bar"; diff --git a/tests/baselines/reference/CompilerHost/passArguments/array.errors.txt b/tests/baselines/reference/CompilerHost/passArguments/array.errors.txt new file mode 100644 index 0000000000000..111f82a3d9064 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/passArguments/array.errors.txt @@ -0,0 +1,10 @@ +/foo-interface.ts(1,16): warning test-extension-arguments: Identifier a is forbidden. +/foo-interface.ts(1,19): warning test-extension-arguments: Identifier b is forbidden. + + +==== /foo-interface.ts (2 errors) ==== + interface Foo {a; b;} + ~ +!!! warning test-extension-arguments: Identifier a is forbidden. + ~ +!!! warning test-extension-arguments: Identifier b is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/passArguments/array.js b/tests/baselines/reference/CompilerHost/passArguments/array.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/passArguments/array.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/CompilerHost/profileExtensionsTraces/test.js b/tests/baselines/reference/CompilerHost/profileExtensionsTraces/test.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/profileExtensionsTraces/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.errors.txt b/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.errors.txt new file mode 100644 index 0000000000000..9e6fc2a47ab5c --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.errors.txt @@ -0,0 +1,114 @@ +warning test-errors: Not allowed. +warning test-errors[Throws2](THROWS2): Not allowed. +error test-errors[Throws7]: Not allowed. +error test-errors[Throws8](THROWS8): Not allowed. +error test-errors[ThrowsOnAfterVisit](!!!): afterVisit failed with error: Error: Throws on afterVisit +error test-errors[ThrowsOnConstruct]: Lint construction failed: Throws on construct +error test-errors[ThrowsOnVisit](!!!): visit failed with error: Error: Throws on visit +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws10](THROWS10): Not allowed. +/hello.ts(1,1): error test-errors[Throws12]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws4](THROWS4): Not allowed. +/hello.ts(1,1): warning test-errors[Throws6]: Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,9): error test-errors[Throws11]: Not allowed. +/hello.ts(1,9): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,9): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,9): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,13): error test-errors[Throws11]: Not allowed. +/hello.ts(1,13): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,13): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,13): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,37): error test-errors[Throws11]: Not allowed. +/hello.ts(1,37): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,37): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,37): error test-errors[Throws9](THROWS9): Not allowed. + + +!!! warning test-errors: Not allowed. +!!! warning test-errors[Throws2](THROWS2): Not allowed. +!!! error test-errors[Throws7]: Not allowed. +!!! error test-errors[Throws8](THROWS8): Not allowed. +!!! error test-errors[ThrowsOnAfterVisit](!!!): afterVisit failed with error: Error: Throws on afterVisit +!!! error test-errors[ThrowsOnConstruct]: Lint construction failed: Throws on construct +!!! error test-errors[ThrowsOnVisit](!!!): visit failed with error: Error: Throws on visit +==== /hello.ts (32 errors) ==== + console.log("Hello, world!");/*EOL*/ + ~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~ +!!! error test-errors[Throws10](THROWS10): Not allowed. + ~~~~~~~~~~ +!!! error test-errors[Throws12]: Not allowed. + ~~~~~~~~~~ +!!! warning test-errors[Throws4](THROWS4): Not allowed. + ~~~~~~~~~~ +!!! warning test-errors[Throws6]: Not allowed. + ~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + +!!! error test-errors[Throws11]: Not allowed. + +!!! warning test-errors[Throws3](THROWS3): Not allowed. + +!!! warning test-errors[Throws5]: Not allowed. + +!!! error test-errors[Throws9](THROWS9): Not allowed. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.js b/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsAllDIagnosticsFormats/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.errors.txt b/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.errors.txt new file mode 100644 index 0000000000000..2f527e1085ea8 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.errors.txt @@ -0,0 +1,21 @@ +/foo-bar-math.ts(1,7): warning test-multierrors(FOO): Identifier 'foo' is forbidden. +/foo-bar-math.ts(1,7): warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. +/foo-bar-math.ts(2,7): warning test-multierrors(BAR): Identifier 'bar' is forbidden. +/foo-bar-math.ts(2,7): warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. +/foo-bar-math.ts(3,7): warning test-multierrors[NoShortNames](SINGLE): Single character identifiers are forbidden + + +==== /foo-bar-math.ts (5 errors) ==== + const foo = 3; + ~~~ +!!! warning test-multierrors(FOO): Identifier 'foo' is forbidden. + ~~~ +!!! warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. + const bar = 4; + ~~~ +!!! warning test-multierrors(BAR): Identifier 'bar' is forbidden. + ~~~ +!!! warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. + const x = 3 * 4; + ~ +!!! warning test-multierrors[NoShortNames](SINGLE): Single character identifiers are forbidden \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.js b/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.js new file mode 100644 index 0000000000000..8cf880068a1c5 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsDiagnosticsWithShortnames/test.js @@ -0,0 +1,9 @@ +//// [foo-bar-math.ts] +const foo = 3; +const bar = 4; +const x = 3 * 4; + +//// [foo-bar-math.js] +var foo = 3; +var bar = 4; +var x = 3 * 4; diff --git a/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.errors.txt b/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.errors.txt new file mode 100644 index 0000000000000..7d6ee017a2a6b --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.errors.txt @@ -0,0 +1,8 @@ +error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-semantic-lint'.'. +error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-syntactic-lint'.'. + + +!!! error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-semantic-lint'.'. +!!! error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-syntactic-lint'.'. +==== /hello.ts (0 errors) ==== + console.log("Hello, world!");/*EOL*/ \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.js b/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/reportsFailedLoads/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.js b/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..acf7782714e0c --- /dev/null +++ b/tests/baselines/reference/CompilerHost/semanticLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.errors.txt b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.errors.txt new file mode 100644 index 0000000000000..7b4b32f665de6 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.errors.txt @@ -0,0 +1,13 @@ +/foo-const.ts(1,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-const.ts (3 errors) ==== + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.js b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.js new file mode 100644 index 0000000000000..93ea8cd509684 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.js @@ -0,0 +1,5 @@ +//// [foo-const.ts] +const s: "foo" = "foo"; + +//// [foo-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.trace.txt new file mode 100644 index 0000000000000..acf7782714e0c --- /dev/null +++ b/tests/baselines/reference/CompilerHost/semanticLintLoads/w-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.js b/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..21b4721f1a6ed --- /dev/null +++ b/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..76f57ec088c21 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/syntacticLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.errors.txt b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.errors.txt new file mode 100644 index 0000000000000..26aff22d2534b --- /dev/null +++ b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.errors.txt @@ -0,0 +1,7 @@ +/foo-interface.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. + + +==== /foo-interface.ts (1 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.js b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.trace.txt b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.trace.txt new file mode 100644 index 0000000000000..76f57ec088c21 --- /dev/null +++ b/tests/baselines/reference/CompilerHost/syntacticLintLoads/w-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.errors.txt new file mode 100644 index 0000000000000..86ceab8437d30 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.errors.txt @@ -0,0 +1,6 @@ +message test-plugin-loaded: Test language service plugin loaded! + + +!!! message test-plugin-loaded: Test language service plugin loaded! +==== /hello.ts (0 errors) ==== + console.log("Hello, world!");/*EOL*/ \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-add-program-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.errors.txt b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.errors.txt new file mode 100644 index 0000000000000..28ac94a0b59fb --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.errors.txt @@ -0,0 +1,16 @@ +message program-diagnostics-mutated: Program diagnostics mutated! +message semantic-diagnostics-mutated: Semantic diagnostics mutated! +message syntactic-diagnostics-mutated: Syntactic diagnostics mutated! +/hello-error.ts(1,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +/hello-error.ts(1,31): error TS1109: Expression expected. + + +!!! message program-diagnostics-mutated: Program diagnostics mutated! +!!! message semantic-diagnostics-mutated: Semantic diagnostics mutated! +!!! message syntactic-diagnostics-mutated: Syntactic diagnostics mutated! +==== /hello-error.ts (2 errors) ==== + console.log("Hello, error!") - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.js b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.js new file mode 100644 index 0000000000000..9650d50b1bb7c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-chain-services.js @@ -0,0 +1,5 @@ +//// [hello-error.ts] +console.log("Hello, error!") - + +//// [hello-error.js] +console.log("Hello, error!") - ; diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.errors.txt b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.errors.txt new file mode 100644 index 0000000000000..63a20e9cb70e1 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.errors.txt @@ -0,0 +1,20 @@ +message program-diagnostics-replaced: Program diagnostics replaced! +message semantic-diagnostics-replaced: Semantic diagnostics replaced! +message syntactic-diagnostics-replaced: Syntactic diagnostics replaced! + + +!!! message program-diagnostics-replaced: Program diagnostics replaced! +!!! message semantic-diagnostics-replaced: Semantic diagnostics replaced! +!!! message syntactic-diagnostics-replaced: Syntactic diagnostics replaced! +==== /atotc.ts (0 errors) ==== + It was the best of times, it was the worst of times, + it was the age of wisdom, it was the age of foolishness, + it was the epoch of belief, it was the epoch of incredulity, + it was the season of Light, it was the season of Darkness, + it was the spring of hope, it was the winter of despair, + we had everything before us, we had nothing before us, + we were all going direct to Heaven, we were all going direct + the other way--in short, the period was so far like the present + period, that some of its noisiest authorities insisted on its + being received, for good or for evil, in the superlative degree + of comparison only. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.js b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.js new file mode 100644 index 0000000000000..0a4b5fe31af18 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-all-functions.js @@ -0,0 +1,117 @@ +//// [atotc.ts] +It was the best of times, it was the worst of times, +it was the age of wisdom, it was the age of foolishness, +it was the epoch of belief, it was the epoch of incredulity, +it was the season of Light, it was the season of Darkness, +it was the spring of hope, it was the winter of despair, +we had everything before us, we had nothing before us, +we were all going direct to Heaven, we were all going direct +the other way--in short, the period was so far like the present +period, that some of its noisiest authorities insisted on its +being received, for good or for evil, in the superlative degree +of comparison only. + +//// [atotc.js] +It; +was; +the; +best; +of; +times, it; +was; +the; +worst; +of; +times, + it; +was; +the; +age; +of; +wisdom, it; +was; +the; +age; +of; +foolishness, + it; +was; +the; +epoch; +of; +belief, it; +was; +the; +epoch; +of; +incredulity, + it; +was; +the; +season; +of; +Light, it; +was; +the; +season; +of; +Darkness, + it; +was; +the; +spring; +of; +hope, it; +was; +the; +winter; +of; +despair, + we; +had; +everything; +before; +us, we; +had; +nothing; +before; +us, + we; +were; +all; +going; +direct; +to; +Heaven, we; +were; +all; +going; +direct; +the; +other; +way-- in short, the; +period; +was; +so; +far; +like; +the; +present; +period, that; +some; +of; +its; +noisiest; +authorities; +insisted; +on; +its; +being; +received, ; +for (good; or; ) + for (evil, in the) + superlative; +degree; +of; +comparison; +only.; diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.errors.txt b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.errors.txt new file mode 100644 index 0000000000000..5402510857df8 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.errors.txt @@ -0,0 +1,10 @@ +/hello-error.ts(1,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +/hello-error.ts(1,31): error TS1109: Expression expected. + + +==== /hello-error.ts (2 errors) ==== + console.log("Hello, error!") - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.js b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.js new file mode 100644 index 0000000000000..9650d50b1bb7c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-filter-passthru.js @@ -0,0 +1,5 @@ +//// [hello-error.ts] +console.log("Hello, error!") - + +//// [hello-error.js] +console.log("Hello, error!") - ; diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.errors.txt b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.errors.txt new file mode 100644 index 0000000000000..63a20e9cb70e1 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.errors.txt @@ -0,0 +1,20 @@ +message program-diagnostics-replaced: Program diagnostics replaced! +message semantic-diagnostics-replaced: Semantic diagnostics replaced! +message syntactic-diagnostics-replaced: Syntactic diagnostics replaced! + + +!!! message program-diagnostics-replaced: Program diagnostics replaced! +!!! message semantic-diagnostics-replaced: Semantic diagnostics replaced! +!!! message syntactic-diagnostics-replaced: Syntactic diagnostics replaced! +==== /atotc.ts (0 errors) ==== + It was the best of times, it was the worst of times, + it was the age of wisdom, it was the age of foolishness, + it was the epoch of belief, it was the epoch of incredulity, + it was the season of Light, it was the season of Darkness, + it was the spring of hope, it was the winter of despair, + we had everything before us, we had nothing before us, + we were all going direct to Heaven, we were all going direct + the other way--in short, the period was so far like the present + period, that some of its noisiest authorities insisted on its + being received, for good or for evil, in the superlative degree + of comparison only. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.js b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.js new file mode 100644 index 0000000000000..0a4b5fe31af18 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/languageServiceExtensions/can-override-all-functions.js @@ -0,0 +1,117 @@ +//// [atotc.ts] +It was the best of times, it was the worst of times, +it was the age of wisdom, it was the age of foolishness, +it was the epoch of belief, it was the epoch of incredulity, +it was the season of Light, it was the season of Darkness, +it was the spring of hope, it was the winter of despair, +we had everything before us, we had nothing before us, +we were all going direct to Heaven, we were all going direct +the other way--in short, the period was so far like the present +period, that some of its noisiest authorities insisted on its +being received, for good or for evil, in the superlative degree +of comparison only. + +//// [atotc.js] +It; +was; +the; +best; +of; +times, it; +was; +the; +worst; +of; +times, + it; +was; +the; +age; +of; +wisdom, it; +was; +the; +age; +of; +foolishness, + it; +was; +the; +epoch; +of; +belief, it; +was; +the; +epoch; +of; +incredulity, + it; +was; +the; +season; +of; +Light, it; +was; +the; +season; +of; +Darkness, + it; +was; +the; +spring; +of; +hope, it; +was; +the; +winter; +of; +despair, + we; +had; +everything; +before; +us, we; +had; +nothing; +before; +us, + we; +were; +all; +going; +direct; +to; +Heaven, we; +were; +all; +going; +direct; +the; +other; +way-- in short, the; +period; +was; +so; +far; +like; +the; +present; +period, that; +some; +of; +its; +noisiest; +authorities; +insisted; +on; +its; +being; +received, ; +for (good; or; ) + for (evil, in the) + superlative; +degree; +of; +comparison; +only.; diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.errors.txt new file mode 100644 index 0000000000000..1cb72fb0e9434 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.errors.txt @@ -0,0 +1,17 @@ +/foo-interface-const.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. +/foo-interface-const.ts(2,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-interface-const.ts(2,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-interface-const.ts(2,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-interface-const.ts (4 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.js new file mode 100644 index 0000000000000..fc662ca5eb71c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.js @@ -0,0 +1,6 @@ +//// [foo-interface-const.ts] +interface Foo {a; b;} +const s: "foo" = "foo"; + +//// [foo-interface-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/both-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.errors.txt new file mode 100644 index 0000000000000..7b4b32f665de6 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.errors.txt @@ -0,0 +1,13 @@ +/foo-const.ts(1,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-const.ts (3 errors) ==== + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.js new file mode 100644 index 0000000000000..3743391a17e19 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.js @@ -0,0 +1,5 @@ +//// [foo-const.ts] +const s: "foo" = "foo"; + +//// [foo-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/semantic-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.errors.txt new file mode 100644 index 0000000000000..26aff22d2534b --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.errors.txt @@ -0,0 +1,7 @@ +/foo-interface.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. + + +==== /foo-interface.ts (1 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.trace.txt new file mode 100644 index 0000000000000..9069e84844866 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multiLintLoads/syntactic-diagnostics.trace.txt @@ -0,0 +1,18 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.errors.txt b/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.errors.txt new file mode 100644 index 0000000000000..f2f78f412a2cb --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.errors.txt @@ -0,0 +1,31 @@ +/foo-bar-const-interface.ts(1,11): warning test-multi-extension[IsNamedFoo]: Identifier 'foo' is forbidden. +/foo-bar-const-interface.ts(2,11): warning test-multi-extension[IsNamedBar]: Identifier 'bar' is forbidden. +/foo-bar-const-interface.ts(3,7): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(3,10): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(3,18): warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. +/foo-bar-const-interface.ts(4,5): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. +/foo-bar-const-interface.ts(4,8): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. +/foo-bar-const-interface.ts(4,16): warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + + +==== /foo-bar-const-interface.ts (8 errors) ==== + interface Foo {b;} + ~~~ +!!! warning test-multi-extension[IsNamedFoo]: Identifier 'foo' is forbidden. + interface Bar {a;} + ~~~ +!!! warning test-multi-extension[IsNamedBar]: Identifier 'bar' is forbidden. + const f: "foo" = "foo"; + ~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueFoo]: String literal type 'foo' is forbidden. + let b: "bar" = "bar"; + ~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. + ~~~~~ +!!! warning test-multi-extension[IsValueBar]: String literal type 'bar' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.js b/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.js new file mode 100644 index 0000000000000..7c7d27a43ddf5 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/multipleRulesFoundInSingleExtension/test.js @@ -0,0 +1,9 @@ +//// [foo-bar-const-interface.ts] +interface Foo {b;} +interface Bar {a;} +const f: "foo" = "foo"; +let b: "bar" = "bar"; + +//// [foo-bar-const-interface.js] +var f = "foo"; +var b = "bar"; diff --git a/tests/baselines/reference/LanguageServiceHost/passArguments/array.errors.txt b/tests/baselines/reference/LanguageServiceHost/passArguments/array.errors.txt new file mode 100644 index 0000000000000..111f82a3d9064 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/passArguments/array.errors.txt @@ -0,0 +1,10 @@ +/foo-interface.ts(1,16): warning test-extension-arguments: Identifier a is forbidden. +/foo-interface.ts(1,19): warning test-extension-arguments: Identifier b is forbidden. + + +==== /foo-interface.ts (2 errors) ==== + interface Foo {a; b;} + ~ +!!! warning test-extension-arguments: Identifier a is forbidden. + ~ +!!! warning test-extension-arguments: Identifier b is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/passArguments/array.js b/tests/baselines/reference/LanguageServiceHost/passArguments/array.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/passArguments/array.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/LanguageServiceHost/profileExtensionsTraces/test.js b/tests/baselines/reference/LanguageServiceHost/profileExtensionsTraces/test.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/profileExtensionsTraces/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.errors.txt b/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.errors.txt new file mode 100644 index 0000000000000..9e6fc2a47ab5c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.errors.txt @@ -0,0 +1,114 @@ +warning test-errors: Not allowed. +warning test-errors[Throws2](THROWS2): Not allowed. +error test-errors[Throws7]: Not allowed. +error test-errors[Throws8](THROWS8): Not allowed. +error test-errors[ThrowsOnAfterVisit](!!!): afterVisit failed with error: Error: Throws on afterVisit +error test-errors[ThrowsOnConstruct]: Lint construction failed: Throws on construct +error test-errors[ThrowsOnVisit](!!!): visit failed with error: Error: Throws on visit +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws10](THROWS10): Not allowed. +/hello.ts(1,1): error test-errors[Throws12]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws4](THROWS4): Not allowed. +/hello.ts(1,1): warning test-errors[Throws6]: Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,1): error test-errors[Throws11]: Not allowed. +/hello.ts(1,1): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,1): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,1): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,9): error test-errors[Throws11]: Not allowed. +/hello.ts(1,9): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,9): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,9): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,13): error test-errors[Throws11]: Not allowed. +/hello.ts(1,13): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,13): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,13): error test-errors[Throws9](THROWS9): Not allowed. +/hello.ts(1,37): error test-errors[Throws11]: Not allowed. +/hello.ts(1,37): warning test-errors[Throws3](THROWS3): Not allowed. +/hello.ts(1,37): warning test-errors[Throws5]: Not allowed. +/hello.ts(1,37): error test-errors[Throws9](THROWS9): Not allowed. + + +!!! warning test-errors: Not allowed. +!!! warning test-errors[Throws2](THROWS2): Not allowed. +!!! error test-errors[Throws7]: Not allowed. +!!! error test-errors[Throws8](THROWS8): Not allowed. +!!! error test-errors[ThrowsOnAfterVisit](!!!): afterVisit failed with error: Error: Throws on afterVisit +!!! error test-errors[ThrowsOnConstruct]: Lint construction failed: Throws on construct +!!! error test-errors[ThrowsOnVisit](!!!): visit failed with error: Error: Throws on visit +==== /hello.ts (32 errors) ==== + console.log("Hello, world!");/*EOL*/ + ~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~ +!!! error test-errors[Throws10](THROWS10): Not allowed. + ~~~~~~~~~~ +!!! error test-errors[Throws12]: Not allowed. + ~~~~~~~~~~ +!!! warning test-errors[Throws4](THROWS4): Not allowed. + ~~~~~~~~~~ +!!! warning test-errors[Throws6]: Not allowed. + ~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + ~~~~~~~~~~~~~~~ +!!! error test-errors[Throws11]: Not allowed. + ~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws3](THROWS3): Not allowed. + ~~~~~~~~~~~~~~~ +!!! warning test-errors[Throws5]: Not allowed. + ~~~~~~~~~~~~~~~ +!!! error test-errors[Throws9](THROWS9): Not allowed. + +!!! error test-errors[Throws11]: Not allowed. + +!!! warning test-errors[Throws3](THROWS3): Not allowed. + +!!! warning test-errors[Throws5]: Not allowed. + +!!! error test-errors[Throws9](THROWS9): Not allowed. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.js b/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsAllDIagnosticsFormats/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.errors.txt b/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.errors.txt new file mode 100644 index 0000000000000..2f527e1085ea8 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.errors.txt @@ -0,0 +1,21 @@ +/foo-bar-math.ts(1,7): warning test-multierrors(FOO): Identifier 'foo' is forbidden. +/foo-bar-math.ts(1,7): warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. +/foo-bar-math.ts(2,7): warning test-multierrors(BAR): Identifier 'bar' is forbidden. +/foo-bar-math.ts(2,7): warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. +/foo-bar-math.ts(3,7): warning test-multierrors[NoShortNames](SINGLE): Single character identifiers are forbidden + + +==== /foo-bar-math.ts (5 errors) ==== + const foo = 3; + ~~~ +!!! warning test-multierrors(FOO): Identifier 'foo' is forbidden. + ~~~ +!!! warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. + const bar = 4; + ~~~ +!!! warning test-multierrors(BAR): Identifier 'bar' is forbidden. + ~~~ +!!! warning test-multierrors[NoShortNames](SHORT): Short identifiers are forbidden. + const x = 3 * 4; + ~ +!!! warning test-multierrors[NoShortNames](SINGLE): Single character identifiers are forbidden \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.js b/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.js new file mode 100644 index 0000000000000..cf277cae619b3 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsDiagnosticsWithShortnames/test.js @@ -0,0 +1,9 @@ +//// [foo-bar-math.ts] +const foo = 3; +const bar = 4; +const x = 3 * 4; + +//// [foo-bar-math.js] +var foo = 3; +var bar = 4; +var x = 3 * 4; diff --git a/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.errors.txt b/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.errors.txt new file mode 100644 index 0000000000000..7d6ee017a2a6b --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.errors.txt @@ -0,0 +1,8 @@ +error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-semantic-lint'.'. +error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-syntactic-lint'.'. + + +!!! error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-semantic-lint'.'. +!!! error TS6151: Extension loading failed with error 'Error: Host could not locate extension 'test-syntactic-lint'.'. +==== /hello.ts (0 errors) ==== + console.log("Hello, world!");/*EOL*/ \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.js b/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/reportsFailedLoads/test.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..acf7782714e0c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.errors.txt new file mode 100644 index 0000000000000..7b4b32f665de6 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.errors.txt @@ -0,0 +1,13 @@ +/foo-const.ts(1,7): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,10): warning test-semantic-lint: String literal type 'foo' is forbidden. +/foo-const.ts(1,18): warning test-semantic-lint: String literal type 'foo' is forbidden. + + +==== /foo-const.ts (3 errors) ==== + const s: "foo" = "foo"; + ~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. + ~~~~~ +!!! warning test-semantic-lint: String literal type 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.js new file mode 100644 index 0000000000000..3743391a17e19 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.js @@ -0,0 +1,5 @@ +//// [foo-const.ts] +const s: "foo" = "foo"; + +//// [foo-const.js] +var s = "foo"; diff --git a/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.trace.txt new file mode 100644 index 0000000000000..acf7782714e0c --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/semanticLintLoads/w-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-semantic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-semantic-lint' from 'node_modules' folder. +File '/node_modules/test-semantic-lint.js' does not exist. +File '/node_modules/test-semantic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-semantic-lint/package.json'. +'package.json' has 'main' field 'main.js' that references '/node_modules/test-semantic-lint/main.js'. +File '/node_modules/test-semantic-lint/main.js' exist - use it as a name resolution result. +======== Module name 'test-semantic-lint' was successfully resolved to '/node_modules/test-semantic-lint/main.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.js new file mode 100644 index 0000000000000..b9f140e37bdde --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.js @@ -0,0 +1,5 @@ +//// [hello.ts] +console.log("Hello, world!");/*EOL*/ + +//// [hello.js] +console.log("Hello, world!"); /*EOL*/ diff --git a/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.trace.txt new file mode 100644 index 0000000000000..76f57ec088c21 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/no-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.errors.txt b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.errors.txt new file mode 100644 index 0000000000000..26aff22d2534b --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.errors.txt @@ -0,0 +1,7 @@ +/foo-interface.ts(1,11): warning test-syntactic-lint: Identifier 'foo' is forbidden. + + +==== /foo-interface.ts (1 errors) ==== + interface Foo {a; b;} + ~~~ +!!! warning test-syntactic-lint: Identifier 'foo' is forbidden. \ No newline at end of file diff --git a/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.js b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.js new file mode 100644 index 0000000000000..9bb521dc08570 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.js @@ -0,0 +1,4 @@ +//// [foo-interface.ts] +interface Foo {a; b;} + +//// [foo-interface.js] diff --git a/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.trace.txt b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.trace.txt new file mode 100644 index 0000000000000..76f57ec088c21 --- /dev/null +++ b/tests/baselines/reference/LanguageServiceHost/syntacticLintLoads/w-diagnostics.trace.txt @@ -0,0 +1,9 @@ +======== Resolving module 'test-syntactic-lint' from '/tsconfig.json'. ======== +Module resolution kind is not specified, using 'NodeJs'. +Loading module 'test-syntactic-lint' from 'node_modules' folder. +File '/node_modules/test-syntactic-lint.js' does not exist. +File '/node_modules/test-syntactic-lint.jsx' does not exist. +Found 'package.json' at '/node_modules/test-syntactic-lint/package.json'. +'package.json' has 'main' field 'index.js' that references '/node_modules/test-syntactic-lint/index.js'. +File '/node_modules/test-syntactic-lint/index.js' exist - use it as a name resolution result. +======== Module name 'test-syntactic-lint' was successfully resolved to '/node_modules/test-syntactic-lint/index.js'. ======== \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-12.trace.json b/tests/baselines/reference/library-reference-12.trace.json index 84144f82729c6..25fb7f618cd70 100644 --- a/tests/baselines/reference/library-reference-12.trace.json +++ b/tests/baselines/reference/library-reference-12.trace.json @@ -17,6 +17,7 @@ "File '/a/node_modules/jquery.ts' does not exist.", "File '/a/node_modules/jquery.d.ts' does not exist.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", + "Expected type of 'typings' field in 'package.json' to be 'string', got 'undefined'.", "'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.", "File '/a/node_modules/jquery/dist/jquery.d.ts' exist - use it as a name resolution result.", "======== Type reference directive 'jquery' was successfully resolved to '/a/node_modules/jquery/dist/jquery.d.ts', primary: false. ========" diff --git a/tests/baselines/reference/library-reference-2.trace.json b/tests/baselines/reference/library-reference-2.trace.json index c26f7d2763d7f..0cdb8e98c48e5 100644 --- a/tests/baselines/reference/library-reference-2.trace.json +++ b/tests/baselines/reference/library-reference-2.trace.json @@ -2,12 +2,14 @@ "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", "Found 'package.json' at '/types/jquery/package.json'.", + "Expected type of 'typings' field in 'package.json' to be 'string', got 'undefined'.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", "Found 'package.json' at '/types/jquery/package.json'.", + "Expected type of 'typings' field in 'package.json' to be 'string', got 'undefined'.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========" diff --git a/tests/cases/extensions/available/extension-api/index.ts b/tests/cases/extensions/available/extension-api/index.ts new file mode 100644 index 0000000000000..f46c222d83641 --- /dev/null +++ b/tests/cases/extensions/available/extension-api/index.ts @@ -0,0 +1,49 @@ +import * as tsi from "typescript"; + +export abstract class SyntacticLintWalker implements tsi.LintWalker { + static "extension-kind": tsi.ExtensionKind.SyntacticLint = "syntactic-lint"; + protected ts: typeof tsi; + protected args: any; + protected host: tsi.CompilerHost; + protected program: tsi.Program; + constructor(state: {ts: typeof tsi, args: any, host: tsi.CompilerHost, program: tsi.Program}) { + this.ts = state.ts; + this.args = state.args; + this.host = state.host; + this.program = state.program; + } + abstract visit(node: tsi.Node, error: tsi.LintErrorMethod): boolean | void; +} + +export abstract class SemanticLintWalker implements tsi.LintWalker { + static "extension-kind": tsi.ExtensionKind.SemanticLint = "semantic-lint"; + protected ts: typeof tsi; + protected args: any; + protected host: tsi.CompilerHost; + protected program: tsi.Program; + protected checker: tsi.TypeChecker; + constructor(state: {ts: typeof tsi, args: any, host: tsi.CompilerHost, program: tsi.Program, checker: tsi.TypeChecker}) { + this.ts = state.ts; + this.args = state.args; + this.host = state.host; + this.program = state.program; + this.checker = state.checker; + } + abstract visit(node: tsi.Node, error: tsi.LintErrorMethod): boolean | void; +} + +export abstract class LanguageServiceProvider implements tsi.LanguageServiceProvider { + static "extension-kind": tsi.ExtensionKind.LanguageService = "language-service"; + protected ts: typeof tsi; + protected args: any; + protected host: tsi.LanguageServiceHost; + protected service: tsi.LanguageService; + protected registry: tsi.DocumentRegistry; + constructor(state: {ts: typeof tsi, args: any, host: tsi.LanguageServiceHost, service: tsi.LanguageService, registry: tsi.DocumentRegistry}) { + this.ts = state.ts; + this.args = state.args; + this.host = state.host; + this.service = state.service; + this.registry = state.registry; + } +} diff --git a/tests/cases/extensions/available/extension-api/package.json b/tests/cases/extensions/available/extension-api/package.json new file mode 100644 index 0000000000000..4db5f4be792e7 --- /dev/null +++ b/tests/cases/extensions/available/extension-api/package.json @@ -0,0 +1,8 @@ +{ + "name": "extension-api", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "types": "index.d.ts" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-errors/index.ts b/tests/cases/extensions/available/test-errors/index.ts new file mode 100644 index 0000000000000..1b4773d8f1583 --- /dev/null +++ b/tests/cases/extensions/available/test-errors/index.ts @@ -0,0 +1,117 @@ +import {SyntacticLintWalker} from "extension-api"; + +export default class Throws extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("Not allowed."); + return false; + } +} + +export class Throws2 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("THROWS2", "Not allowed."); + return false; + } +} + +export class Throws3 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("THROWS3", "Not allowed.", node); + return false; + } +} + +export class Throws4 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("THROWS4", "Not allowed.", 0, 10); + return false; + } +} + +export class Throws5 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("Not allowed.", node); + return false; + } +} + +export class Throws6 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error("Not allowed.", 0, 10); + return false; + } +} + +export class Throws7 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "Not allowed."); + return false; + } +} + +export class Throws8 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "THROWS8", "Not allowed."); + return false; + } +} + +export class Throws9 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "THROWS9", "Not allowed.", node); + return false; + } +} + +export class Throws10 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "THROWS10", "Not allowed.", 0, 10); + return false; + } +} + +export class Throws11 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "Not allowed.", node); + return false; + } +} + +export class Throws12 extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + error(this.ts.DiagnosticCategory.Error, "Not allowed.", 0, 10); + return false; + } +} + +export class ThrowsOnConstruct extends SyntacticLintWalker { + constructor(state) { super(state); throw new Error("Throws on construct"); } + visit(node, error) {} +} + +export class ThrowsOnVisit extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + throw new Error("Throws on visit"); + } +} + +export class ThrowsOnAfterVisit extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { return false; } + afterVisit(node, error) { + throw new Error("Throws on afterVisit"); + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-errors/package.json b/tests/cases/extensions/available/test-errors/package.json new file mode 100644 index 0000000000000..b3df9c7b4d305 --- /dev/null +++ b/tests/cases/extensions/available/test-errors/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-errors", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-extension-arguments/index.ts b/tests/cases/extensions/available/test-extension-arguments/index.ts new file mode 100644 index 0000000000000..3f14d54d4b325 --- /dev/null +++ b/tests/cases/extensions/available/test-extension-arguments/index.ts @@ -0,0 +1,14 @@ +import {SyntacticLintWalker} from "extension-api"; + +export default class IsNamedX extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + if (node.kind === this.ts.SyntaxKind.Identifier) { + for (let i = 0; i prev.code === "program-diagnostics-amended" ? { + file: undefined, + start: undefined, + length: undefined, + messageText: "Program diagnostics mutated!", + category: 2, + code: "program-diagnostics-mutated", + } : prev); + } + getSyntacticDiagnosticsFilter(fileName, previous) { + return previous.map(prev => prev.code === "syntactic-diagnostics-amended" ? { + file: undefined, + start: undefined, + length: undefined, + messageText: "Syntactic diagnostics mutated!", + category: 2, + code: "syntactic-diagnostics-mutated", + } : prev); + } + getSemanticDiagnosticsFilter(fileName, previous) { + return previous.map(prev => prev.code === "semantic-diagnostics-amended" ? { + file: undefined, + start: undefined, + length: undefined, + messageText: "Semantic diagnostics mutated!", + category: 2, + code: "semantic-diagnostics-mutated", + } : prev); + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-chain/package.json b/tests/cases/extensions/available/test-service-chain/package.json new file mode 100644 index 0000000000000..e52968c9a299f --- /dev/null +++ b/tests/cases/extensions/available/test-service-chain/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-service-chain", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-filters/index.ts b/tests/cases/extensions/available/test-service-filters/index.ts new file mode 100644 index 0000000000000..43feaf6bc0983 --- /dev/null +++ b/tests/cases/extensions/available/test-service-filters/index.ts @@ -0,0 +1,134 @@ +import {LanguageServiceProvider} from "extension-api"; + +import * as ts from "typescript"; + +export default class extends LanguageServiceProvider { + constructor(state) { super(state); } + getProgramDiagnosticsFilter(previous) { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Program diagnostics replaced!", + category: 2, + code: "program-diagnostics-replaced", + }]; + } + getSyntacticDiagnosticsFilter(fileName, previous) { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Syntactic diagnostics replaced!", + category: 2, + code: "syntactic-diagnostics-replaced", + }]; + } + getSemanticDiagnosticsFilter(fileName, previous) { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Semantic diagnostics replaced!", + category: 2, + code: "semantic-diagnostics-replaced", + }]; + } + getEncodedSyntacticClassificationsFilter(fileName, span, previous) { + return { + spans: [span.start, span.length, this.ts.endsWith(fileName, "atotc.ts") ? this.ts.ClassificationType.text : this.ts.ClassificationType.comment], + endOfLineState: this.ts.EndOfLineState.None + }; + } + getEncodedSemanticClassificationsFilter(fileName, span, previous) { + return { + spans: [span.start, span.length, this.ts.endsWith(fileName, "atotc.ts") ? this.ts.ClassificationType.moduleName : this.ts.ClassificationType.comment], + endOfLineState: this.ts.EndOfLineState.None + }; + } + getCompletionsAtPositionFilter(fileName, position, previous) { + return { + isMemberCompletion: false, + isNewIdentifierLocation: false, + entries: [{name: "fakeCompletion", kind: "", kindModifiers: "", sortText: "fakeCompletion"}] + }; + } + getCompletionEntryDetailsFilter(fileName, position, entryName, previous) { + return { + name: "fakeCompletion", + kind: position.toString(), + kindModifiers: entryName, + displayParts: [], + documentation: [], + }; + } + getQuickInfoAtPositionFilter(fileName, position, previous) { + return {}; + } + getNameOrDottedNameSpanFilter(fileName, startPos, endPos, previous) { + return {}; + } + getBreakpointStatementAtPositionFilter(fileName, position, previous) { + return {}; + } + getSignatureHelpItemsFilter(fileName, position, previous) { + return { + items: [], + applicableSpan: undefined, + selectedItemIndex: undefined, + argumentIndex: 0, + argumentCount: 0, + }; + } + getRenameInfoFilter(fileName, position, previous) { + return {}; + } + findRenameLocationsFilter(fileName, position, findInStrings, findInComments, previous) { + return {}; + } + getDefinitionAtPositionFilter(fileName, position, previous) { + return {}; + } + getTypeDefinitionAtPositionFilter(fileName, position, previous) { + return {}; + } + getReferencesAtPositionFilter(fileName, position, previous) { + return {}; + } + findReferencesFilter(fileName, position, previous) { + return {}; + } + getDocumentHighlightsFilter(fileName, position, filesToSearch, previous) { + return {}; + } + getNavigateToItemsFilter(searchValue, maxResultCount, previous) { + return {}; + } + getNavigationBarItemsFilter(fileName, previous) { + return {}; + } + getOutliningSpansFilter(fileName, previous) { + return {}; + } + getTodoCommentsFilter(fileName, descriptors, previous) { + return []; + } + getBraceMatchingAtPositionFilter(fileName, position, previous) { + return []; + } + getIndentationAtPositionFilter(fileName, position, options, previous) { + return {}; + } + getFormattingEditsForRangeFilter(fileName, start, end, options, previous) { + return {}; + } + getFormattingEditsForDocumentFilter(fileName, options, previous) { + return {}; + } + getFormattingEditsAfterKeystrokeFilter(fileName, position, key, options, previous) { + return {}; + } + getDocCommentTemplateAtPositionFilter(fileName, position, previous) { + return {newText: "/********Yes.*********/", caretOffset: 9}; + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-filters/package.json b/tests/cases/extensions/available/test-service-filters/package.json new file mode 100644 index 0000000000000..4afc14481f05a --- /dev/null +++ b/tests/cases/extensions/available/test-service-filters/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-service-filters", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-overrides/index.ts b/tests/cases/extensions/available/test-service-overrides/index.ts new file mode 100644 index 0000000000000..f206583f0a029 --- /dev/null +++ b/tests/cases/extensions/available/test-service-overrides/index.ts @@ -0,0 +1,133 @@ +import {LanguageServiceProvider} from "extension-api"; +import * as ts from "typescript"; + +export default class extends LanguageServiceProvider { + constructor(state) { super(state); } + getProgramDiagnostics() { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Program diagnostics replaced!", + category: 2, + code: "program-diagnostics-replaced", + }]; + } + getSyntacticDiagnostics(fileName) { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Syntactic diagnostics replaced!", + category: 2, + code: "syntactic-diagnostics-replaced", + }]; + } + getSemanticDiagnostics(fileName) { + return [{ + file: undefined, + start: undefined, + length: undefined, + messageText: "Semantic diagnostics replaced!", + category: 2, + code: "semantic-diagnostics-replaced", + }]; + } + getEncodedSyntacticClassifications(fileName, span) { + return { + spans: [span.start, span.length, this.ts.endsWith(fileName, "atotc.ts") ? this.ts.ClassificationType.text : this.ts.ClassificationType.comment], + endOfLineState: this.ts.EndOfLineState.None + }; + } + getEncodedSemanticClassifications(fileName, span) { + return { + spans: [span.start, span.length, this.ts.endsWith(fileName, "atotc.ts") ? this.ts.ClassificationType.moduleName : this.ts.ClassificationType.comment], + endOfLineState: this.ts.EndOfLineState.None + }; + } + getCompletionsAtPosition(fileName, position) { + return { + isMemberCompletion: false, + isNewIdentifierLocation: false, + entries: [{name: "fakeCompletion", kind: "", kindModifiers: "", sortText: "fakeCompletion"}] + }; + } + getCompletionEntryDetails(fileName, position, entryName) { + return { + name: "fakeCompletion", + kind: position.toString(), + kindModifiers: entryName, + displayParts: [], + documentation: [], + }; + } + getQuickInfoAtPosition(fileName, position) { + return {}; + } + getNameOrDottedNameSpan(fileName, startPos, endPos) { + return {}; + } + getBreakpointStatementAtPosition(fileName, position) { + return {}; + } + getSignatureHelpItems(fileName, position) { + return { + items: [], + applicableSpan: undefined, + selectedItemIndex: undefined, + argumentIndex: 0, + argumentCount: 0, + }; + } + getRenameInfo(fileName, position) { + return {}; + } + findRenameLocations(fileName, position, findInStrings, findInComments) { + return {}; + } + getDefinitionAtPosition(fileName, position) { + return {}; + } + getTypeDefinitionAtPosition(fileName, position) { + return {}; + } + getReferencesAtPosition(fileName, position) { + return {}; + } + findReferences(fileName, position) { + return {}; + } + getDocumentHighlights(fileName, position, filesToSearch) { + return {}; + } + getNavigateToItems(searchValue, maxResultCount) { + return {}; + } + getNavigationBarItems(fileName) { + return {}; + } + getOutliningSpans(fileName) { + return {}; + } + getTodoComments(fileName, descriptors) { + return []; + } + getBraceMatchingAtPosition(fileName, position) { + return []; + } + getIndentationAtPosition(fileName, position, options) { + return {}; + } + getFormattingEditsForRange(fileName, start, end, options) { + return {}; + } + getFormattingEditsForDocument(fileName, options) { + return {}; + } + getFormattingEditsAfterKeystroke(fileName, position, key, options) { + return {}; + } + getDocCommentTemplateAtPosition(fileName, position) { + return {newText: "/********Yes.*********/", caretOffset: 9}; + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-overrides/package.json b/tests/cases/extensions/available/test-service-overrides/package.json new file mode 100644 index 0000000000000..92436b41974f2 --- /dev/null +++ b/tests/cases/extensions/available/test-service-overrides/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-service-overrides", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-passthru/index.ts b/tests/cases/extensions/available/test-service-passthru/index.ts new file mode 100644 index 0000000000000..074a90623815d --- /dev/null +++ b/tests/cases/extensions/available/test-service-passthru/index.ts @@ -0,0 +1,14 @@ +import {LanguageServiceProvider} from "extension-api"; + +export default class extends LanguageServiceProvider { + constructor(state) { super(state); } + getProgramDiagnosticsFilter(previous) { + return previous; + } + getSyntacticDiagnosticsFilter(fileName, previous) { + return previous; + } + getSemanticDiagnosticsFilter(fileName, previous) { + return previous; + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-service-passthru/package.json b/tests/cases/extensions/available/test-service-passthru/package.json new file mode 100644 index 0000000000000..4315a97feec91 --- /dev/null +++ b/tests/cases/extensions/available/test-service-passthru/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-service-passthru", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-syntactic-lint/index.ts b/tests/cases/extensions/available/test-syntactic-lint/index.ts new file mode 100644 index 0000000000000..73e9e6b5ae416 --- /dev/null +++ b/tests/cases/extensions/available/test-syntactic-lint/index.ts @@ -0,0 +1,12 @@ +import {SyntacticLintWalker} from "extension-api"; + +export default class IsNamedFoo extends SyntacticLintWalker { + constructor(state) { super(state); } + visit(node, error) { + if (node.kind === this.ts.SyntaxKind.Identifier) { + if (node.text.toLowerCase() === "foo") { + error("Identifier 'foo' is forbidden.", node); + } + } + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/test-syntactic-lint/package.json b/tests/cases/extensions/available/test-syntactic-lint/package.json new file mode 100644 index 0000000000000..a7d3e0e95e26e --- /dev/null +++ b/tests/cases/extensions/available/test-syntactic-lint/package.json @@ -0,0 +1,7 @@ +{ + "name": "test-syntactic-lint", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "" +} \ No newline at end of file diff --git a/tests/cases/extensions/available/tsconfig.json b/tests/cases/extensions/available/tsconfig.json new file mode 100644 index 0000000000000..f47c7d90a5b7a --- /dev/null +++ b/tests/cases/extensions/available/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + // This baseUrl option is useful while writing tests - it lets us + // pretend all these modules can see one another (as if they were in a node_modules folder) + // since when they're loaded into the virtual fs the test host provides, they _will_ be in a + // node_modules folder + "baseUrl": "./" + } +} \ No newline at end of file diff --git a/tests/cases/extensions/available/typescript/package.json b/tests/cases/extensions/available/typescript/package.json new file mode 100644 index 0000000000000..4a11df79f86b2 --- /dev/null +++ b/tests/cases/extensions/available/typescript/package.json @@ -0,0 +1,3 @@ +{ + "types": "../../../../built/local/typescript.d.ts" +} \ No newline at end of file diff --git a/tests/cases/extensions/fourslash/test.ts b/tests/cases/extensions/fourslash/test.ts new file mode 100644 index 0000000000000..ee1f6094e6e4e --- /dev/null +++ b/tests/cases/extensions/fourslash/test.ts @@ -0,0 +1,5 @@ +/// + +goTo.file("hello.ts"); +goTo.marker("EOL"); +verify.caretAtMarker("EOL"); \ No newline at end of file diff --git a/tests/cases/extensions/fourslash/verify-overridden-diagnostics.ts b/tests/cases/extensions/fourslash/verify-overridden-diagnostics.ts new file mode 100644 index 0000000000000..5d3ca5220fd06 --- /dev/null +++ b/tests/cases/extensions/fourslash/verify-overridden-diagnostics.ts @@ -0,0 +1,15 @@ +/// + +goTo.file("atotc.ts"); +verify.getSemanticDiagnostics(JSON.stringify([{message: "Semantic diagnostics replaced!", category: "message", code: "semantic-diagnostics-replaced"}], undefined, 2)); +verify.getSyntacticDiagnostics(JSON.stringify([{message: "Syntactic diagnostics replaced!", category: "message", code: "syntactic-diagnostics-replaced"}], undefined, 2)); +verify.completionListContains("fakeCompletion", "", undefined, ""); +verify.completionEntryDetailIs("fakeCompletion", "", undefined, "0"); +verify.quickInfoIs(undefined, undefined); +verify.nameOrDottedNameSpanTextIs(""); +verify.signatureHelpArgumentCountIs(0); +verify.definitionCountIs(0); +verify.referencesAre([]); +verify.todoCommentsInCurrentFile([]); +verify.noMatchingBracePositionInCurrentFile(0); +verify.DocCommentTemplate("/********Yes.*********/", 9); diff --git a/tests/cases/extensions/scenarios/languageServiceExtensions/can-add-program-diagnostics.json b/tests/cases/extensions/scenarios/languageServiceExtensions/can-add-program-diagnostics.json new file mode 100644 index 0000000000000..842c7d267eae7 --- /dev/null +++ b/tests/cases/extensions/scenarios/languageServiceExtensions/can-add-program-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-language-service"], + "compilerOptions": { + "extensions": ["test-language-service"] + }, + "fourslashTest": "test.ts" +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/languageServiceExtensions/can-chain-services.json b/tests/cases/extensions/scenarios/languageServiceExtensions/can-chain-services.json new file mode 100644 index 0000000000000..c33df892e4cd2 --- /dev/null +++ b/tests/cases/extensions/scenarios/languageServiceExtensions/can-chain-services.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "hello-error.ts" + ], + "availableExtensions": ["test-service-chain"], + "compilerOptions": { + "extensions": ["test-service-chain"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-all-functions.json b/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-all-functions.json new file mode 100644 index 0000000000000..c33c6b1be8eb5 --- /dev/null +++ b/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-all-functions.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "atotc.ts" + ], + "availableExtensions": ["test-service-filters"], + "compilerOptions": { + "extensions": ["test-service-filters"] + }, + "fourslashTest": "verify-overridden-diagnostics.ts" +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-passthru.json b/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-passthru.json new file mode 100644 index 0000000000000..56e690cefd160 --- /dev/null +++ b/tests/cases/extensions/scenarios/languageServiceExtensions/can-filter-passthru.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "hello-error.ts" + ], + "availableExtensions": ["test-service-passthru"], + "compilerOptions": { + "extensions": ["test-service-passthru"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/languageServiceExtensions/can-override-all-functions.json b/tests/cases/extensions/scenarios/languageServiceExtensions/can-override-all-functions.json new file mode 100644 index 0000000000000..d557d8bb5ed01 --- /dev/null +++ b/tests/cases/extensions/scenarios/languageServiceExtensions/can-override-all-functions.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "atotc.ts" + ], + "availableExtensions": ["test-service-overrides"], + "compilerOptions": { + "extensions": ["test-service-overrides"] + }, + "fourslashTest": "verify-overridden-diagnostics.ts" +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/multiLintLoads/both-diagnostics.json b/tests/cases/extensions/scenarios/multiLintLoads/both-diagnostics.json new file mode 100644 index 0000000000000..5cf8f90fcedf3 --- /dev/null +++ b/tests/cases/extensions/scenarios/multiLintLoads/both-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "foo-interface-const.ts" + ], + "availableExtensions": ["test-syntactic-lint", "test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint", "test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/multiLintLoads/no-diagnostics.json b/tests/cases/extensions/scenarios/multiLintLoads/no-diagnostics.json new file mode 100644 index 0000000000000..8adfabcb3f981 --- /dev/null +++ b/tests/cases/extensions/scenarios/multiLintLoads/no-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-syntactic-lint", "test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint", "test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/multiLintLoads/semantic-diagnostics.json b/tests/cases/extensions/scenarios/multiLintLoads/semantic-diagnostics.json new file mode 100644 index 0000000000000..96c6320f69679 --- /dev/null +++ b/tests/cases/extensions/scenarios/multiLintLoads/semantic-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "foo-const.ts" + ], + "availableExtensions": ["test-syntactic-lint", "test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint", "test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/multiLintLoads/syntactic-diagnostics.json b/tests/cases/extensions/scenarios/multiLintLoads/syntactic-diagnostics.json new file mode 100644 index 0000000000000..eada4a0fb89b7 --- /dev/null +++ b/tests/cases/extensions/scenarios/multiLintLoads/syntactic-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "foo-interface.ts" + ], + "availableExtensions": ["test-syntactic-lint", "test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint", "test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/multipleRulesFoundInSingleExtension/test.json b/tests/cases/extensions/scenarios/multipleRulesFoundInSingleExtension/test.json new file mode 100644 index 0000000000000..3db9277bb0863 --- /dev/null +++ b/tests/cases/extensions/scenarios/multipleRulesFoundInSingleExtension/test.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "foo-bar-const-interface.ts" + ], + "availableExtensions": ["test-multi-extension"], + "compilerOptions": { + "extensions": ["test-multi-extension"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/passArguments/array.json b/tests/cases/extensions/scenarios/passArguments/array.json new file mode 100644 index 0000000000000..e1556cdab97a8 --- /dev/null +++ b/tests/cases/extensions/scenarios/passArguments/array.json @@ -0,0 +1,11 @@ +{ + "inputFiles": [ + "foo-interface.ts" + ], + "availableExtensions": ["test-extension-arguments"], + "compilerOptions": { + "extensions": { + "test-extension-arguments": ["a", "b"] + } + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/profileExtensionsTraces/test.json b/tests/cases/extensions/scenarios/profileExtensionsTraces/test.json new file mode 100644 index 0000000000000..9544e514cb2b6 --- /dev/null +++ b/tests/cases/extensions/scenarios/profileExtensionsTraces/test.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-multi-extension"], + "compilerOptions": { + "extensions": ["test-multi-extension"], + "profileExtensions": 2 + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/reportsAllDIagnosticsFormats/test.json b/tests/cases/extensions/scenarios/reportsAllDIagnosticsFormats/test.json new file mode 100644 index 0000000000000..e779598ac5ccf --- /dev/null +++ b/tests/cases/extensions/scenarios/reportsAllDIagnosticsFormats/test.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-errors"], + "compilerOptions": { + "extensions": ["test-errors"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/reportsDiagnosticsWithShortnames/test.json b/tests/cases/extensions/scenarios/reportsDiagnosticsWithShortnames/test.json new file mode 100644 index 0000000000000..a383a4aa06293 --- /dev/null +++ b/tests/cases/extensions/scenarios/reportsDiagnosticsWithShortnames/test.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "foo-bar-math.ts" + ], + "availableExtensions": ["test-multierrors"], + "compilerOptions": { + "extensions": ["test-multierrors"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/reportsFailedLoads/test.json b/tests/cases/extensions/scenarios/reportsFailedLoads/test.json new file mode 100644 index 0000000000000..1ccf2b0a8a70b --- /dev/null +++ b/tests/cases/extensions/scenarios/reportsFailedLoads/test.json @@ -0,0 +1,9 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": [], + "compilerOptions": { + "extensions": ["test-syntactic-lint", "test-semantic-lint"] + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/semanticLintLoads/no-diagnostics.json b/tests/cases/extensions/scenarios/semanticLintLoads/no-diagnostics.json new file mode 100644 index 0000000000000..d04083aedd426 --- /dev/null +++ b/tests/cases/extensions/scenarios/semanticLintLoads/no-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/semanticLintLoads/w-diagnostics.json b/tests/cases/extensions/scenarios/semanticLintLoads/w-diagnostics.json new file mode 100644 index 0000000000000..06736c30bb9f5 --- /dev/null +++ b/tests/cases/extensions/scenarios/semanticLintLoads/w-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "foo-const.ts" + ], + "availableExtensions": ["test-semantic-lint"], + "compilerOptions": { + "extensions": ["test-semantic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/syntacticLintLoads/no-diagnostics.json b/tests/cases/extensions/scenarios/syntacticLintLoads/no-diagnostics.json new file mode 100644 index 0000000000000..194510f8c0060 --- /dev/null +++ b/tests/cases/extensions/scenarios/syntacticLintLoads/no-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "hello.ts" + ], + "availableExtensions": ["test-syntactic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/scenarios/syntacticLintLoads/w-diagnostics.json b/tests/cases/extensions/scenarios/syntacticLintLoads/w-diagnostics.json new file mode 100644 index 0000000000000..e22c0391a15cb --- /dev/null +++ b/tests/cases/extensions/scenarios/syntacticLintLoads/w-diagnostics.json @@ -0,0 +1,10 @@ +{ + "inputFiles": [ + "foo-interface.ts" + ], + "availableExtensions": ["test-syntactic-lint"], + "compilerOptions": { + "extensions": ["test-syntactic-lint"], + "traceResolution": true + } +} \ No newline at end of file diff --git a/tests/cases/extensions/source/atotc.ts b/tests/cases/extensions/source/atotc.ts new file mode 100644 index 0000000000000..9818c6d2f434c --- /dev/null +++ b/tests/cases/extensions/source/atotc.ts @@ -0,0 +1,11 @@ +It was the best of times, it was the worst of times, +it was the age of wisdom, it was the age of foolishness, +it was the epoch of belief, it was the epoch of incredulity, +it was the season of Light, it was the season of Darkness, +it was the spring of hope, it was the winter of despair, +we had everything before us, we had nothing before us, +we were all going direct to Heaven, we were all going direct +the other way--in short, the period was so far like the present +period, that some of its noisiest authorities insisted on its +being received, for good or for evil, in the superlative degree +of comparison only. \ No newline at end of file diff --git a/tests/cases/extensions/source/foo-bar-const-interface.ts b/tests/cases/extensions/source/foo-bar-const-interface.ts new file mode 100644 index 0000000000000..86cecfd018b5c --- /dev/null +++ b/tests/cases/extensions/source/foo-bar-const-interface.ts @@ -0,0 +1,4 @@ +interface Foo {b;} +interface Bar {a;} +const f: "foo" = "foo"; +let b: "bar" = "bar"; \ No newline at end of file diff --git a/tests/cases/extensions/source/foo-bar-math.ts b/tests/cases/extensions/source/foo-bar-math.ts new file mode 100644 index 0000000000000..c46bb83566937 --- /dev/null +++ b/tests/cases/extensions/source/foo-bar-math.ts @@ -0,0 +1,3 @@ +const foo = 3; +const bar = 4; +const x = 3 * 4; \ No newline at end of file diff --git a/tests/cases/extensions/source/foo-const.ts b/tests/cases/extensions/source/foo-const.ts new file mode 100644 index 0000000000000..2d6d0b7189ca5 --- /dev/null +++ b/tests/cases/extensions/source/foo-const.ts @@ -0,0 +1 @@ +const s: "foo" = "foo"; \ No newline at end of file diff --git a/tests/cases/extensions/source/foo-interface-const.ts b/tests/cases/extensions/source/foo-interface-const.ts new file mode 100644 index 0000000000000..5161785a831c7 --- /dev/null +++ b/tests/cases/extensions/source/foo-interface-const.ts @@ -0,0 +1,2 @@ +interface Foo {a; b;} +const s: "foo" = "foo"; \ No newline at end of file diff --git a/tests/cases/extensions/source/foo-interface.ts b/tests/cases/extensions/source/foo-interface.ts new file mode 100644 index 0000000000000..ef4afbc1b3fef --- /dev/null +++ b/tests/cases/extensions/source/foo-interface.ts @@ -0,0 +1 @@ +interface Foo {a; b;} \ No newline at end of file diff --git a/tests/cases/extensions/source/hello-error.ts b/tests/cases/extensions/source/hello-error.ts new file mode 100644 index 0000000000000..251cc73498d66 --- /dev/null +++ b/tests/cases/extensions/source/hello-error.ts @@ -0,0 +1 @@ +console.log("Hello, error!") - \ No newline at end of file diff --git a/tests/cases/extensions/source/hello.ts b/tests/cases/extensions/source/hello.ts new file mode 100644 index 0000000000000..97d87624465a4 --- /dev/null +++ b/tests/cases/extensions/source/hello.ts @@ -0,0 +1 @@ +console.log("Hello, world!");/*EOL*/ \ No newline at end of file