Skip to content

Commit 385113a

Browse files
Update API and fix dot-notation rule implementation
1 parent ec62979 commit 385113a

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

cmd/rslint/api.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"strings"
67
"sync"
78

89
"github.com/microsoft/typescript-go/shim/ast"
@@ -171,14 +172,21 @@ func (h *IPCHandler) HandleLint(req api.LintRequest) (*api.LintResponse, error)
171172
option interface{}
172173
}
173174
rulesWithOptions := []RuleWithOption{}
174-
// filter rule based on request.RuleOptions
175+
// Filter rules based on request.RuleOptions, supporting both short and plugin-prefixed names
175176
if len(req.RuleOptions) > 0 {
177+
// Build a map from short name -> option by trimming any prefix like "@typescript-eslint/"
178+
shortOpts := map[string]interface{}{}
179+
for key, opt := range req.RuleOptions {
180+
short := key
181+
if idx := strings.LastIndexByte(key, '/'); idx >= 0 {
182+
short = key[idx+1:]
183+
}
184+
shortOpts[short] = opt
185+
}
186+
176187
for _, r := range origin_rules {
177-
if option, ok := req.RuleOptions[r.Name]; ok {
178-
rulesWithOptions = append(rulesWithOptions, RuleWithOption{
179-
rule: r,
180-
option: option,
181-
})
188+
if option, ok := shortOpts[r.Name]; ok {
189+
rulesWithOptions = append(rulesWithOptions, RuleWithOption{rule: r, option: option})
182190
}
183191
}
184192
}

internal/rules/dot_notation/dot_notation.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ func checkNode(ctx rule.RuleContext, node *ast.Node, opts DotNotationOptions, al
102102
case ast.KindStringLiteral:
103103
propertyName = argument.AsStringLiteral().Text
104104
isValidProperty = true
105+
case ast.KindNoSubstitutionTemplateLiteral:
106+
// Handle `obj[`foo`]` (no expressions)
107+
propertyName = argument.AsNoSubstitutionTemplateLiteral().Text
108+
isValidProperty = true
105109
case ast.KindNumericLiteral:
106110
// Numeric properties should use bracket notation
107111
return
@@ -159,7 +163,14 @@ func checkPropertyAccessKeywords(ctx rule.RuleContext, node *ast.Node) {
159163
}
160164

161165
propertyName := name.AsIdentifier().Text
162-
if isReservedWord(propertyName) {
166+
// Align with typescript-eslint behavior: do not flag some identifiers even when allowKeywords is false
167+
skipKeywords := map[string]bool{
168+
"arguments": true,
169+
"let": true,
170+
"yield": true,
171+
"eval": true,
172+
}
173+
if isReservedWord(propertyName) && !skipKeywords[propertyName] {
163174
ctx.ReportNodeWithFixes(node, rule.RuleMessage{
164175
Id: "useBrackets",
165176
Description: fmt.Sprintf(".%s is a syntax error.", propertyName),
@@ -196,10 +207,14 @@ func shouldAllowBracketNotation(ctx rule.RuleContext, node *ast.Node, propertyNa
196207
}
197208
}
198209

199-
// If allowIndexSignaturePropertyAccess is true, check for actual index signatures
210+
// If allowIndexSignaturePropertyAccess is true, allow bracket only when there is NO named property,
211+
// but the type has an applicable index signature.
200212
if allowIndexSignaturePropertyAccess {
201-
if hasIndexSignature(ctx, objectType) {
202-
return true
213+
// If there is a named property, prefer dot notation
214+
if sym := ctx.TypeChecker.GetPropertyOfType(objectType, propertyName); sym == nil {
215+
if hasIndexSignature(ctx, objectType) {
216+
return true
217+
}
203218
}
204219
}
205220

0 commit comments

Comments
 (0)