馃殌 Grammar-Aware Code Formatter: Structure through separation (supports Go, JavaScript, TypeScript, JSX, and TSX)
go
formatter
code-formatter
javascript
typescript
jsx
tsx
1package main
2
3func isWhitespace(character byte) bool {
4 return character == ' ' || character == '\t' || character == '\n' || character == '\r' || character == '\f'
5}
6
7func isClosingBrace(sourceLine string) bool {
8 for characterIndex := 0; characterIndex < len(sourceLine); characterIndex++ {
9 character := sourceLine[characterIndex]
10
11 if isWhitespace(character) {
12 continue
13 }
14
15 return character == '}' || character == ')'
16 }
17
18 return false
19}
20
21func isOpeningBrace(sourceLine string) bool {
22 for characterIndex := len(sourceLine) - 1; characterIndex >= 0; characterIndex-- {
23 character := sourceLine[characterIndex]
24
25 if isWhitespace(character) {
26 continue
27 }
28
29 return character == '{' || character == '('
30 }
31
32 return false
33}
34
35func isCaseLabel(sourceLine string) bool {
36 firstNonWhitespaceIndex := 0
37
38 for firstNonWhitespaceIndex < len(sourceLine) && isWhitespace(sourceLine[firstNonWhitespaceIndex]) {
39 firstNonWhitespaceIndex++
40 }
41
42 if firstNonWhitespaceIndex >= len(sourceLine) {
43 return false
44 }
45
46 contentAfterWhitespace := sourceLine[firstNonWhitespaceIndex:]
47
48 if len(contentAfterWhitespace) >= 5 && contentAfterWhitespace[:4] == "case" && isWhitespace(contentAfterWhitespace[4]) {
49 return true
50 }
51
52 if len(contentAfterWhitespace) >= 7 && contentAfterWhitespace[:7] == "default" {
53 for characterIndex := 7; characterIndex < len(contentAfterWhitespace); characterIndex++ {
54 character := contentAfterWhitespace[characterIndex]
55
56 if isWhitespace(character) {
57 continue
58 }
59
60 if character == ':' {
61 return true
62 }
63
64 break
65 }
66 }
67
68 if firstNonWhitespaceIndex > 0 {
69 lastNonWhitespaceIndex := len(sourceLine) - 1
70
71 for lastNonWhitespaceIndex >= 0 && isWhitespace(sourceLine[lastNonWhitespaceIndex]) {
72 lastNonWhitespaceIndex--
73 }
74
75 if lastNonWhitespaceIndex >= 0 && sourceLine[lastNonWhitespaceIndex] == ':' {
76 return true
77 }
78 }
79
80 return false
81}
82
83func isCommentOnly(sourceLine string) bool {
84 for characterIndex := range len(sourceLine) {
85 character := sourceLine[characterIndex]
86
87 if isWhitespace(character) {
88 continue
89 }
90
91 return len(sourceLine) > characterIndex+1 && sourceLine[characterIndex] == '/' && sourceLine[characterIndex+1] == '/'
92 }
93
94 return false
95}
96
97func isPackageLine(trimmedLine string) bool {
98 return len(trimmedLine) > 8 && trimmedLine[:8] == "package "
99}
100
101func countRawStringDelimiters(sourceLine string) int {
102 delimiterCount := 0
103 insideDoubleQuotedString := false
104 insideCharacterLiteral := false
105
106 for characterIndex := 0; characterIndex < len(sourceLine); characterIndex++ {
107 character := sourceLine[characterIndex]
108
109 if insideCharacterLiteral {
110 if character == '\\' && characterIndex+1 < len(sourceLine) {
111 characterIndex++
112
113 continue
114 }
115
116 if character == '\'' {
117 insideCharacterLiteral = false
118 }
119
120 continue
121 }
122
123 if insideDoubleQuotedString {
124 if character == '\\' && characterIndex+1 < len(sourceLine) {
125 characterIndex++
126
127 continue
128 }
129
130 if character == '"' {
131 insideDoubleQuotedString = false
132 }
133
134 continue
135 }
136
137 if character == '\'' {
138 insideCharacterLiteral = true
139
140 continue
141 }
142
143 if character == '"' {
144 insideDoubleQuotedString = true
145
146 continue
147 }
148
149 if character == '`' {
150 delimiterCount++
151 }
152 }
153
154 return delimiterCount
155}