Skip to content

Commit 880a9e9

Browse files
Andaristgraphemeclusterjakebaileyrbuckton
authored
Port Regular Expressions checking (#3061)
Co-authored-by: =?UTF-8?q?=E5=BD=A2=E7=B4=A0=E5=8F=A2=E9=9B=86=E3=83=BB=E3=81=90?= =?UTF-8?q?=E3=82=89=E3=81=B5=E3=81=83=E3=83=BC=E3=82=80?= <graphemecluster@gmail.com> Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
1 parent 478d035 commit 880a9e9

50 files changed

Lines changed: 3508 additions & 2213 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

internal/checker/checker.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ type Checker struct {
679679
markedAssignmentSymbolLinks core.LinkStore[*ast.Symbol, MarkedAssignmentSymbolLinks]
680680
symbolContainerLinks core.LinkStore[*ast.Symbol, ContainingSymbolLinks]
681681
sourceFileLinks core.LinkStore[*ast.SourceFile, SourceFileLinks]
682+
regExpScanner *scanner.Scanner
682683
patternForType map[*Type]*ast.Node
683684
contextFreeTypes map[*ast.Node]*Type
684685
anyType *Type

internal/checker/grammarchecks.go

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,43 +54,35 @@ func (c *Checker) grammarErrorOnNodeSkippedOnNoEmit(node *ast.Node, message *dia
5454
return false
5555
}
5656

57-
func (c *Checker) checkGrammarRegularExpressionLiteral(_ *ast.RegularExpressionLiteral) bool {
58-
// !!!
59-
// Unclear if this is needed until regular expression parsing is more thoroughly implemented.
57+
func (c *Checker) checkGrammarRegularExpressionLiteral(node *ast.RegularExpressionLiteral) bool {
58+
sourceFile := ast.GetSourceFileOfNode(node.AsNode())
59+
if !c.hasParseDiagnostics(sourceFile) {
60+
var lastError *ast.Diagnostic
61+
if c.regExpScanner == nil {
62+
c.regExpScanner = scanner.NewScanner()
63+
}
64+
c.regExpScanner.SetScriptTarget(c.languageVersion)
65+
c.regExpScanner.SetLanguageVariant(sourceFile.LanguageVariant)
66+
c.regExpScanner.SetOnError(func(message *diagnostics.Message, start int, length int, args ...any) {
67+
if message.Category() == diagnostics.CategoryMessage && lastError != nil && start == lastError.Pos() && length == lastError.Len() {
68+
// For providing spelling suggestions.
69+
err := ast.NewDiagnostic(nil, core.NewTextRange(start, start+length), message, args...)
70+
lastError.AddRelatedInfo(err)
71+
} else if lastError == nil || start != lastError.Pos() {
72+
lastError = ast.NewDiagnostic(sourceFile, core.NewTextRange(start, start+length), message, args...)
73+
c.diagnostics.Add(lastError)
74+
}
75+
})
76+
c.regExpScanner.SetText(sourceFile.Text())
77+
c.regExpScanner.ResetTokenState(node.AsNode().Pos())
78+
c.regExpScanner.Scan()
79+
tokenIsRegularExpressionLiteral := c.regExpScanner.ReScanSlashToken(true) == ast.KindRegularExpressionLiteral
80+
c.regExpScanner.SetText("")
81+
c.regExpScanner.SetOnError(nil)
82+
debug.Assert(tokenIsRegularExpressionLiteral)
83+
return lastError != nil
84+
}
6085
return false
61-
// sourceFile := ast.GetSourceFileOfNode(node.AsNode())
62-
// if !c.hasParseDiagnostics(sourceFile) && !node.IsUnterminated {
63-
// var lastError *ast.Diagnostic
64-
// scanner := NewScanner()
65-
// scanner.skipTrivia = true
66-
// scanner.SetScriptTarget(sourceFile.LanguageVersion)
67-
// scanner.SetLanguageVariant(sourceFile.LanguageVariant)
68-
// scanner.SetOnError(func(message *diagnostics.Message, start int, length int, args ...any) {
69-
// // !!!
70-
// // Original uses `tokenEnd()` - unclear if this is the same as the `start` passed in here.
71-
// // const start = scanner.TokenEnd()
72-
73-
// // The scanner is operating on a slice of the original source text, so we need to adjust the start
74-
// // for error reporting.
75-
// start = start + node.Pos()
76-
77-
// // For providing spelling suggestions
78-
// if message.Category() == diagnostics.CategoryMessage && lastError != nil && start == lastError.Pos() && length == lastError.Len() {
79-
// err := ast.NewDiagnostic(sourceFile, core.NewTextRange(start, start+length), message, args)
80-
// lastError.AddRelatedInfo(err)
81-
// } else if !(lastError != nil) || start != lastError.Pos() {
82-
// lastError = ast.NewDiagnostic(sourceFile, core.NewTextRange(start, start+length), message, args)
83-
// c.diagnostics.Add(lastError)
84-
// }
85-
// })
86-
// scanner.SetText(sourceFile.Text[node.Pos():node.Loc.Len()])
87-
// scanner.Scan()
88-
// if scanner.ReScanSlashToken() != ast.KindRegularExpressionLiteral {
89-
// panic("Expected to rescan RegularExpressionLiteral")
90-
// }
91-
// return lastError != nil
92-
// }
93-
// return false
9486
}
9587

9688
func (c *Checker) checkGrammarPrivateIdentifierExpression(privId *ast.PrivateIdentifier) bool {

0 commit comments

Comments
 (0)