-
Notifications
You must be signed in to change notification settings - Fork 764
Create tokens with the right data #2308
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
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| . "github.com/microsoft/typescript-go/internal/fourslash/tests/util" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestCompletionsUnterminatedLiteral(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| const content = `// @noLib: true | ||
| function foo(a"/*1*/` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{ | ||
| ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ | ||
| CommitCharacters: &DefaultCommitCharacters, | ||
| }, | ||
| Items: &fourslash.CompletionsExpectedItems{}, | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -178,7 +178,7 @@ func (t *Tracker) InsertNodeBefore(sourceFile *ast.SourceFile, before *ast.Node, | |
| // InsertModifierBefore inserts a modifier token (like 'type') before a node with a trailing space. | ||
| func (t *Tracker) InsertModifierBefore(sourceFile *ast.SourceFile, modifier ast.Kind, before *ast.Node) { | ||
| pos := astnav.GetStartOfNode(before, sourceFile, false) | ||
| token := sourceFile.GetOrCreateToken(modifier, pos, pos, before.Parent) | ||
| token := sourceFile.GetOrCreateToken(modifier, pos, pos, before.Parent, ast.TokenFlagsNone) | ||
| t.InsertNodeAt(sourceFile, core.TextPos(pos), token, NodeOptions{Suffix: " "}) | ||
| } | ||
|
|
||
|
|
@@ -262,7 +262,7 @@ func (t *Tracker) endPosForInsertNodeAfter(sourceFile *ast.SourceFile, after *as | |
| endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(after.End())) | ||
| t.ReplaceRange(sourceFile, | ||
| lsproto.Range{Start: endPos, End: endPos}, | ||
| sourceFile.GetOrCreateToken(ast.KindSemicolonToken, after.End(), after.End(), after.Parent), | ||
| sourceFile.GetOrCreateToken(ast.KindSemicolonToken, after.End(), after.End(), after.Parent, ast.TokenFlagsNone), | ||
| NodeOptions{}, | ||
| ) | ||
| } | ||
|
|
@@ -347,7 +347,7 @@ func (t *Tracker) InsertNodeInListAfter(sourceFile *ast.SourceFile, after *ast.N | |
|
|
||
| // insert separator immediately following the 'after' node to preserve comments in trailing trivia | ||
| // !!! formatcontext | ||
| t.ReplaceRange(sourceFile, lsproto.Range{Start: end, End: end}, sourceFile.GetOrCreateToken(separator, after.End(), after.End()+len(separatorString), after.Parent), NodeOptions{}) | ||
| t.ReplaceRange(sourceFile, lsproto.Range{Start: end, End: end}, sourceFile.GetOrCreateToken(separator, after.End(), after.End()+len(separatorString), after.Parent, ast.TokenFlagsNone), NodeOptions{}) | ||
|
||
| // use the same indentation as 'after' item | ||
| indentation := format.FindFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, t.formatSettings) | ||
| // insert element before the line break on the line that contains 'after' element | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
TokenFlagsare not being set for these literal types, even though they all haveLiteralLikeBase(orTemplateLiteralLikeBase) which includes aTokenFlagsfield. This is critical because these flags carry important information like whether a literal is unterminated (seeTokenFlagsUnterminatedandIsUnterminatedLiteralin utilities.go), which is exactly what this PR is trying to fix.The flags need to be set after creating these nodes. For example:
Note that for
NoSubstitutionTemplateLiteral, it should setTemplateFlags(not the inheritedTokenFlagsfromLiteralLikeBase) sinceIsUnterminatedLiteralchecksTemplateFlagsfor template literal kinds.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unfortunately correct, and it's very annoying e.g.
NewStringLiteraldoesn't take the flags because I keep forgetting about it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it?
This code is also sort of the same as
parseLiteralExpressionwhich does sort of make it seem like this is all sort of error prone, yeah.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should in general, as there's code in the LS that uses token flags, and code in the printer that also uses token flags, but there's tons of existing places where we don't set flags right now. I'll try and refactor that in another PR tomorrow.