Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var JsxClosingBracketLocationRule = rule.Rule{ Name: "react/jsx-closing-bracket-location", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { opts := parseOptions(options) check := func(node *ast.Node) { var tagName *ast.Node var attrs []*ast.Node var selfClosing bool switch node.Kind { case ast.KindJsxOpeningElement: opening := node.AsJsxOpeningElement() tagName = opening.TagName if opening.Attributes != nil { jsxAttrs := opening.Attributes.AsJsxAttributes() if jsxAttrs.Properties != nil { attrs = jsxAttrs.Properties.Nodes } } selfClosing = false case ast.KindJsxSelfClosingElement: self := node.AsJsxSelfClosingElement() tagName = self.TagName if self.Attributes != nil { jsxAttrs := self.Attributes.AsJsxAttributes() if jsxAttrs.Properties != nil { attrs = jsxAttrs.Properties.Nodes } } selfClosing = true default: return } text := ctx.SourceFile.Text() lineStarts := ctx.SourceFile.ECMALineMap() elemTrimmed := utils.TrimNodeTextRange(ctx.SourceFile, node) openingPos := elemTrimmed.Pos() elemEnd := elemTrimmed.End() gtPos := elemEnd - 1 for gtPos > openingPos && gtPos < len(text) && text[gtPos] != '>' { gtPos-- } if gtPos < 0 || gtPos >= len(text) || text[gtPos] != '>' { return } closingPos := gtPos if selfClosing { slash := gtPos - 1 for slash > openingPos && (text[slash] == ' ' || text[slash] == '\t' || text[slash] == '\n' || text[slash] == '\r') { slash-- } if slash <= openingPos || text[slash] != '/' { return } closingPos = slash } openingLine := scanner.ComputeLineOfPosition(lineStarts, openingPos) openingLineStart := int(lineStarts[openingLine]) openingColumn := reactutil.UTF16Length(text[openingLineStart:openingPos]) closingLine := scanner.ComputeLineOfPosition(lineStarts, closingPos) closingLineStart := int(lineStarts[closingLine]) closingColumn := reactutil.UTF16Length(text[closingLineStart:closingPos]) tagTrimmed := utils.TrimNodeTextRange(ctx.SourceFile, tagName) tagLine := scanner.ComputeLineOfPosition(lineStarts, tagTrimmed.Pos()) openingStartIndent := leadingWhitespace(text, openingLineStart) info := tokenInfo{ openingPos: openingPos, openingLine: openingLine, openingColumn: openingColumn, closingPos: closingPos, closingLine: closingLine, closingColumn: closingColumn, tagLine: tagLine, openingStartCol: reactutil.UTF16Length(openingStartIndent), openTab: openingLineStart < len(text) && text[openingLineStart] == '\t', closeTab: closingLineStart < len(text) && text[closingLineStart] == '\t', selfClosing: selfClosing, } if len(attrs) > 0 { lastProp := attrs[len(attrs)-1] lpTrimmed := utils.TrimNodeTextRange(ctx.SourceFile, lastProp) lpStart := lpTrimmed.Pos() lpEnd := lpTrimmed.End() lpFirstLine := scanner.ComputeLineOfPosition(lineStarts, lpStart) lpLastLine := scanner.ComputeLineOfPosition(lineStarts, lpEnd-1) lpLineStart := int(lineStarts[lpFirstLine]) lpColumn := reactutil.UTF16Length(text[lpLineStart:lpStart]) info.hasLastProp = true info.lastPropEnd = lpEnd info.lastPropFirstLine = lpFirstLine info.lastPropLastLine = lpLastLine info.lastPropColumn = lpColumn } expectedLocation, disabled := getExpectedLocation(info, opts) if disabled { return } usingSameIndentation := true if expectedLocation == "tag-aligned" { usingSameIndentation = info.openTab == info.closeTab } if hasCorrectLocation(info, expectedLocation) && usingSameIndentation { return } locationDesc, ok := locationMessages[expectedLocation] if !ok { return } details := "" expectedNextLine := info.hasLastProp && info.lastPropLastLine == info.closingLine correctColumn, hasCorrectColumn := getCorrectColumn(info, expectedLocation) if hasCorrectColumn { if expectedNextLine { details = fmt.Sprintf(" (expected column %d on the next line)", correctColumn+1) } else { details = fmt.Sprintf(" (expected column %d)", correctColumn+1) } } fix := buildFix(text, info, expectedLocation, expectedNextLine, correctColumn, lineStarts, elemEnd, tagTrimmed.End(), selfClosing) msg := rule.RuleMessage{ Id: "bracketLocation", Description: fmt.Sprintf("The closing bracket must be %s%s", locationDesc, details), } closingEnd := closingPos + 1 if closingEnd > len(text) { closingEnd = len(text) } reportRange := core.NewTextRange(closingPos, closingEnd) if fix != nil { ctx.ReportRangeWithFixes(reportRange, msg, *fix) } else { ctx.ReportRange(reportRange, msg) } } return rule.RuleListeners{ ast.KindJsxOpeningElement: check, ast.KindJsxSelfClosingElement: check, } }, }
JsxClosingBracketLocationRule enforces the closing bracket location for JSX multiline elements.
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.