mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-05 20:55:58 +00:00
[writer] Allow for out of order text generation
Add Insert() methods to TextBuffer. Allows generators to insert helper functions at the top of the output without requiring a scan of the program before generation. Change-Id: I05f67ad05d189f2249e35cfac99536afccb5578d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/57140 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
facb5ced00
commit
ea1a4680d4
@ -39,17 +39,16 @@ std::string TextGenerator::TrimSuffix(std::string str,
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextGenerator::LineWriter::LineWriter(TextGenerator* generator)
|
TextGenerator::LineWriter::LineWriter(TextBuffer* buf) : buffer(buf) {}
|
||||||
: gen(generator) {}
|
|
||||||
|
|
||||||
TextGenerator::LineWriter::LineWriter(LineWriter&& other) {
|
TextGenerator::LineWriter::LineWriter(LineWriter&& other) {
|
||||||
gen = other.gen;
|
buffer = other.buffer;
|
||||||
other.gen = nullptr;
|
other.buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextGenerator::LineWriter::~LineWriter() {
|
TextGenerator::LineWriter::~LineWriter() {
|
||||||
if (gen) {
|
if (buffer) {
|
||||||
gen->current_buffer_->Append(os.str());
|
buffer->Append(os.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +67,47 @@ void TextGenerator::TextBuffer::Append(const std::string& line) {
|
|||||||
lines.emplace_back(Line{current_indent, line});
|
lines.emplace_back(Line{current_indent, line});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextGenerator::TextBuffer::Insert(const std::string& line,
|
||||||
|
size_t before,
|
||||||
|
uint32_t indent) {
|
||||||
|
if (before >= lines.size()) {
|
||||||
|
diag::List d;
|
||||||
|
TINT_ICE(Writer, d)
|
||||||
|
<< "TextBuffer::Insert() called with before >= lines.size()\n"
|
||||||
|
<< " before:" << before << "\n"
|
||||||
|
<< " lines.size(): " << lines.size();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lines.insert(lines.begin() + before, Line{indent, line});
|
||||||
|
}
|
||||||
|
|
||||||
void TextGenerator::TextBuffer::Append(const TextBuffer& tb) {
|
void TextGenerator::TextBuffer::Append(const TextBuffer& tb) {
|
||||||
for (auto& line : tb.lines) {
|
for (auto& line : tb.lines) {
|
||||||
|
// TODO(bclayton): inefficent, consider optimizing
|
||||||
lines.emplace_back(Line{current_indent + line.indent, line.content});
|
lines.emplace_back(Line{current_indent + line.indent, line.content});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextGenerator::TextBuffer::Insert(const TextBuffer& tb,
|
||||||
|
size_t before,
|
||||||
|
uint32_t indent) {
|
||||||
|
if (before >= lines.size()) {
|
||||||
|
diag::List d;
|
||||||
|
TINT_ICE(Writer, d)
|
||||||
|
<< "TextBuffer::Insert() called with before >= lines.size()\n"
|
||||||
|
<< " before:" << before << "\n"
|
||||||
|
<< " lines.size(): " << lines.size();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t idx = 0;
|
||||||
|
for (auto& line : tb.lines) {
|
||||||
|
// TODO(bclayton): inefficent, consider optimizing
|
||||||
|
lines.insert(lines.begin() + before + idx,
|
||||||
|
Line{indent + line.indent, line.content});
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string TextGenerator::TextBuffer::String() const {
|
std::string TextGenerator::TextBuffer::String() const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (auto& line : lines) {
|
for (auto& line : lines) {
|
||||||
@ -96,11 +130,14 @@ TextGenerator::ScopedParen::~ScopedParen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextGenerator::ScopedIndent::ScopedIndent(TextGenerator* generator)
|
TextGenerator::ScopedIndent::ScopedIndent(TextGenerator* generator)
|
||||||
: gen(generator) {
|
: ScopedIndent(generator->current_buffer_) {}
|
||||||
gen->increment_indent();
|
|
||||||
|
TextGenerator::ScopedIndent::ScopedIndent(TextBuffer* buffer)
|
||||||
|
: buffer_(buffer) {
|
||||||
|
buffer_->IncrementIndent();
|
||||||
}
|
}
|
||||||
TextGenerator::ScopedIndent::~ScopedIndent() {
|
TextGenerator::ScopedIndent::~ScopedIndent() {
|
||||||
gen->decrement_indent();
|
buffer_->DecrementIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
|
@ -60,38 +60,6 @@ class TextGenerator {
|
|||||||
std::string TrimSuffix(std::string str, const std::string& suffix);
|
std::string TrimSuffix(std::string str, const std::string& suffix);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// LineWriter is a helper that acts as a string buffer, who's content is
|
|
||||||
/// emitted to the TextGenerator as a single line on destruction.
|
|
||||||
struct LineWriter {
|
|
||||||
public:
|
|
||||||
/// Constructor
|
|
||||||
/// @param generator the TextGenerator that the LineWriter will append its
|
|
||||||
/// content to on destruction
|
|
||||||
explicit LineWriter(TextGenerator* generator);
|
|
||||||
/// Move constructor
|
|
||||||
/// @param rhs the LineWriter to move
|
|
||||||
LineWriter(LineWriter&& rhs);
|
|
||||||
/// Destructor
|
|
||||||
~LineWriter();
|
|
||||||
|
|
||||||
/// @returns the ostringstream
|
|
||||||
operator std::ostream &() { return os; }
|
|
||||||
|
|
||||||
/// @param rhs the value to write to the line
|
|
||||||
/// @returns the ostream so calls can be chained
|
|
||||||
template <typename T>
|
|
||||||
std::ostream& operator<<(T&& rhs) {
|
|
||||||
return os << std::forward<T>(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
LineWriter(const LineWriter&) = delete;
|
|
||||||
LineWriter& operator=(const LineWriter&) = delete;
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
TextGenerator* gen;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Line holds a single line of text
|
/// Line holds a single line of text
|
||||||
struct Line {
|
struct Line {
|
||||||
/// The indentation of the line in whitespaces
|
/// The indentation of the line in whitespaces
|
||||||
@ -120,10 +88,23 @@ class TextGenerator {
|
|||||||
/// @param line the line to append to the TextBuffer
|
/// @param line the line to append to the TextBuffer
|
||||||
void Append(const std::string& line);
|
void Append(const std::string& line);
|
||||||
|
|
||||||
|
/// Inserts the line to the TextBuffer before the line with index `before`
|
||||||
|
/// @param line the line to append to the TextBuffer
|
||||||
|
/// @param before the zero-based index of the line to insert the text before
|
||||||
|
/// @param indent the indentation to apply to the inserted lines
|
||||||
|
void Insert(const std::string& line, size_t before, uint32_t indent);
|
||||||
|
|
||||||
/// Appends the lines of `tb` to the end of this TextBuffer
|
/// Appends the lines of `tb` to the end of this TextBuffer
|
||||||
/// @param tb the TextBuffer to append to the end of this TextBuffer
|
/// @param tb the TextBuffer to append to the end of this TextBuffer
|
||||||
void Append(const TextBuffer& tb);
|
void Append(const TextBuffer& tb);
|
||||||
|
|
||||||
|
/// Inserts the lines of `tb` to the TextBuffer before the line with index
|
||||||
|
/// `before`
|
||||||
|
/// @param tb the TextBuffer to insert into this TextBuffer
|
||||||
|
/// @param before the zero-based index of the line to insert the text before
|
||||||
|
/// @param indent the indentation to apply to the inserted lines
|
||||||
|
void Insert(const TextBuffer& tb, size_t before, uint32_t indent);
|
||||||
|
|
||||||
/// @returns the buffer's content as a single string
|
/// @returns the buffer's content as a single string
|
||||||
std::string String() const;
|
std::string String() const;
|
||||||
|
|
||||||
@ -135,6 +116,39 @@ class TextGenerator {
|
|||||||
std::vector<Line> lines;
|
std::vector<Line> lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// LineWriter is a helper that acts as a string buffer, who's content is
|
||||||
|
/// emitted to the TextBuffer as a single line on destruction.
|
||||||
|
struct LineWriter {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// @param buffer the TextBuffer that the LineWriter will append its
|
||||||
|
/// content to on destruction, at the end of the buffer.
|
||||||
|
explicit LineWriter(TextBuffer* buffer);
|
||||||
|
|
||||||
|
/// Move constructor
|
||||||
|
/// @param rhs the LineWriter to move
|
||||||
|
LineWriter(LineWriter&& rhs);
|
||||||
|
/// Destructor
|
||||||
|
~LineWriter();
|
||||||
|
|
||||||
|
/// @returns the ostringstream
|
||||||
|
operator std::ostream &() { return os; }
|
||||||
|
|
||||||
|
/// @param rhs the value to write to the line
|
||||||
|
/// @returns the ostream so calls can be chained
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(T&& rhs) {
|
||||||
|
return os << std::forward<T>(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LineWriter(const LineWriter&) = delete;
|
||||||
|
LineWriter& operator=(const LineWriter&) = delete;
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
TextBuffer* buffer;
|
||||||
|
};
|
||||||
|
|
||||||
/// Helper for writing a '(' on construction and a ')' destruction.
|
/// Helper for writing a '(' on construction and a ')' destruction.
|
||||||
struct ScopedParen {
|
struct ScopedParen {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
@ -154,7 +168,11 @@ class TextGenerator {
|
|||||||
/// indentation on destruction.
|
/// indentation on destruction.
|
||||||
struct ScopedIndent {
|
struct ScopedIndent {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param generator the TextGenerator that the ScopedIndent will indent
|
/// @param buffer the TextBuffer that the ScopedIndent will indent
|
||||||
|
explicit ScopedIndent(TextBuffer* buffer);
|
||||||
|
/// Constructor
|
||||||
|
/// @param generator ScopedIndent will indent the generator's
|
||||||
|
/// `current_buffer_`
|
||||||
explicit ScopedIndent(TextGenerator* generator);
|
explicit ScopedIndent(TextGenerator* generator);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~ScopedIndent();
|
~ScopedIndent();
|
||||||
@ -163,7 +181,7 @@ class TextGenerator {
|
|||||||
ScopedIndent(ScopedIndent&& rhs) = delete;
|
ScopedIndent(ScopedIndent&& rhs) = delete;
|
||||||
ScopedIndent(const ScopedIndent&) = delete;
|
ScopedIndent(const ScopedIndent&) = delete;
|
||||||
ScopedIndent& operator=(const ScopedIndent&) = delete;
|
ScopedIndent& operator=(const ScopedIndent&) = delete;
|
||||||
TextGenerator* gen;
|
TextBuffer* buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @returns the resolved type of the ast::Expression `expr`
|
/// @returns the resolved type of the ast::Expression `expr`
|
||||||
@ -184,8 +202,14 @@ class TextGenerator {
|
|||||||
return builder_.TypeOf(type_decl);
|
return builder_.TypeOf(type_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a new LineWriter, used for buffering and writing a line to out_
|
/// @returns a new LineWriter, used for buffering and writing a line to
|
||||||
LineWriter line() { return LineWriter(this); }
|
/// the end of #current_buffer_.
|
||||||
|
LineWriter line() { return LineWriter(current_buffer_); }
|
||||||
|
|
||||||
|
/// @param buffer the TextBuffer to write the line to
|
||||||
|
/// @returns a new LineWriter, used for buffering and writing a line to
|
||||||
|
/// the end of `buffer`.
|
||||||
|
LineWriter line(TextBuffer* buffer) { return LineWriter(buffer); }
|
||||||
|
|
||||||
/// The program
|
/// The program
|
||||||
Program const* const program_;
|
Program const* const program_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user