@@ -76,193 +76,3 @@ class FormatterDocument {
76
76
return *SM.getLLVMSourceMgr ().getMemoryBuffer (BufferID);
77
77
}
78
78
};
79
-
80
- class SwiftIndentInvocation {
81
- private:
82
- std::string MainExecutablePath;
83
- std::string OutputFilename = " -" ;
84
- std::vector<std::string> InputFilenames;
85
- CodeFormatOptions FormatOptions;
86
- bool InPlace = false ;
87
- std::vector<std::string> LineRanges;
88
-
89
- bool parseLineRange (StringRef Input, unsigned &FromLine, unsigned &ToLine) {
90
- std::pair<StringRef, StringRef> LineRange = Input.split (" :" );
91
- return LineRange.first .getAsInteger (0 , FromLine) ||
92
- LineRange.second .getAsInteger (0 , ToLine);
93
- }
94
-
95
- public:
96
- SwiftIndentInvocation (const std::string &ExecPath)
97
- : MainExecutablePath(ExecPath) {}
98
-
99
- const std::string &getOutputFilename () { return OutputFilename; }
100
-
101
- const std::vector<std::string> &getInputFilenames () { return InputFilenames; }
102
-
103
- const std::vector<std::string> &getLineRanges () { return LineRanges; }
104
-
105
- int parseArgs (ArrayRef<const char *> Args, DiagnosticEngine &Diags) {
106
- using namespace options ;
107
-
108
- std::unique_ptr<llvm::opt::OptTable> Table = createSwiftOptTable ();
109
- unsigned MissingIndex;
110
- unsigned MissingCount;
111
- llvm::opt::InputArgList ParsedArgs =
112
- Table->ParseArgs (Args, MissingIndex, MissingCount, SwiftIndentOption);
113
- if (MissingCount) {
114
- Diags.diagnose (SourceLoc (), diag::error_missing_arg_value,
115
- ParsedArgs.getArgString (MissingIndex), MissingCount);
116
- return 1 ;
117
- }
118
-
119
- if (ParsedArgs.getLastArg (OPT_use_tabs))
120
- FormatOptions.UseTabs = true ;
121
-
122
- if (ParsedArgs.getLastArg (OPT_indent_switch_case))
123
- FormatOptions.IndentSwitchCase = true ;
124
-
125
- if (ParsedArgs.getLastArg (OPT_in_place))
126
- InPlace = true ;
127
-
128
- if (const Arg *A = ParsedArgs.getLastArg (OPT_tab_width))
129
- if (StringRef (A->getValue ()).getAsInteger (10 , FormatOptions.TabWidth ))
130
- Diags.diagnose (SourceLoc (), diag::error_invalid_arg_value,
131
- A->getAsString (ParsedArgs), A->getValue ());
132
-
133
- if (const Arg *A = ParsedArgs.getLastArg (OPT_indent_width))
134
- if (StringRef (A->getValue ()).getAsInteger (10 , FormatOptions.IndentWidth ))
135
- Diags.diagnose (SourceLoc (), diag::error_invalid_arg_value,
136
- A->getAsString (ParsedArgs), A->getValue ());
137
-
138
- for (const Arg *A : ParsedArgs.filtered (OPT_line_range))
139
- LineRanges.push_back (A->getValue ());
140
-
141
- if (ParsedArgs.hasArg (OPT_UNKNOWN)) {
142
- for (const Arg *A : ParsedArgs.filtered (OPT_UNKNOWN)) {
143
- Diags.diagnose (SourceLoc (), diag::error_unknown_arg,
144
- A->getAsString (ParsedArgs));
145
- }
146
- return true ;
147
- }
148
-
149
- if (ParsedArgs.getLastArg (OPT_help)) {
150
- std::string ExecutableName =
151
- llvm::sys::path::stem (MainExecutablePath).str ();
152
- Table->printHelp (llvm::outs (), ExecutableName.c_str (),
153
- " Swift Format Tool" , options::SwiftIndentOption, 0 ,
154
- /* ShowAllAliases*/ false );
155
- return 1 ;
156
- }
157
-
158
- for (const Arg *A : ParsedArgs.filtered (OPT_INPUT)) {
159
- InputFilenames.push_back (A->getValue ());
160
- }
161
-
162
- if (const Arg *A = ParsedArgs.getLastArg (OPT_o)) {
163
- OutputFilename = A->getValue ();
164
- }
165
-
166
- return 0 ;
167
- }
168
-
169
- // / Formats a filename and returns false if successful, true otherwise.
170
- bool format (StringRef Filename, DiagnosticEngine &Diags) {
171
- auto ErrOrBuf = llvm::MemoryBuffer::getFileOrSTDIN (Filename);
172
- if (!ErrOrBuf) {
173
- Diags.diagnose (SourceLoc (), diag::error_no_such_file_or_directory,
174
- Filename);
175
- return true ;
176
- }
177
- std::unique_ptr<llvm::MemoryBuffer> Code = std::move (ErrOrBuf.get ());
178
- if (Code->getBufferSize () == 0 ) {
179
- // Assume empty files are formatted successfully.
180
- return false ;
181
- }
182
- FormatterDocument Doc (std::move (Code));
183
- if (LineRanges.empty ()) {
184
- LineRanges.push_back (" 1:" + std::to_string (UINT_MAX));
185
- }
186
-
187
- std::string Output = Doc.memBuffer ().getBuffer ().str ();
188
- for (unsigned Range = 0 ; Range < LineRanges.size (); ++Range) {
189
- unsigned FromLine;
190
- unsigned ToLine;
191
- if (parseLineRange (LineRanges[Range], FromLine, ToLine)) {
192
- Diags.diagnose (SourceLoc (), diag::error_formatting_invalid_range);
193
- return true ;
194
- }
195
- if (FromLine > ToLine) {
196
- Diags.diagnose (SourceLoc (), diag::error_formatting_invalid_range);
197
- return true ;
198
- }
199
- for (unsigned Line = FromLine; Line <= ToLine; ++Line) {
200
- size_t Offset = getOffsetOfLine (Line, Output);
201
- ssize_t Length = getOffsetOfLine (Line + 1 , Output) - 1 - Offset;
202
- if (Length < 0 )
203
- break ;
204
-
205
- std::string Formatted =
206
- Doc.reformat (LineRange (Line, 1 ), FormatOptions).second ;
207
- if (Formatted.find_first_not_of (" \t\v\f " , 0 ) == StringRef::npos)
208
- Formatted = " " ;
209
-
210
- Output.replace (Offset, Length, Formatted);
211
- Doc.updateCode (llvm::MemoryBuffer::getMemBufferCopy (Output));
212
- }
213
- if (Filename == " -" || (!InPlace && OutputFilename == " -" )) {
214
- llvm::outs () << Output;
215
- return false ;
216
- }
217
- std::error_code EC;
218
- StringRef Destination;
219
- if (InPlace)
220
- Destination = Filename;
221
- else
222
- Destination = OutputFilename;
223
- llvm::raw_fd_ostream out (Destination, EC, llvm::sys::fs::OF_None);
224
- if (out.has_error () || EC) {
225
- Diags.diagnose (SourceLoc (), diag::error_opening_output, Filename,
226
- EC.message ());
227
- out.clear_error ();
228
- return true ;
229
- }
230
- out << Output;
231
- }
232
- return false ;
233
- }
234
- };
235
-
236
- int swift_indent_main (ArrayRef<const char *> Args, const char *Argv0,
237
- void *MainAddr) {
238
- CompilerInstance Instance;
239
- PrintingDiagnosticConsumer PDC;
240
- Instance.addDiagnosticConsumer (&PDC);
241
-
242
- SwiftIndentInvocation Invocation (
243
- llvm::sys::fs::getMainExecutable (Argv0, MainAddr));
244
-
245
- DiagnosticEngine &Diags = Instance.getDiags ();
246
- if (Invocation.parseArgs (Args, Diags) != 0 )
247
- return EXIT_FAILURE;
248
-
249
- std::vector<std::string> InputFiles = Invocation.getInputFilenames ();
250
- unsigned NumInputFiles = InputFiles.size ();
251
- if (NumInputFiles == 0 ) {
252
- // Read source code from standard input.
253
- Invocation.format (" -" , Diags);
254
- } else if (NumInputFiles == 1 ) {
255
- Invocation.format (InputFiles[0 ], Diags);
256
- } else {
257
- if (!Invocation.getLineRanges ().empty ()) {
258
- // We don't support formatting file ranges for multiple files.
259
- Instance.getDiags ().diagnose (SourceLoc (),
260
- diag::error_formatting_multiple_file_ranges);
261
- return EXIT_FAILURE;
262
- }
263
- for (unsigned i = 0 ; i < NumInputFiles; ++i)
264
- Invocation.format (InputFiles[i], Diags);
265
- }
266
-
267
- return EXIT_SUCCESS;
268
- }
0 commit comments