馃殌 Grammar-Aware Code Formatter: Structure through separation (supports Go, JavaScript, TypeScript, JSX, and TSX)
go formatter code-formatter javascript typescript jsx tsx
at main 155 lines 3.3 kB view raw
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}