 Documentation
      ¶
      Documentation
      ¶
    
    
  
    
  
    Index ¶
Constants ¶
This section is empty.
Variables ¶
var DotNotationRule = rule.CreateRule(rule.Rule{ Name: "dot-notation", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { opts := parseOptions(options) var allowRE *regexp.Regexp if opts.AllowPattern != "" { if re, err := regexp.Compile(opts.AllowPattern); err == nil { allowRE = re } } if ctx.Program != nil { _ = ctx.Program.Options() } listeners := rule.RuleListeners{} listeners[ast.KindElementAccessExpression] = func(node *ast.Node) { elem := node.AsElementAccessExpression() if elem == nil || elem.ArgumentExpression == nil { return } propName, ok := getStringLiteralValue(ctx.SourceFile, elem.ArgumentExpression) if !ok { return } if allowRE != nil && allowRE.MatchString(propName) { return } if !opts.AllowKeywords && (propName == "null" || propName == "true" || propName == "false") { return } objType := ctx.TypeChecker.GetTypeAtLocation(elem.Expression) nnType := ctx.TypeChecker.GetNonNullableType(objType) appType := checker.Checker_getApparentType(ctx.TypeChecker, nnType) sym := checker.Checker_getPropertyOfType(ctx.TypeChecker, appType, propName) if sym == nil { for _, s := range checker.Checker_getPropertiesOfType(ctx.TypeChecker, appType) { if s != nil && s.Name == propName { sym = s break } } } if sym != nil { flags := checker.GetDeclarationModifierFlagsFromSymbol(sym) if (flags & ast.ModifierFlagsPrivate) != 0 { if opts.AllowPrivateClassPropertyAccess { return } } else if (flags & ast.ModifierFlagsProtected) != 0 { if opts.AllowProtectedClassPropertyAccess { return } } } else { allowIndexAccess := opts.AllowIndexSignaturePropertyAccess if ctx.Program != nil { if copts := ctx.Program.Options(); copts != nil && copts.NoPropertyAccessFromIndexSignature.IsTrue() { allowIndexAccess = true } } if hasAnyIndexSignature(appType) && allowIndexAccess { return } } if isValidIdentifier(propName) && (opts.AllowKeywords || (!isKeyword(propName))) { text := ctx.SourceFile.Text() nodeRange := utils.TrimNodeTextRange(ctx.SourceFile, node) exprRange := utils.TrimNodeTextRange(ctx.SourceFile, elem.Expression) bracketStart := exprRange.End() for bracketStart < nodeRange.End() && text[bracketStart] != '[' { bracketStart++ } whitespace := "" if bracketStart > exprRange.End() { whitespace = text[exprRange.End():bracketStart] } objectText := text[exprRange.Pos():exprRange.End()] replacement := objectText + whitespace + "." + propName ctx.ReportNodeWithFixes(node, buildUseDotMessage(), rule.RuleFixReplace(ctx.SourceFile, node, replacement)) } } listeners[ast.KindPropertyAccessExpression] = func(node *ast.Node) { if opts.AllowKeywords { return } pae := node.AsPropertyAccessExpression() if pae == nil || pae.Name() == nil || pae.Expression == nil { return } name := pae.Name().Text() if !isKeyword(name) && name != "true" && name != "false" && name != "null" { return } textRange := utils.TrimNodeTextRange(ctx.SourceFile, node) if !utils.HasCommentsInRange(ctx.SourceFile, textRange) { text := ctx.SourceFile.Text() objRange := utils.TrimNodeTextRange(ctx.SourceFile, pae.Expression) dotPos := objRange.End() for dotPos < textRange.End() && text[dotPos] != '.' { dotPos++ } whitespace := "" if dotPos > objRange.End() { whitespace = text[objRange.End():dotPos] } objectText := text[objRange.Pos():objRange.End()] replacement := objectText + whitespace + "[\"" + name + "\"]" ctx.ReportNodeWithFixes(node, buildUseBracketsMessage(name), rule.RuleFixReplace(ctx.SourceFile, node, replacement)) return } ctx.ReportNode(node, buildUseBracketsMessage(name)) } return listeners }, })
DotNotationRule enforces dot-notation when safe and allowed by options.
KNOWN LIMITATION: The test infrastructure in /packages/rule-tester doesn't properly pass TypeScript compiler options from individual test cases. This means tests that rely on specific tsconfig settings (like noPropertyAccessFromIndexSignature) may not work correctly. The test runner always uses the same rslint.json config file for all test cases, which references a fixed tsconfig.json. Individual test cases can specify different tsconfig files via languageOptions.parserOptions.project, but these are ignored by the test runner. See: /packages/rule-tester/src/index.ts line 273 - the lint() call doesn't use per-test config.
Functions ¶
This section is empty.
Types ¶
type Options ¶
type Options struct {
	AllowIndexSignaturePropertyAccess bool   `json:"allowIndexSignaturePropertyAccess"`
	AllowKeywords                     bool   `json:"allowKeywords"`
	AllowPattern                      string `json:"allowPattern"`
	AllowPrivateClassPropertyAccess   bool   `json:"allowPrivateClassPropertyAccess"`
	AllowProtectedClassPropertyAccess bool   `json:"allowProtectedClassPropertyAccess"`
}
    Options mirrors @typescript-eslint/dot-notation options