| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #ifndef CARBON_TOOLCHAIN_FORMAT_FORMATTER_H_
- #define CARBON_TOOLCHAIN_FORMAT_FORMATTER_H_
- #include <cstdint>
- #include "common/ostream.h"
- #include "toolchain/lex/tokenized_buffer.h"
- namespace Carbon::Format {
- // Implements Format(); see format.h. It's intended to be constructed and
- // `Run()` once, then destructed.
- //
- // TODO: This will probably need to work less linearly in the future, for
- // example to handle smart wrapping of arguments. This is a simple
- // implementation that only handles simple code. Before adding too much more
- // complexity, it should be rewritten.
- //
- // TODO: Add retention of blank lines between original code.
- //
- // TODO: Add support for formatting line ranges (will need flags too).
- class Formatter {
- public:
- explicit Formatter(const Lex::TokenizedBuffer* tokens, llvm::raw_ostream* out)
- : tokens_(tokens), out_(out) {}
- // See class comments.
- auto Run() -> bool;
- private:
- // Tracks the status of the current line of output.
- enum class LineState : uint8_t {
- // There is no output for the current line.
- Empty,
- // The current line has content (possibly just an indent), and does not need
- // a separator added.
- HasSeparator,
- // The current line has content, and will need a separator, typically a
- // single space or newline.
- NeedsSeparator,
- };
- // Ensure output is on an empty line, setting line_state_ to Empty. May output
- // a newline, dependent on line state. Does not indent, allowing blank lines.
- auto RequireEmptyLine() -> void;
- // Ensures there is a separator before adding new content. May do
- // `PrepareForPackedContent` or output a separator space, dependent on line
- // state. Always results in line_state_ being HasSeparator; the caller is
- // responsible for adjusting state if needed.
- auto PrepareForSpacedContent() -> void;
- // Requires that the current line is indented, but not necessarily a separator
- // space. May output spaces for `indent_`, dependent on line state. Only
- // guarantees the line_state_ is not Empty; the caller is responsible for
- // adjusting state if needed.
- auto PrepareForPackedContent() -> void;
- // Returns the next token index.
- static auto NextToken(Lex::TokenIndex token) -> Lex::TokenIndex {
- return *(Lex::TokenIterator(token) + 1);
- }
- // The tokens being formatted.
- const Lex::TokenizedBuffer* tokens_;
- // The output stream for formatted content.
- llvm::raw_ostream* out_;
- // The state of the line currently written to output.
- LineState line_state_ = LineState::Empty;
- // The current code indent level, to be added to new lines.
- int indent_ = 0;
- };
- } // namespace Carbon::Format
- #endif // CARBON_TOOLCHAIN_FORMAT_FORMATTER_H_
|