Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7646,7 +7646,8 @@ namespace ts {
}
}

function isDeclarationFileName(fileName: string): boolean {
/** @internal */
export function isDeclarationFileName(fileName: string): boolean {
return fileExtensionIs(fileName, Extension.Dts);
}

Expand Down
10 changes: 7 additions & 3 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2344,7 +2344,7 @@ namespace ts {
const refPath = resolveProjectReferencePath(host, ref);
// An absolute path pointing to the containing directory of the config file
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile;
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
if (sourceFile === undefined) {
return undefined;
}
Expand Down Expand Up @@ -2823,10 +2823,14 @@ namespace ts {
};
}

export interface ResolveProjectReferencePathHost {
fileExists(fileName: string): boolean;
}
/**
* Returns the target config filename of a project reference
* Returns the target config filename of a project reference.
* Note: The file might not exist.
*/
export function resolveProjectReferencePath(host: CompilerHost | UpToDateHost, ref: ProjectReference): ResolvedConfigFileName {
export function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName {
if (!host.fileExists(ref.path)) {
return combinePaths(ref.path, "tsconfig.json") as ResolvedConfigFileName;
}
Expand Down
22 changes: 11 additions & 11 deletions src/compiler/sourcemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,6 @@ namespace ts {
sourceMapDataList = undefined!;
}

interface SourceMapSection {
version: 3;
file: string;
sourceRoot?: string;
sources: string[];
names?: string[];
mappings: string;
sourcesContent?: (string | null)[];
sections?: undefined;
}

type SourceMapSectionDefinition =
| { offset: { line: number, column: number }, url: string } // Included for completeness
| { offset: { line: number, column: number }, map: SourceMap };
Expand Down Expand Up @@ -577,6 +566,17 @@ namespace ts {
}
}

export interface SourceMapSection {
version: 3;
file: string;
sourceRoot?: string;
sources: string[];
names?: string[];
mappings: string;
sourcesContent?: (string | null)[];
sections?: undefined;
}

const base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

function base64FormatEncode(inValue: number) {
Expand Down
17 changes: 12 additions & 5 deletions src/harness/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ namespace ts.server {
return { span: this.decodeSpan(codeEdit, fileName), newText: codeEdit.newText };
}

private processRequest<T extends protocol.Request>(command: string, args?: T["arguments"]): T {
private processRequest<T extends protocol.Request>(command: string, args: T["arguments"]): T {
const request: protocol.Request = {
seq: this.sequence,
type: "request",
Expand Down Expand Up @@ -278,17 +278,18 @@ namespace ts.server {

const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.DefinitionAndBoundSpan, args);
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
const body = Debug.assertDefined(response.body); // TODO: GH#18217

return {
definitions: response.body!.definitions.map(entry => ({ // TODO: GH#18217
definitions: body.definitions.map(entry => ({
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
name: ""
})),
textSpan: this.decodeSpan(response.body!.textSpan, request.arguments.file)
textSpan: this.decodeSpan(body.textSpan, request.arguments.file)
};
}

Expand Down Expand Up @@ -341,8 +342,10 @@ namespace ts.server {
}));
}

getEmitOutput(_fileName: string): EmitOutput {
return notImplemented();
getEmitOutput(file: string): EmitOutput {
const request = this.processRequest<protocol.EmitOutputRequest>(protocol.CommandTypes.EmitOutput, { file });
const response = this.processResponse<protocol.EmitOutputResponse>(request);
return response.body;
}

getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] {
Expand Down Expand Up @@ -716,6 +719,10 @@ namespace ts.server {
throw new Error("cleanupSemanticCache is not available through the server layer.");
}

getSourceMapper(): never {
return notImplemented();
}

dispose(): void {
throw new Error("dispose is not available through the server layer.");
}
Expand Down
64 changes: 39 additions & 25 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ namespace FourSlash {

// If any of the expected values are undefined, assume that users don't
// care about them.
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
if (replacementSpan && !ts.textSpansEqual(replacementSpan, entry.replacementSpan)) {
return false;
}
else if (expectedText && text !== expectedText) {
Expand Down Expand Up @@ -1644,7 +1644,7 @@ Actual: ${stringify(fullActual)}`);
});
}

public baselineGetEmitOutput(insertResultsIntoVfs?: boolean) {
private getEmitFiles(): ReadonlyArray<FourSlashFile> {
// Find file to be emitted
const emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on

Expand All @@ -1661,12 +1661,29 @@ Actual: ${stringify(fullActual)}`);
this.raiseError("No emitThisFile is specified in the test file");
}

return emitFiles;
}

public verifyGetEmitOutput(expectedOutputFiles: ReadonlyArray<string>): void {
const outputFiles = ts.flatMap(this.getEmitFiles(), e => this.languageService.getEmitOutput(e.fileName).outputFiles);

assert.deepEqual(outputFiles.map(f => f.name), expectedOutputFiles);

for (const { name, text } of outputFiles) {
const fromTestFile = this.getFileContent(name);
if (fromTestFile !== text) {
this.raiseError("Emit output is not as expected: " + showTextDiff(fromTestFile, text));
}
}
}

public baselineGetEmitOutput(): void {
Harness.Baseline.runBaseline(
this.testData.globalOptions[MetadataOptionNames.baselineFile],
ts.Debug.assertDefined(this.testData.globalOptions[MetadataOptionNames.baselineFile]),
() => {
let resultString = "";
// Loop through all the emittedFiles and emit them one by one
emitFiles.forEach(emitFile => {
for (const emitFile of this.getEmitFiles()) {
const emitOutput = this.languageService.getEmitOutput(emitFile.fileName);
// Print emitOutputStatus in readable format
resultString += "EmitSkipped: " + emitOutput.emitSkipped + Harness.IO.newLine();
Expand All @@ -1692,13 +1709,10 @@ Actual: ${stringify(fullActual)}`);

for (const outputFile of emitOutput.outputFiles) {
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
resultString = resultString + fileName + outputFile.text;
if (insertResultsIntoVfs) {
this.languageServiceAdapterHost.addScript(ts.getNormalizedAbsolutePath(outputFile.name, "/"), outputFile.text, /*isRootFile*/ true);
}
resultString = resultString + Harness.IO.newLine() + fileName + outputFile.text;
}
resultString += Harness.IO.newLine();
});
}

return resultString;
});
Expand Down Expand Up @@ -2137,11 +2151,10 @@ Actual: ${stringify(fullActual)}`);
this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0");
}

const duplicate = findDuplicatedElement(implementations, implementationsAreEqual);
const duplicate = findDuplicatedElement(implementations, ts.documentSpansEqual);
if (duplicate) {
const { textSpan, fileName } = duplicate;
const end = textSpan.start + textSpan.length;
this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`);
this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${ts.textSpanEnd(textSpan)}) in ${fileName}`);
}

const ranges = this.getRanges();
Expand Down Expand Up @@ -2208,10 +2221,6 @@ Actual: ${stringify(fullActual)}`);
this.raiseError(error);
}

function implementationsAreEqual(a: ImplementationLocationInformation, b: ImplementationLocationInformation) {
return a.fileName === b.fileName && TestState.textSpansEqual(a.textSpan, b.textSpan);
}

function displayPartIsEqualTo(a: ts.SymbolDisplayPart, b: ts.SymbolDisplayPart): boolean {
return a.kind === b.kind && a.text === b.text;
}
Expand Down Expand Up @@ -3260,7 +3269,7 @@ Actual: ${stringify(fullActual)}`);

if (spanIndex !== undefined) {
const span = this.getTextSpanForRangeAtIndex(spanIndex);
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + stringify(entryId)));
assert.isTrue(ts.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + stringify(entryId)));
}

eq(item.hasAction, hasAction, "hasAction");
Expand Down Expand Up @@ -3346,10 +3355,6 @@ Actual: ${stringify(fullActual)}`);
this.cancellationToken.resetCancelled();
}

private static textSpansEqual(a: ts.TextSpan | undefined, b: ts.TextSpan | undefined): boolean {
return !!a && !!b && a.start === b.start && a.length === b.length;
}

public getEditsForFileRename({ oldPath, newPath, newFileContents }: FourSlashInterface.GetEditsForFileRenameOptions): void {
const test = (fileContents: { readonly [fileName: string]: string }, description: string): void => {
const changes = this.languageService.getEditsForFileRename(oldPath, newPath, this.formatCodeSettings, ts.emptyOptions);
Expand Down Expand Up @@ -3551,8 +3556,13 @@ ${code}

function getNonFileNameOptionInObject(optionObject: { [s: string]: string }): string | undefined {
for (const option in optionObject) {
if (option !== MetadataOptionNames.fileName) {
return option;
switch (option) {
case MetadataOptionNames.fileName:
case MetadataOptionNames.baselineFile:
case MetadataOptionNames.emitThisFile:
break;
default:
return option;
}
}
return undefined;
Expand Down Expand Up @@ -4270,8 +4280,12 @@ namespace FourSlashInterface {
this.state.baselineCurrentFileNameOrDottedNameSpans();
}

public baselineGetEmitOutput(insertResultsIntoVfs?: boolean) {
this.state.baselineGetEmitOutput(insertResultsIntoVfs);
public getEmitOutput(expectedOutputFiles: ReadonlyArray<string>): void {
this.state.verifyGetEmitOutput(expectedOutputFiles);
}

public baselineGetEmitOutput() {
this.state.baselineGetEmitOutput();
}

public baselineQuickInfo() {
Expand Down
7 changes: 6 additions & 1 deletion src/harness/harnessLanguageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ namespace Harness.LanguageService {
getSourceFile(): ts.SourceFile {
throw new Error("SourceFile can not be marshaled across the shim layer.");
}
getSourceMapper(): never {
return ts.notImplemented();
}
dispose(): void { this.shim.dispose({}); }
}

Expand Down Expand Up @@ -704,7 +707,9 @@ namespace Harness.LanguageService {
return ts.sys.getEnvironmentVariable(name);
}

readDirectory() { return ts.notImplemented(); }
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
return this.host.readDirectory(path, extensions, exclude, include, depth);
}

watchFile(): ts.FileWatcher {
return { close: ts.noop };
Expand Down
2 changes: 2 additions & 0 deletions src/harness/virtualFileSystemWithWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ interface Array<T> {}`
}

export interface SymLink {
/** Location of the symlink. */
path: string;
/** Relative path to the real file. */
symLink: string;
}

Expand Down
Loading