-
Notifications
You must be signed in to change notification settings - Fork 649
noslash #991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
noslash #991
Changes from 14 commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
11307f8
fourslash skeleton
gabritto 437061f
refactor to test case parser, probably revert later
gabritto bb18b40
fourslash basic parsing
gabritto fc1391f
use io.Pipe
gabritto f3dd294
do some panic recovery
gabritto 28a330e
don't panic on repeated global options in test parser
gabritto 34dc3ae
more server/panic/etc fixes
gabritto 91a3a2d
fix nil references in server and completions, verify completions
gabritto c535d3e
Merge branch 'main' into gabritto/noslash
gabritto 8d8c751
add default capabilities
gabritto ab1fe19
refactor server to use lsp message reader/writer
gabritto bc81d49
add compiler options for inferred projects in server/service
gabritto 8116e10
set compiler options in hacky way in fourslash
gabritto 472745e
add parsed source file caching
gabritto a25a3ce
more fourslash completions
gabritto 29e7273
support expected completion item string
gabritto 744b15c
validate marker character
gabritto 8fb549c
get file name from test name
gabritto 2c5c58f
move things into fourslash package
gabritto b3cb619
move more things around
gabritto e9a6f85
WIP: conversion script
gabritto 5da2f95
silence server logs in fourslash
gabritto e277b2c
clean up script
gabritto a5a0514
skip failing generated tests
gabritto a3af405
clean up script, have it read input files from args
gabritto a823122
fix some blank lines
gabritto 15258be
fix content parsing
gabritto fc60000
Merge from main
gabritto dac80f9
fix infinite loop in findPrecedingMatchingToken
gabritto 45f4a48
update failing tests
gabritto 3fd1866
Merge branch 'main' into gabritto/noslash
gabritto 9f0335c
format, lint, etc
gabritto a0da7e6
add one generated test as example
gabritto 70b3bbf
Merge branch 'main' into gabritto/noslash
gabritto 937a6a6
rename script
gabritto 66b8719
Merge branch 'main' into gabritto/noslash
gabritto f1a5596
add launch task for fourslash tests
gabritto a4e364d
redo parsed source file cache
gabritto fb18438
move script to fourslash
gabritto bec9c69
Merge branch 'main' into gabritto/noslash
gabritto fb393e5
use t.cleanup
gabritto 220b3d5
use local ptrTo
gabritto 0a7caf0
renames, fix script helper
gabritto 3415325
remove select
gabritto bd57d92
use stringutil
gabritto 4333d1c
Merge branch 'main' into gabritto/noslash
gabritto 31277f6
fix merge
gabritto d91b010
fix lint
gabritto c91f099
format, add helper
gabritto 7b534c8
format script
gabritto 38034bc
Merge branch 'main' into gabritto/noslash
gabritto 56d2ac4
rename scripts folder, remove package.json, add command to top-level …
gabritto 634e00f
don't change npm versions
gabritto 1404efd
Merge branch 'main' into gabritto/noslash
gabritto d4a9fab
CR
gabritto 277edad
format generated files
gabritto c1c3933
format script
gabritto 157de4d
update failing tests, add all generated tests
gabritto 5e1881c
organize failing tests list
gabritto a244789
skip with noembed
gabritto 41eec38
Revert "skip with noembed"
gabritto 406788b
skip if no embed inside fourslash
gabritto eeb5b6a
update failing tests once again
gabritto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,12 +31,16 @@ func (l *LanguageService) ProvideCompletion( | |
preferences *UserPreferences, | ||
) (*lsproto.CompletionList, error) { | ||
program, file := l.getProgramAndFile(documentURI) | ||
var triggerCharacter *string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactored this file to get rid of nil reference crashes when accessing client capabilities and trigger character. |
||
if context != nil { | ||
triggerCharacter = context.TriggerCharacter | ||
} | ||
return l.getCompletionsAtPosition( | ||
ctx, | ||
program, | ||
file, | ||
int(l.converters.LineAndCharacterToPosition(file, position)), | ||
context, | ||
triggerCharacter, | ||
preferences, | ||
clientOptions, | ||
), nil | ||
|
@@ -272,16 +276,16 @@ func (l *LanguageService) getCompletionsAtPosition( | |
program *compiler.Program, | ||
file *ast.SourceFile, | ||
position int, | ||
context *lsproto.CompletionContext, | ||
triggerCharacter *string, | ||
preferences *UserPreferences, | ||
clientOptions *lsproto.CompletionClientCapabilities, | ||
) *lsproto.CompletionList { | ||
_, previousToken := getRelevantTokens(position, file) | ||
if context.TriggerCharacter != nil && !IsInString(file, position, previousToken) && !isValidTrigger(file, *context.TriggerCharacter, previousToken, position) { | ||
if triggerCharacter != nil && !IsInString(file, position, previousToken) && !isValidTrigger(file, *triggerCharacter, previousToken, position) { | ||
return nil | ||
} | ||
|
||
if context.TriggerCharacter != nil && *context.TriggerCharacter == " " { | ||
if triggerCharacter != nil && *triggerCharacter == " " { | ||
// `isValidTrigger` ensures we are at `import |` | ||
if ptrIsTrue(preferences.IncludeCompletionsForImportStatements) { | ||
return &lsproto.CompletionList{ | ||
|
@@ -1886,7 +1890,7 @@ func (l *LanguageService) createCompletionItem( | |
insertText = origin.asObjectLiteralMethod().insertText | ||
isSnippet = origin.asObjectLiteralMethod().isSnippet | ||
labelDetails = origin.asObjectLiteralMethod().labelDetails // !!! check if this can conflict with case above where we set label details | ||
if !ptrIsTrue(clientOptions.CompletionItem.LabelDetailsSupport) { | ||
if !clientSupportsItemLabelDetails(clientOptions) { | ||
name = name + *origin.asObjectLiteralMethod().labelDetails.Detail | ||
labelDetails = nil | ||
} | ||
|
@@ -1896,7 +1900,7 @@ func (l *LanguageService) createCompletionItem( | |
|
||
if data.isJsxIdentifierExpected && | ||
!data.isRightOfOpenTag && | ||
ptrIsTrue(clientOptions.CompletionItem.SnippetSupport) && | ||
clientSupportsItemSnippet(clientOptions) && | ||
!jsxAttributeCompletionStyleIs(preferences.JsxAttributeCompletionStyle, JsxAttributeCompletionStyleNone) && | ||
!(ast.IsJsxAttribute(data.location.Parent) && data.location.Parent.Initializer() != nil) { | ||
useBraces := jsxAttributeCompletionStyleIs(preferences.JsxAttributeCompletionStyle, JsxAttributeCompletionStyleBraces) | ||
|
@@ -1964,10 +1968,10 @@ func (l *LanguageService) createCompletionItem( | |
|
||
elementKind := getSymbolKind(typeChecker, symbol, data.location) | ||
var commitCharacters *[]string | ||
if ptrIsTrue(clientOptions.CompletionItem.CommitCharactersSupport) { | ||
if clientSupportsItemCommitCharacters(clientOptions) { | ||
if elementKind == ScriptElementKindWarning || elementKind == ScriptElementKindString { | ||
commitCharacters = &[]string{} | ||
} else if !supportsDefaultCommitCharacters(clientOptions) { | ||
} else if !clientSupportsDefaultCommitCharacters(clientOptions) { | ||
commitCharacters = ptrTo(data.defaultCommitCharacters) | ||
} | ||
// Otherwise use the completion list default. | ||
|
@@ -1998,11 +2002,6 @@ func (l *LanguageService) createCompletionItem( | |
) | ||
} | ||
|
||
func supportsDefaultCommitCharacters(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return clientOptions.CompletionList.ItemDefaults != nil && | ||
slices.Contains(*clientOptions.CompletionList.ItemDefaults, "commitCharacters") | ||
} | ||
|
||
func isRecommendedCompletionMatch(localSymbol *ast.Symbol, recommendedCompletion *ast.Symbol, typeChecker *checker.Checker) bool { | ||
return localSymbol == recommendedCompletion || | ||
localSymbol.Flags&ast.SymbolFlagsExportValue != 0 && typeChecker.GetExportSymbolOfSymbol(localSymbol) == recommendedCompletion | ||
|
@@ -3889,8 +3888,8 @@ func setCommitCharacters( | |
defaultCommitCharacters *[]string, | ||
) *lsproto.CompletionItemDefaults { | ||
var itemDefaults *lsproto.CompletionItemDefaults | ||
supportsItemCommitCharacters := ptrIsTrue(clientOptions.CompletionItem.CommitCharactersSupport) | ||
if supportsDefaultCommitCharacters(clientOptions) && supportsItemCommitCharacters { | ||
supportsItemCommitCharacters := clientSupportsItemCommitCharacters(clientOptions) | ||
if clientSupportsDefaultCommitCharacters(clientOptions) && supportsItemCommitCharacters { | ||
itemDefaults = &lsproto.CompletionItemDefaults{ | ||
CommitCharacters: defaultCommitCharacters, | ||
} | ||
|
@@ -4027,7 +4026,7 @@ func (l *LanguageService) createLSPCompletionItem( | |
} | ||
} else { | ||
// Ported from vscode ts extension. | ||
if optionalReplacementSpan != nil && ptrIsTrue(clientOptions.CompletionItem.InsertReplaceSupport) { | ||
if optionalReplacementSpan != nil && clientSupportsItemInsertReplace(clientOptions) { | ||
insertRange := &lsproto.Range{ | ||
Start: optionalReplacementSpan.Start, | ||
End: l.createLspPosition(position, file), | ||
|
@@ -4056,7 +4055,7 @@ func (l *LanguageService) createLSPCompletionItem( | |
filterText = accessorText + core.IfElse(insertText != "", insertText, name) | ||
if textEdit == nil { | ||
insertText = filterText | ||
if wordRange != nil && ptrIsTrue(clientOptions.CompletionItem.InsertReplaceSupport) { | ||
if wordRange != nil && clientSupportsItemInsertReplace(clientOptions) { | ||
textEdit = &lsproto.TextEditOrInsertReplaceEdit{ | ||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{ | ||
NewText: insertText, | ||
|
@@ -4200,3 +4199,30 @@ func (l *LanguageService) getLabelStatementCompletions( | |
} | ||
return items | ||
} | ||
|
||
func hasCompletionItem(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return clientOptions != nil && clientOptions.CompletionItem != nil | ||
} | ||
|
||
func clientSupportsItemLabelDetails(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return hasCompletionItem(clientOptions) && ptrIsTrue(clientOptions.CompletionItem.LabelDetailsSupport) | ||
} | ||
|
||
func clientSupportsItemSnippet(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return hasCompletionItem(clientOptions) && ptrIsTrue(clientOptions.CompletionItem.SnippetSupport) | ||
} | ||
|
||
func clientSupportsItemCommitCharacters(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return hasCompletionItem(clientOptions) && ptrIsTrue(clientOptions.CompletionItem.CommitCharactersSupport) | ||
} | ||
|
||
func clientSupportsItemInsertReplace(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
return hasCompletionItem(clientOptions) && ptrIsTrue(clientOptions.CompletionItem.InsertReplaceSupport) | ||
} | ||
|
||
func clientSupportsDefaultCommitCharacters(clientOptions *lsproto.CompletionClientCapabilities) bool { | ||
if clientOptions == nil || clientOptions.CompletionList == nil || clientOptions.CompletionList.ItemDefaults == nil { | ||
return false | ||
} | ||
return slices.Contains(*clientOptions.CompletionList.ItemDefaults, "commitCharacters") | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package ls_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/microsoft/typescript-go/internal/ls" | ||
"github.com/microsoft/typescript-go/internal/lsp/lsproto" | ||
"github.com/microsoft/typescript-go/internal/testutil/lstestutil" | ||
) | ||
|
||
const content = `export {}; | ||
interface Point { | ||
x: number; | ||
y: number; | ||
} | ||
declare const p: Point; | ||
p./*a*/` | ||
|
||
func TestBasicInterfaceMembers(t *testing.T) { | ||
t.Parallel() | ||
f, done := lstestutil.NewFourslash(t, nil /*capabilities*/, content, "basicInterfaceMembers.ts") | ||
f.VerifyCompletions(t, "a", lstestutil.VerifyCompletionsResult{ | ||
Exact: &lsproto.CompletionList{ | ||
IsIncomplete: false, | ||
ItemDefaults: &lsproto.CompletionItemDefaults{ | ||
CommitCharacters: &lstestutil.DefaultCommitCharacters, | ||
}, | ||
Items: []*lsproto.CompletionItem{ | ||
{ | ||
Label: "x", | ||
Kind: lstestutil.PtrTo(lsproto.CompletionItemKindField), | ||
SortText: lstestutil.PtrTo(string(ls.SortTextLocationPriority)), | ||
FilterText: lstestutil.PtrTo(".x"), | ||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{ | ||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{ | ||
NewText: "x", | ||
Insert: lsproto.Range{ | ||
Start: lsproto.Position{Line: 6, Character: 2}, | ||
End: lsproto.Position{Line: 6, Character: 2}, | ||
}, | ||
Replace: lsproto.Range{ | ||
Start: lsproto.Position{Line: 6, Character: 2}, | ||
End: lsproto.Position{Line: 6, Character: 2}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Label: "y", | ||
Kind: lstestutil.PtrTo(lsproto.CompletionItemKindField), | ||
SortText: lstestutil.PtrTo(string(ls.SortTextLocationPriority)), | ||
FilterText: lstestutil.PtrTo(".y"), | ||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{ | ||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{ | ||
NewText: "y", | ||
Insert: lsproto.Range{ | ||
Start: lsproto.Position{Line: 6, Character: 2}, | ||
End: lsproto.Position{Line: 6, Character: 2}, | ||
}, | ||
Replace: lsproto.Range{ | ||
Start: lsproto.Position{Line: 6, Character: 2}, | ||
End: lsproto.Position{Line: 6, Character: 2}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
done() | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.