Revert to using spread instead of mutating value later

This commit is contained in:
Sheetal Nandi
2019-06-12 14:29:43 -07:00
parent a84ed93f72
commit da2aa9781e
8 changed files with 115 additions and 127 deletions

View File

@@ -396,11 +396,14 @@ namespace ts.server {
for (const entry of body.locs) {
const fileName = entry.file;
for (const { start, end, declarationStart, declarationEnd, ...prefixSuffixText } of entry.locs) {
const renameLocation: RenameLocation = { textSpan: this.decodeSpan({ start, end }, fileName), fileName, ...prefixSuffixText };
if (declarationStart !== undefined) {
renameLocation.declarationSpan = this.decodeSpan({ start: declarationStart, end: declarationEnd! }, fileName);
}
locations.push(renameLocation);
locations.push({
textSpan: this.decodeSpan({ start, end }, fileName),
fileName,
...(declarationStart !== undefined ?
{ declarationSpan: this.decodeSpan({ start: declarationStart, end: declarationEnd! }, fileName) } :
undefined),
...prefixSuffixText
});
}
}

View File

@@ -957,17 +957,16 @@ namespace FourSlash {
definition: typeof definition === "string" ? definition : { ...definition, range: ts.createTextSpanFromRange(definition.range) },
references: ranges.map<ts.ReferenceEntry>(r => {
const { isWriteAccess = false, isDefinition = false, isInString, declarationRangeIndex } = (r.marker && r.marker.data || {}) as { isWriteAccess?: boolean, isDefinition?: boolean, isInString?: true, declarationRangeIndex?: number };
const result: ts.ReferenceEntry = {
return {
fileName: r.fileName,
textSpan: ts.createTextSpanFromRange(r),
isWriteAccess,
isDefinition,
...(declarationRangeIndex !== undefined ?
{ declarationSpan: ts.createTextSpanFromRange(this.getRanges()[declarationRangeIndex]) } :
undefined),
...(isInString ? { isInString: true } : undefined),
};
if (declarationRangeIndex !== undefined) {
result.declarationSpan = ts.createTextSpanFromRange(this.getRanges()[declarationRangeIndex]);
}
return result;
}),
}));
@@ -1192,14 +1191,17 @@ Actual: ${stringify(fullActual)}`);
const sort = (locations: ReadonlyArray<ts.RenameLocation> | undefined) =>
locations && ts.sort(locations, (r1, r2) => ts.compareStringsCaseSensitive(r1.fileName, r2.fileName) || r1.textSpan.start - r2.textSpan.start);
assert.deepEqual(sort(references), sort(ranges.map(rangeOrOptions => {
assert.deepEqual(sort(references), sort(ranges.map((rangeOrOptions): ts.RenameLocation => {
const { range, ...prefixSuffixText } = "range" in rangeOrOptions ? rangeOrOptions : { range: rangeOrOptions };
const result: ts.RenameLocation = { fileName: range.fileName, textSpan: ts.createTextSpanFromRange(range), ...prefixSuffixText };
const { declarationRangeIndex } = (range.marker && range.marker.data || {}) as { declarationRangeIndex?: number; };
if (declarationRangeIndex !== undefined) {
result.declarationSpan = ts.createTextSpanFromRange(this.getRanges()[declarationRangeIndex]);
}
return result;
return {
fileName: range.fileName,
textSpan: ts.createTextSpanFromRange(range),
...(declarationRangeIndex !== undefined ?
{ declarationSpan: ts.createTextSpanFromRange(this.getRanges()[declarationRangeIndex]) } :
undefined),
...prefixSuffixText
};
})));
}
}

View File

@@ -1066,14 +1066,11 @@ namespace ts.server {
}
private toDeclarationFileSpan(fileName: string, textSpan: TextSpan, declarationSpan: TextSpan | undefined, project: Project): protocol.DeclarationFileSpan {
const result = this.toFileSpan(fileName, textSpan, project) as protocol.DeclarationFileSpan;
if (declarationSpan) {
const declaration = this.toFileSpan(fileName, declarationSpan, project);
result.declarationStart = declaration.start;
result.declarationEnd = declaration.end;
}
return result;
const fileSpan = this.toFileSpan(fileName, textSpan, project);
const declaration = declarationSpan && this.toFileSpan(fileName, declarationSpan, project);
return declaration ?
{ ...fileSpan, declarationStart: declaration.start, declarationEnd: declaration.end } :
fileSpan;
}
private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.DeclarationFileSpan> {
@@ -1099,36 +1096,27 @@ namespace ts.server {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
const implementations = this.mapImplementationLocations(project.getLanguageService().getImplementationAtPosition(file, position) || emptyArray, project);
if (simplifiedResult) {
return implementations.map(({ fileName, textSpan, declarationSpan }) => this.toDeclarationFileSpan(fileName, textSpan, declarationSpan, project));
}
return implementations.map(Session.mapToOriginalLocation);
return simplifiedResult ?
implementations.map(({ fileName, textSpan, declarationSpan }) => this.toDeclarationFileSpan(fileName, textSpan, declarationSpan, project)) :
implementations.map(Session.mapToOriginalLocation);
}
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
if (!occurrences) {
return emptyArray;
}
return occurrences.map(occurrence => {
const { fileName, isWriteAccess, textSpan, isInString, declarationSpan } = occurrence;
const scriptInfo = project.getScriptInfo(fileName)!;
const result = toProtocolDeclarationTextSpan(textSpan, declarationSpan, scriptInfo) as protocol.OccurrencesResponseItem;
result.file = fileName;
result.isWriteAccess = isWriteAccess;
// no need to serialize the property if it is not true
if (isInString) {
result.isInString = isInString;
}
return result;
});
return occurrences ?
occurrences.map<protocol.OccurrencesResponseItem>(occurrence => {
const { fileName, isWriteAccess, textSpan, isInString, declarationSpan } = occurrence;
const scriptInfo = project.getScriptInfo(fileName)!;
return {
...toProtocolDeclarationTextSpan(textSpan, declarationSpan, scriptInfo),
file: fileName,
isWriteAccess,
...(isInString ? { isInString } : undefined)
};
}) :
emptyArray;
}
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
@@ -1178,11 +1166,10 @@ namespace ts.server {
const scriptInfo = project.getScriptInfo(fileName)!;
return {
file: fileName,
highlightSpans: highlightSpans.map(({ textSpan, kind, declarationSpan }) => {
const result = toProtocolDeclarationTextSpan(textSpan, declarationSpan, scriptInfo) as protocol.HighlightSpan;
result.kind = kind;
return result;
})
highlightSpans: highlightSpans.map(({ textSpan, kind, declarationSpan }) => ({
...toProtocolDeclarationTextSpan(textSpan, declarationSpan, scriptInfo),
kind
}))
};
});
}
@@ -1328,8 +1315,7 @@ namespace ts.server {
isDefinition
};
}));
const result: protocol.ReferencesResponseBody = { refs, symbolName, symbolStartOffset, symbolDisplayString };
return result;
return { refs, symbolName, symbolStartOffset, symbolDisplayString };
}
/**
* @param fileName is the name of the file to be opened
@@ -2580,11 +2566,11 @@ namespace ts.server {
}
function toProtocolDeclarationTextSpan(span: TextSpan, declarationSpan: TextSpan | undefined, scriptInfo: ScriptInfo): protocol.DeclarationTextSpan {
const result = toProcolTextSpan(span, scriptInfo) as protocol.DeclarationTextSpan;
if (!declarationSpan) return result;
result.declarationStart = scriptInfo.positionToLineOffset(declarationSpan.start);
result.declarationEnd = scriptInfo.positionToLineOffset(textSpanEnd(declarationSpan));
return result;
const textSpan = toProcolTextSpan(span, scriptInfo);
const declarationTextSpan = declarationSpan && toProcolTextSpan(declarationSpan, scriptInfo);
return declarationTextSpan ?
{ ...textSpan, declarationStart: declarationTextSpan.start, declarationEnd: declarationTextSpan.end } :
textSpan;
}
function convertTextChangeToCodeEdit(change: TextChange, scriptInfo: ScriptInfoOrConfig): protocol.CodeEdit {

View File

@@ -161,15 +161,14 @@ namespace ts.FindAllReferences {
}
}
export function setDeclarationSpan(span: DocumentSpan, sourceFile: SourceFile, declaration?: DeclarationNode) {
if (declaration) {
const declarationSpan = isDeclarationNodeWithStartAndEnd(declaration) ?
getTextSpan(declaration.start, sourceFile, declaration.end) :
getTextSpan(declaration, sourceFile);
if (declarationSpan.start !== span.textSpan.start || declarationSpan.length !== span.textSpan.length) {
span.declarationSpan = declarationSpan;
}
}
export function toDeclarationSpan(textSpan: TextSpan, sourceFile: SourceFile, declaration?: DeclarationNode): { declarationSpan: TextSpan } | undefined {
if (!declaration) return undefined;
const declarationSpan = isDeclarationNodeWithStartAndEnd(declaration) ?
getTextSpan(declaration.start, sourceFile, declaration.end) :
getTextSpan(declaration, sourceFile);
return declarationSpan.start !== textSpan.start || declarationSpan.length !== textSpan.length ?
{ declarationSpan } :
undefined;
}
export interface Options {
@@ -304,17 +303,17 @@ namespace ts.FindAllReferences {
const { node, name, kind, displayParts, declaration } = info;
const sourceFile = node.getSourceFile();
const result: ReferencedSymbolDefinitionInfo = {
const textSpan = getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile);
return {
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: sourceFile.fileName,
kind,
name,
textSpan: getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile),
displayParts
textSpan,
displayParts,
...toDeclarationSpan(textSpan, sourceFile, declaration)
};
setDeclarationSpan(result, sourceFile, declaration);
return result;
}
function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, node: Node): { displayParts: SymbolDisplayPart[], kind: ScriptElementKind } {
@@ -351,9 +350,12 @@ namespace ts.FindAllReferences {
}
else {
const sourceFile = entry.node.getSourceFile();
const result: DocumentSpan = { textSpan: getTextSpan(entry.node, sourceFile), fileName: sourceFile.fileName };
setDeclarationSpan(result, sourceFile, entry.declaration);
return result;
const textSpan = getTextSpan(entry.node, sourceFile);
return {
textSpan,
fileName: sourceFile.fileName,
...toDeclarationSpan(textSpan, sourceFile, entry.declaration)
};
}
}
@@ -438,10 +440,8 @@ namespace ts.FindAllReferences {
textSpan: documentSpan.textSpan,
kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference,
isInString: entry.kind === EntryKind.StringLiteral ? true : undefined,
...documentSpan.declarationSpan && { declarationSpan: documentSpan.declarationSpan }
};
if (documentSpan.declarationSpan) {
span.declarationSpan = documentSpan.declarationSpan;
}
return { fileName: documentSpan.fileName, span };
}

View File

@@ -273,20 +273,20 @@ namespace ts.GoToDefinition {
function createDefinitionInfoFromName(declaration: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo {
const name = getNameOfDeclaration(declaration) || declaration;
const sourceFile = name.getSourceFile();
const result: DefinitionInfo = {
const textSpan = createTextSpanFromNode(name, sourceFile);
return {
fileName: sourceFile.fileName,
textSpan: createTextSpanFromNode(name, sourceFile),
textSpan,
kind: symbolKind,
name: symbolName,
containerKind: undefined!, // TODO: GH#18217
containerName,
...FindAllReferences.toDeclarationSpan(
textSpan,
sourceFile,
FindAllReferences.getDeclarationForDeclarationSpan(declaration)
)
};
FindAllReferences.setDeclarationSpan(
result,
sourceFile,
FindAllReferences.getDeclarationForDeclarationSpan(declaration)
);
return result;
}
function createDefinitionFromSignatureDeclaration(typeChecker: TypeChecker, decl: SignatureDeclaration): DefinitionInfo {

View File

@@ -1546,19 +1546,14 @@ namespace ts {
function getOccurrencesAtPosition(fileName: string, position: number): ReadonlyArray<ReferenceEntry> | undefined {
return flatMap(
getDocumentHighlights(fileName, position, [fileName]),
entry => entry.highlightSpans.map(highlightSpan => {
const result: ReferenceEntry = {
fileName: entry.fileName,
textSpan: highlightSpan.textSpan,
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
isDefinition: false,
isInString: highlightSpan.isInString,
};
if (highlightSpan.declarationSpan) {
result.declarationSpan = highlightSpan.declarationSpan;
}
return result;
})
entry => entry.highlightSpans.map<ReferenceEntry>(highlightSpan => ({
fileName: entry.fileName,
textSpan: highlightSpan.textSpan,
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
isDefinition: false,
...highlightSpan.isInString && { isInString: true },
...highlightSpan.declarationSpan && { declarationSpan: highlightSpan.declarationSpan }
}))
);
}
@@ -1577,13 +1572,13 @@ namespace ts {
const node = getTouchingPropertyName(sourceFile, position);
if (isIdentifier(node) && (isJsxOpeningElement(node.parent) || isJsxClosingElement(node.parent)) && isIntrinsicJsxName(node.escapedText)) {
const { openingElement, closingElement } = node.parent.parent;
return [openingElement, closingElement].map(node => {
const result: RenameLocation = {
return [openingElement, closingElement].map((node): RenameLocation => {
const textSpan = createTextSpanFromNode(node.tagName, sourceFile);
return {
fileName: sourceFile.fileName,
textSpan: createTextSpanFromNode(node.tagName, sourceFile)
textSpan,
...FindAllReferences.toDeclarationSpan(textSpan, sourceFile, node.parent)
};
FindAllReferences.setDeclarationSpan(result, sourceFile, node.parent);
return result;
});
}
else {

View File

@@ -7,12 +7,12 @@ namespace ts.projectSystem {
declarationOptions?: SpanFromSubstringOptions;
}
function documentSpanFromSubstring({ file, text, declarationText, options, declarationOptions }: DocumentSpanFromSubstring): DocumentSpan {
const result: DocumentSpan = { fileName: file.path, textSpan: textSpanFromSubstring(file.content, text, options) };
if (declarationText) {
const declarationSpan = documentSpanFromSubstring({ file, text: declarationText, options: declarationOptions });
result.declarationSpan = declarationSpan.textSpan;
}
return result;
const declarationSpan = declarationText !== undefined ? documentSpanFromSubstring({ file, text: declarationText, options: declarationOptions }) : undefined;
return {
fileName: file.path,
textSpan: textSpanFromSubstring(file.content, text, options),
...declarationSpan && { declarationSpan: declarationSpan.textSpan }
};
}
function renameLocation(input: DocumentSpanFromSubstring): RenameLocation {

View File

@@ -523,13 +523,16 @@ namespace ts.projectSystem {
}
export function protocolDeclarationFileSpanFromSubstring({ declarationText, declarationOptions, ...rest }: DeclarationFileSpanFromSubString): protocol.DeclarationFileSpan {
const result = protocolFileSpanFromSubstring(rest);
if (!declarationText) return result;
const declarationSpan = protocolFileSpanFromSubstring({ file: rest.file, text: declarationText, options: declarationOptions });
return {
...result,
declarationStart: declarationSpan.start,
declarationEnd: declarationSpan.end
};
const declarationSpan = declarationText !== undefined ?
protocolFileSpanFromSubstring({ file: rest.file, text: declarationText, options: declarationOptions }) :
undefined;
return declarationSpan ?
{
...result,
declarationStart: declarationSpan.start,
declarationEnd: declarationSpan.end
} :
result;
}
export interface ProtocolDeclarationTextSpanFromString {
@@ -542,16 +545,15 @@ namespace ts.projectSystem {
export function protocolDeclarationTextSpanFromSubstring({ fileText, text, options, declarationText, declarationOptions }: ProtocolDeclarationTextSpanFromString): protocol.DeclarationTextSpan {
const span = textSpanFromSubstring(fileText, text, options);
const toLocation = protocolToLocation(fileText);
const result: protocol.DeclarationTextSpan = {
const declarationSpan = declarationText !== undefined ? textSpanFromSubstring(fileText, declarationText, declarationOptions) : undefined;
return {
start: toLocation(span.start),
end: toLocation(textSpanEnd(span))
end: toLocation(textSpanEnd(span)),
...declarationSpan && {
declarationStart: toLocation(declarationSpan.start),
declarationEnd: toLocation(textSpanEnd(declarationSpan))
}
};
if (declarationText) {
const span = textSpanFromSubstring(fileText, declarationText, declarationOptions);
result.declarationStart = toLocation(span.start);
result.declarationEnd = toLocation(textSpanEnd(span));
}
return result;
}
export interface ProtocolRenameSpanFromSubstring extends ProtocolDeclarationTextSpanFromString {