@@ -76,193 +76,3 @@ class FormatterDocument {
7676 return *SM.getLLVMSourceMgr ().getMemoryBuffer (BufferID);
7777 }
7878};
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