Skip to content

Commit

Permalink
Add ParsedVerilogSourceFile (PR #745)
Browse files Browse the repository at this point in the history
verilog/analysis: Add ParsedVerilogSourceFile class
  • Loading branch information
hzeller authored Apr 13, 2021
2 parents d4cd328 + 82d56e3 commit 826998c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
17 changes: 17 additions & 0 deletions verilog/analysis/verilog_project.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@ absl::Status InMemoryVerilogSourceFile::Open() {
return status_;
}

absl::Status ParsedVerilogSourceFile::Open() {
state_ = State::kOpened;
status_ = absl::OkStatus();
return status_;
}

absl::Status ParsedVerilogSourceFile::Parse() {
state_ = State::kParsed;
status_ = absl::OkStatus();
return status_;
}

const verible::TextStructureView* ParsedVerilogSourceFile::GetTextStructure()
const {
return text_structure_;
}

absl::StatusOr<VerilogSourceFile*> VerilogProject::OpenFile(
absl::string_view referenced_filename, absl::string_view resolved_filename,
absl::string_view corpus) {
Expand Down
34 changes: 31 additions & 3 deletions verilog/analysis/verilog_project.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ class VerilogSourceFile {
// Attempts to lex and parse the file (without preprocessing).
// Will Open() if the file is not already opened.
// Depending on context, not all files are suitable for standalone parsing.
absl::Status Parse();
virtual absl::Status Parse();

// After Open(), the underlying text structure contains at least the file's
// contents. After Parse(), it may contain other analyzed structural forms.
// Before Open(), this returns nullptr.
const verible::TextStructureView* GetTextStructure() const;
virtual const verible::TextStructureView* GetTextStructure() const;

// Returns the first non-Ok status if there is one, else OkStatus().
absl::Status Status() const { return status_; }
Expand Down Expand Up @@ -149,7 +149,7 @@ std::ostream& operator<<(std::ostream&, const VerilogSourceFile&);

// An in-memory source file that doesn't require file-system access,
// nor create temporary files.
class InMemoryVerilogSourceFile : public VerilogSourceFile {
class InMemoryVerilogSourceFile final : public VerilogSourceFile {
public:
// filename can be fake, it is not used to open any file.
InMemoryVerilogSourceFile(absl::string_view filename,
Expand All @@ -165,6 +165,34 @@ class InMemoryVerilogSourceFile : public VerilogSourceFile {
const absl::string_view contents_for_open_;
};

// Source file that was already parsed and got its own TextStructure.
// Doesn't require file-system access, nor create temporary files.
class ParsedVerilogSourceFile final : public VerilogSourceFile {
public:
// filename can be fake, it is not used to open any file.
// text_structure is a pointer to a TextStructureView object of
// already parsed file. Current implementation does _not_ make a
// copy of it and expects it will be available for the lifetime of
// object of this class.
ParsedVerilogSourceFile(absl::string_view filename,
const verible::TextStructureView* text_structure,
absl::string_view corpus = "")
: VerilogSourceFile(filename, filename, corpus),
text_structure_(text_structure) {}

// Do nothing (file contents already loaded)
absl::Status Open() override;

// Do nothing (contents already parsed)
absl::Status Parse() override;

// Return TextStructureView provided previously in constructor
const verible::TextStructureView* GetTextStructure() const override;

private:
const verible::TextStructureView* text_structure_;
};

// VerilogProject represents a set of files as a cohesive unit of compilation.
// Files can include top-level translation units and preprocessor included
// files. This is responsible for owning string memory that corresponds
Expand Down
30 changes: 30 additions & 0 deletions verilog/analysis/verilog_project_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,36 @@ TEST(InMemoryVerilogSourceFileTest, ParseInvalidFile) {
EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(ParsedVerilogSourceFileTest, ParseValidFile) {
constexpr absl::string_view text("localparam int p = 1;\n");
std::unique_ptr<VerilogAnalyzer> analyzed_structure =
absl::make_unique<VerilogAnalyzer>(text, "internal");
absl::Status status = analyzed_structure->Analyze();
EXPECT_TRUE(status.ok());
const TextStructureView& input_text_structure = analyzed_structure->Data();

ParsedVerilogSourceFile file("internal", &input_text_structure);
// Parse automatically opens.
EXPECT_TRUE(file.Parse().ok());
EXPECT_TRUE(file.Status().ok());
const TextStructureView* text_structure =
ABSL_DIE_IF_NULL(file.GetTextStructure());
EXPECT_EQ(&input_text_structure, text_structure);
const absl::string_view owned_string_range(text_structure->Contents());
EXPECT_EQ(owned_string_range, text);
const auto* tokens = &text_structure->TokenStream();
EXPECT_NE(tokens, nullptr);
const auto* tree = &text_structure->SyntaxTree();
EXPECT_NE(tree, nullptr);

// Re-parsing doesn't change anything
EXPECT_TRUE(file.Parse().ok());
EXPECT_TRUE(file.Status().ok());
EXPECT_EQ(file.GetTextStructure(), text_structure);
EXPECT_EQ(&text_structure->TokenStream(), tokens);
EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(VerilogProjectTest, Initialization) {
const auto tempdir = ::testing::TempDir();
VerilogProject project(tempdir, {tempdir});
Expand Down

0 comments on commit 826998c

Please sign in to comment.