blob: 7f70b7061f277c46b9b25a6bc50ca8c364024590 [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_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_
#define VERIBLE_VERILOG_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "common/text/token_info.h"
#include "common/util/vector_tree.h"
#include "verilog/tools/kythe/verilog_extractor_indexing_fact_type.h"
namespace verilog {
namespace kythe {
// Position of the Anchor in the original text. Required to be able to reference
// Anchor's content in the original string (as Anchor is owning its content --
// string_view is not applicable).
struct AnchorRange {
const size_t begin;
const size_t length;
AnchorRange(size_t b, size_t l) : begin(b), length(l) {}
};
// Anchor class represents the location and value of some token.
class Anchor {
public:
explicit Anchor(absl::string_view value) : content_(value) {}
explicit Anchor(absl::string_view value, size_t begin, size_t length)
: content_(value) {
source_text_range_.emplace(begin, length);
}
// Delegates construction to use only the string_view spanned by a TokenInfo.
// Recall the TokenInfo's string point to substrings of memory owned
// elsewhere.
explicit Anchor(const verible::TokenInfo& token,
absl::string_view source_content)
: content_(token.text()) {
const int token_left = token.left(source_content);
const int token_right = token.right(source_content);
source_text_range_.emplace(token_left, token_right - token_left);
}
Anchor(const Anchor&); // TODO(fangism): delete, move-only
Anchor(Anchor&&) = default;
Anchor& operator=(const Anchor&) = delete;
Anchor& operator=(Anchor&&) = delete;
// Returns human readable view of this Anchor.
std::string DebugString() const;
absl::string_view Text() const { return content_; }
// Returns the location of the Anchor's content in the original string.
const std::optional<AnchorRange>& SourceTextRange() const {
return source_text_range_;
}
bool operator==(const Anchor&) const;
bool operator!=(const Anchor& other) const { return !(*this == other); }
private:
// Substring of the original text that corresponds to this Anchor.
std::string content_;
std::optional<AnchorRange> source_text_range_;
};
std::ostream& operator<<(std::ostream&, const Anchor&);
// This class is a simplified representation of CST and contains information
// that can be used for extracting indexing-facts for different indexing tools.
//
// This is intended to be an abstract layer between the parser generated CST
// and the indexing tool.
class IndexingNodeData {
public:
template <typename... Args>
/* implicit */ IndexingNodeData(IndexingFactType language_feature, // NOLINT
Args&&... args)
: indexing_fact_type_(language_feature) {
AppendAnchor(std::forward<Args>(args)...);
}
IndexingNodeData(const IndexingNodeData&) = default;
IndexingNodeData& operator=(IndexingNodeData&&) = default;
// TODO(fangism): delete copy-ctor to make this move-only
IndexingNodeData(IndexingNodeData&&) = default;
IndexingNodeData& operator=(const IndexingNodeData&) = delete;
// Consume an Anchor object(s), variadically.
template <typename... Args>
void AppendAnchor(Anchor&& anchor, Args&&... args) {
anchors_.emplace_back(std::move(anchor));
AppendAnchor(std::forward<Args>(args)...);
}
// Swaps the anchors with the given IndexingNodeData.
void SwapAnchors(IndexingNodeData* other) { anchors_.swap(other->anchors_); }
// Returns human readable view of this node.
std::ostream& DebugString(std::ostream* stream) const;
const std::vector<Anchor>& Anchors() const { return anchors_; }
IndexingFactType GetIndexingFactType() const { return indexing_fact_type_; }
// Redirects all non-owned string_views to point into a different copy of the
// same text, located 'delta' away. This is useful for testing, when source
// text is copied to a different location.
void RebaseStringViewsForTesting(std::ptrdiff_t delta);
bool operator==(const IndexingNodeData&) const;
bool operator!=(const IndexingNodeData& other) const {
return !(*this == other);
}
private:
// Base case for variadic AppendAnchor()
void AppendAnchor() const {}
private:
// Represents which language feature this indexing fact is about.
IndexingFactType indexing_fact_type_;
// Anchors representing the different tokens of this indexing fact.
std::vector<Anchor> anchors_;
};
// Without a base string_view, this displays the base-address and length of each
// Anchor's string_view. See PrintableIndexingNodeData for a more readable
// alternative using byte-offsets.
std::ostream& operator<<(std::ostream&, const IndexingNodeData&);
// Pairs together IndexingNodeData and string_view to be a printable object.
struct PrintableIndexingNodeData {
const IndexingNodeData& data;
// The superstring of which all string_views in this subtree is a substring.
const absl::string_view base;
PrintableIndexingNodeData(const IndexingNodeData& data,
absl::string_view base)
: data(data), base(base) {}
};
// Human-readable form for debugging, showing in-file byte offsets of
// string_views.
std::ostream& operator<<(std::ostream&, const PrintableIndexingNodeData&);
// Renaming for VectorTree; IndexingFactNode is actually a VectorTree which is a
// class for constructing trees and dealing with them in a elegant manner.
using IndexingFactNode = verible::VectorTree<IndexingNodeData>;
struct PrintableIndexingFactNode {
const IndexingFactNode& data;
// The superstring of which all string_views in this subtree is a substring.
const absl::string_view base;
PrintableIndexingFactNode(const IndexingFactNode& data,
absl::string_view base)
: data(data), base(base) {}
};
// Human-readable form for debugging.
std::ostream& operator<<(std::ostream&, const PrintableIndexingFactNode&);
} // namespace kythe
} // namespace verilog
#endif // VERIBLE_VERILOG_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_