mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Support rename in comments and strings.
This commit is contained in:
parent
00e5b15a05
commit
2a8b9ef21f
@ -2575,7 +2575,7 @@ module ts {
|
||||
function getStringLiteralType(node: StringLiteralTypeNode): StringLiteralType {
|
||||
if (hasProperty(stringLiteralTypes, node.text)) return stringLiteralTypes[node.text];
|
||||
var type = stringLiteralTypes[node.text] = <StringLiteralType>createType(TypeFlags.StringLiteral);
|
||||
type.text = getSourceTextOfNode(node);
|
||||
type.text = getTextOfNode(node);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -7430,7 +7430,7 @@ module ts {
|
||||
while (!isUniqueLocalName(escapeIdentifier(prefix + name), container)) {
|
||||
prefix += "_";
|
||||
}
|
||||
links.localModuleName = prefix + getSourceTextOfNode(container.name);
|
||||
links.localModuleName = prefix + getTextOfNode(container.name);
|
||||
}
|
||||
return links.localModuleName;
|
||||
}
|
||||
|
||||
@ -54,11 +54,11 @@ module ts {
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
|
||||
}
|
||||
|
||||
export function getSourceTextOfNodeFromSourceText(sourceText: string, node: Node): string {
|
||||
export function getTextOfNodeFromSourceText(sourceText: string, node: Node): string {
|
||||
return sourceText.substring(skipTrivia(sourceText, node.pos), node.end);
|
||||
}
|
||||
|
||||
export function getSourceTextOfNode(node: Node): string {
|
||||
export function getTextOfNode(node: Node): string {
|
||||
var text = getSourceFileOfNode(node).text;
|
||||
return text.substring(skipTrivia(text, node.pos), node.end);
|
||||
}
|
||||
@ -75,7 +75,7 @@ module ts {
|
||||
|
||||
// Return display name of an identifier
|
||||
export function identifierToString(identifier: Identifier) {
|
||||
return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getSourceTextOfNode(identifier);
|
||||
return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getTextOfNode(identifier);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
||||
@ -3045,7 +3045,7 @@ module ts {
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
|
||||
if (labelledStatementInfo.nodeIsNestedInLabel(node.label, /*requireIterationStatement*/ false, /*stopAtFunctionBoundary*/ true)) {
|
||||
grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getSourceTextOfNodeFromSourceText(sourceText, node.label));
|
||||
grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNodeFromSourceText(sourceText, node.label));
|
||||
}
|
||||
labelledStatementInfo.addLabel(node.label);
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ class TypeWriterWalker {
|
||||
private log(node: ts.Node, type: ts.Type): void {
|
||||
var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterFromPosition(actualPos);
|
||||
var sourceText = ts.getSourceTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||
var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||
|
||||
// If we got an unknown type, we temporarily want to fall back to just pretending the name
|
||||
// (source text) of the node is the type. This is to align with the old typeWriter to make
|
||||
|
||||
@ -666,6 +666,8 @@ module ts {
|
||||
getSignatureAtPosition(fileName: string, position: number): SignatureInfo;
|
||||
|
||||
getRenameInfo(fileName: string, position: number): RenameInfo;
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
|
||||
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
|
||||
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[];
|
||||
@ -757,6 +759,11 @@ module ts {
|
||||
newText: string;
|
||||
}
|
||||
|
||||
export interface RenameLocation {
|
||||
textSpan: TypeScript.TextSpan;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export interface ReferenceEntry {
|
||||
textSpan: TypeScript.TextSpan;
|
||||
fileName: string;
|
||||
@ -3062,11 +3069,19 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencesAtPosition(filename: string, position: number): ReferenceEntry[] {
|
||||
function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
return findReferences(fileName, position, findInStrings, findInComments);
|
||||
}
|
||||
|
||||
function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
|
||||
return findReferences(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false);
|
||||
}
|
||||
|
||||
function findReferences(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferenceEntry[] {
|
||||
synchronizeHostData();
|
||||
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
fileName = TypeScript.switchToForwardSlashes(fileName);
|
||||
var sourceFile = getSourceFile(fileName);
|
||||
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
@ -3082,7 +3097,86 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getReferencesForNode(node, program.getSourceFiles());
|
||||
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral);
|
||||
var references = getReferencesForNode(node, program.getSourceFiles());
|
||||
|
||||
var name = (<Identifier>node).text;
|
||||
var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</
|
||||
|
||||
if (findInStrings) {
|
||||
forEach(program.getSourceFiles(), addStringReferences);
|
||||
}
|
||||
|
||||
if (findInComments) {
|
||||
forEach(program.getSourceFiles(), addCommentReferences);
|
||||
}
|
||||
|
||||
return references;
|
||||
|
||||
function addReferencesInRawText(rawText: string, rawTextPositionInSourceText: number, sourceText: string) {
|
||||
var matchIndex = 0;
|
||||
while ((matchIndex = rawText.indexOf(name, matchIndex)) >= 0) {
|
||||
// Only consider it a match if there isn't a letter/number before or after
|
||||
// the match.
|
||||
var indexInSourceText = rawTextPositionInSourceText + matchIndex;
|
||||
|
||||
if (indexInSourceText === 0 || !isIdentifierPart(sourceText.charCodeAt(indexInSourceText - 1), ScriptTarget.ES5)) {
|
||||
var matchEnd = indexInSourceText + name.length;
|
||||
if (matchEnd >= sourceText.length || !isIdentifierPart(sourceText.charCodeAt(matchEnd), ScriptTarget.ES5)) {
|
||||
|
||||
references.push({
|
||||
fileName: sourceFile.filename,
|
||||
textSpan: new TypeScript.TextSpan(indexInSourceText, name.length),
|
||||
isWriteAccess: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
matchIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
function addCommentReferences(sourceFile: SourceFile) {
|
||||
var sourceText = sourceFile.text;
|
||||
forEachChild(sourceFile, addCommentReferencesInNode);
|
||||
|
||||
function addCommentReferencesInNode(node: Node) {
|
||||
if (isToken(node)) {
|
||||
// Found a token, walk its comments (if it has any) for matches).
|
||||
forEach(getLeadingCommentRanges(sourceText, node.pos), addReferencesInCommentRange);
|
||||
}
|
||||
else {
|
||||
forEach(node.getChildren(), addCommentReferencesInNode);
|
||||
}
|
||||
}
|
||||
|
||||
function addReferencesInCommentRange(range: CommentRange) {
|
||||
var commentText = sourceText.substring(range.pos, range.end);
|
||||
|
||||
// Don't add matches in ///<reference comments. We don't want to
|
||||
// unintentionally update a file name.
|
||||
if (!tripleSlashDirectivePrefixRegex.test(commentText)) {
|
||||
addReferencesInRawText(commentText, range.pos, sourceText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addStringReferences(sourceFile: SourceFile) {
|
||||
var sourceText = sourceFile.text;
|
||||
|
||||
forEachChild(sourceFile, addStringReferencesInNode);
|
||||
|
||||
function addStringReferencesInNode(node: Node) {
|
||||
if (node.kind === SyntaxKind.StringLiteral) {
|
||||
// Found a string literal. See if we can find any matches in it.
|
||||
addReferencesInRawText(getTextOfNodeFromSourceText(sourceText, node), node.getStart(sourceFile), sourceText);
|
||||
}
|
||||
else {
|
||||
// Recurse and keep looking for references in strings.
|
||||
forEachChild(node, addStringReferencesInNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencesForNode(node: Node, sourceFiles: SourceFile[]): ReferenceEntry[] {
|
||||
@ -4590,6 +4684,7 @@ module ts {
|
||||
getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
|
||||
getNavigateToItems: getNavigateToItems,
|
||||
getRenameInfo: getRenameInfo,
|
||||
findRenameLocations: findRenameLocations,
|
||||
getNavigationBarItems: getNavigationBarItems,
|
||||
getOutliningSpans: getOutliningSpans,
|
||||
getTodoComments: getTodoComments,
|
||||
|
||||
@ -102,6 +102,12 @@ module ts {
|
||||
*/
|
||||
getRenameInfo(fileName: string, position: number): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { fileName: string, textSpan: { start: number, length: number } }[]
|
||||
*/
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string }
|
||||
@ -650,6 +656,14 @@ module ts {
|
||||
});
|
||||
}
|
||||
|
||||
public findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): string {
|
||||
return this.forwardJSONCall(
|
||||
"findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")",
|
||||
() => {
|
||||
return this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments);
|
||||
});
|
||||
}
|
||||
|
||||
/// GET BRACE MATCHING
|
||||
public getBraceMatchingAtPosition(fileName: string, position: number): string {
|
||||
return this.forwardJSONCall(
|
||||
|
||||
@ -222,7 +222,7 @@ module ts {
|
||||
return n.kind !== SyntaxKind.SyntaxList || n.getChildCount() !== 0;
|
||||
}
|
||||
|
||||
function isToken(n: Node): boolean {
|
||||
export function isToken(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user