Skip to content

Conversation

johnfav03
Copy link

@johnfav03 johnfav03 commented Sep 9, 2025

This PR implements provideDocumentHighlights and the corresponding fourslash tests/functions; the implementation covers syntactic highlights fully, but is missing several cases in semantic highlights due to unimplemented cases in getReferencedSymbolsForNode. Some prevalent examples from the failing test cases include:

  • export logic in getReferencedSymbolsForSymbol
    • cases: getDocumentHighlightInExport, getDocumentHighlightInTypeExport`
  • getReferencesForStringLiteral in getReferencedSymbolsForNode
    • cases: getDocumentHighlightTemplateStrings, getOccurrencesStringLiterals, getOccurrencesStringLiteralTypes
  • constructor logic in getReferencesAtLocation
    • cases: getOccurencesClassExpressionConstructor, getOccurrencesConstructor, getOccurrencesConstructor2

@johnfav03
Copy link
Author

@johnfav03 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

@johnfav03 johnfav03 marked this pull request as ready for review September 17, 2025 21:04
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for "Document highlights" functionality in the testing framework. Document highlights show related occurrences of symbols in a document when the user hovers or selects a symbol.

  • Adds a new baseline test type for documentHighlights test cases
  • Creates extensive test coverage for various TypeScript language constructs including classes, interfaces, keywords, modifiers, and control flow statements
  • Includes test cases for edge cases like inherited properties, parameter properties, and JSX elements

Reviewed Changes

Copilot reviewed 224 out of 224 changed files in this pull request and generated no comments.

Show a summary per file
File Description
testdata/baselines/reference/submodule/fourslash/findRenameLocations/renameDefaultImportDifferentName.baseline.jsonc.diff Diff file showing baseline changes for rename functionality
testdata/baselines/reference/submodule/fourslash/findRenameLocations/renameDefaultImportDifferentName.baseline.jsonc Baseline for testing rename operations on default imports with different names
testdata/baselines/reference/fourslash/findAllReferences/renameDefaultImportDifferentName.baseline.jsonc Baseline for find all references functionality on default imports
testdata/baselines/reference/fourslash/findAllReferences/findReferencesJSXTagName3.baseline.jsonc Baseline for finding references in JSX tag names
testdata/baselines/reference/fourslash/documentHighlights/*.baseline.jsonc 100+ baseline files covering document highlights for various TypeScript constructs including keywords, modifiers, classes, interfaces, control flow, and edge cases

@johnfav03 johnfav03 requested a review from iisaduan September 17, 2025 21:10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a pattern among the failing tests, i.e. something they’re blocked on or a specific follow-up task?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are giving an incorrect output due to a missing case in getReferencedSymbolsForNode() in findAllReferences - I'll update the PR description with cases that could be updated as a follow-up task

Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great first PR 👏

Copy link
Member

@iisaduan iisaduan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Seems like you've quickly gotten a good hang of the codebase :D

Requesting changes because I noticed an incorrect port of some logic, and I also left comments on some refactors and code/comment clean up

}
}
else if (ts.isObjectLiteralExpression(arg)) {
// User preferences case, but multiple files isn't implemented in corsa yet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "multiple files isn't implemented in corsa yet"? Does this fourslash function need different options per file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document highlights has the option search multiple files for references, but Jake told me to ignore this feature; this else if branch is searching for an input parameter that looks like {filesToSearch: ...}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, LSP does not have the ability to return document highlights outside the file where the request occurred.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I am not sure the old code to do so even worked in VS Code.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, vscode doesnt request/handle symbols across multiple files (old vscode extension) and is unused in any strada test, so totally removing/not porting it is probably the way to go

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, https://github.com/microsoft/vscode/blob/07da241ca964f5bb4e618c68c828fcba815e1045/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts#L17 did actually do it, but that's not in the LSP. We could still do this in the future. I'm not sure it's worth it at the moment to do multi-file highlights, but we may want it for script tag reasons and for embedded languages and so on. But, needs to go into the LSP.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, makes sense. I wasn't ever able to get it to trigger in vscode so I assumeed it was never fully implemented. We can leave it as a !!! todo when in lsp in the ls implementation, and later update to match the format in vscode.proposed, but I don't think we need to support it in fourslash conversion if we don't have tests that use it

return []*ast.Node{node}
}
if ast.IsFunctionLike(node) {
return []*ast.Node{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return []*ast.Node{}
return nil


breakAndContinueStatements := aggregateAllBreakAndContinueStatements(clause, sourceFile)
for _, statement := range breakAndContinueStatements {
if ownsBreakOrContinueStatement(switchStatement.AsNode(), statement) && statement.Kind == ast.KindBreakStatement {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to avoid unneded calls to findAncestor

Suggested change
if ownsBreakOrContinueStatement(switchStatement.AsNode(), statement) && statement.Kind == ast.KindBreakStatement {
if statement.Kind == ast.KindBreakStatement && ownsBreakOrContinueStatement(switchStatement.AsNode(), statement) {

finallyBlock := statement.FinallyBlock

if catchClause != nil {
result = append(result, aggregateOwnedThrowStatements(catchClause, sourceFile)...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could do this to all the cases so that we don't need to do the work of copying the slice again

Suggested change
result = append(result, aggregateOwnedThrowStatements(catchClause, sourceFile)...)
result = aggregateOwnedThrowStatements(catchClause, sourceFile)

if catchClause != nil {
result = append(result, aggregateOwnedThrowStatements(catchClause, sourceFile)...)
} else if tryBlock != nil {
result = append(result, aggregateOwnedThrowStatements(tryBlock, sourceFile)...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = append(result, aggregateOwnedThrowStatements(tryBlock, sourceFile)...)
result = aggregateOwnedThrowStatements(tryBlock, sourceFile)

return []*ast.Node{node}
}
if ast.IsTryStatement(node) {
var result []*ast.Node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move this var declaration (and other similar declarations) to right before the block where it's first written to (this case, the if catchClause != nil)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants