blob: d82525388501255189d0333718c52f17f6c65caa [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VERIBLE_VERILOG_FORMATTING_TREE_UNWRAPPER_H_
#define VERIBLE_VERILOG_FORMATTING_TREE_UNWRAPPER_H_
#include <algorithm>
#include <functional>
#include <memory>
#include <vector>
#include "common/formatting/basic_format_style.h"
#include "common/formatting/format_token.h"
#include "common/formatting/token_partition_tree.h"
#include "common/formatting/tree_unwrapper.h"
#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/syntax_tree_context.h"
#include "common/text/text_structure.h"
#include "common/text/token_info.h"
#include "common/text/token_stream_view.h"
#include "verilog/formatting/format_style.h"
#include "verilog/parser/verilog_token_enum.h"
namespace verilog {
namespace formatter {
// Data bundle that needs to outlive TreeUnwrapper.
// This data lives outside of TreeUnwrapper so it can be accessible to
// other phases of the formatter.
struct UnwrapperData {
// TokenStreamView that removes spaces, but preserves comments.
verible::TokenStreamView tokens_view_no_whitespace;
// Array of PreFormatTokens that will be partitioned into UnwrappedLines.
std::vector<verible::PreFormatToken> preformatted_tokens;
explicit UnwrapperData(const verible::TokenSequence&);
};
enum class ContextHint;
// Derived TreeUnwrapper for Verilog Formatting.
// Contains all visitors and logic necessary for creating UnwrappedLines for
// Verilog and SystemVerilog code.
class TreeUnwrapper final : public verible::TreeUnwrapper {
public:
explicit TreeUnwrapper(const verible::TextStructureView& view,
const FormatStyle& style,
const preformatted_tokens_type&);
~TreeUnwrapper() final;
// Deleted standard interfaces:
TreeUnwrapper() = delete;
TreeUnwrapper(const TreeUnwrapper&) = delete;
TreeUnwrapper(TreeUnwrapper&&) = delete;
TreeUnwrapper& operator=(const TreeUnwrapper&) = delete;
TreeUnwrapper& operator=(TreeUnwrapper&&) = delete;
using verible::TreeUnwrapper::Unwrap;
private:
typedef std::vector<verible::PreFormatToken> preformatted_tokens_type;
// Private implementation type for handling tokens between syntax tree leaves.
class TokenScanner;
// Collects filtered tokens into the UnwrappedLines from
// next_unfiltered_token_ up until the TokenInfo referenced by leaf.
// \postcondition next_unfiltered_token_ points to token corresponding to
// leaf.
void CatchUpToCurrentLeaf(const verible::TokenInfo& leaf_token);
void LookAheadBeyondCurrentLeaf();
void LookAheadBeyondCurrentNode();
void InterChildNodeHook(const verible::SyntaxTreeNode&) final;
void CollectLeadingFilteredTokens() final;
// Collects filtered tokens into the UnwrappedLines from
// next_unfiltered_token_ until EOF.
void CollectTrailingFilteredTokens() final;
void Visit(const verible::SyntaxTreeLeaf& leaf) final;
void Visit(const verible::SyntaxTreeNode& node) final;
void SetIndentationsAndCreatePartitions(const verible::SyntaxTreeNode& node);
void ReshapeTokenPartitions(const verible::SyntaxTreeNode& node,
const FormatStyle& style,
verible::TokenPartitionTree* recent_partition);
// Visits a node which requires a new UnwrappedLine, followed by
// traversing all children
void VisitNewUnwrappedLine(const verible::SyntaxTreeNode& node);
// Visits a node which requires a new UnwrappedLine, followed by
// traversing all children. The new UnwrappedLine is *not* indented,
// which is used for flush-left constructs.
void VisitNewUnindentedUnwrappedLine(const verible::SyntaxTreeNode& node);
// Advance next_unfiltered_token_ past any TK_SPACE tokens.
// This is a stop-gap to help account for the change in
// the KeepNonWhitespace (private) function, where we filtered out newlines
// for the sake of PreFormatToken generation.
// Where we used to traverse more inclusive filtered tokens, we must now
// traverse unfiltered tokens.
void EatSpaces();
// Update token tracking, and possibly start a new partition.
void UpdateInterLeafScanner(verilog_tokentype);
// This should only be called directly from CatchUpToCurrentLeaf and
// LookAheadBeyondCurrentLeaf.
void AdvanceLastVisitedLeaf();
// For print debugging.
verible::TokenWithContext VerboseToken(const verible::TokenInfo&) const;
// For print debugging.
verible::TokenPartitionTreePrinter VerilogPartitionPrinter(
const verible::TokenPartitionTree& partition) const;
// Data members:
// Formatting style configuration.
const FormatStyle& style_;
// State machine for visiting non-syntax-tree tokens between leaves.
// This determines placement of comments on unwrapped lines.
// (Private-implementation idiom)
std::unique_ptr<TokenScanner> inter_leaf_scanner_;
void PushContextHint(ContextHint hint) { context_hints_.push_back(hint); }
bool HasContextHint(ContextHint hint) const {
return std::find(context_hints_.rbegin(), context_hints_.rend(), hint) !=
context_hints_.rend();
}
const std::vector<ContextHint>& ContextHints() const {
return context_hints_;
}
std::vector<ContextHint> context_hints_;
// For debug printing.
verible::TokenInfo::Context token_context_;
};
} // namespace formatter
} // namespace verilog
#endif // VERIBLE_VERILOG_FORMATTING_TREE_UNWRAPPER_H_