| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- // 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
- #include "toolchain/semantics/semantics_ir_factory.h"
- #include <gmock/gmock.h>
- #include <gtest/gtest.h>
- #include "toolchain/diagnostics/mocks.h"
- #include "toolchain/lexer/tokenized_buffer.h"
- #include "toolchain/parser/parse_tree.h"
- #include "toolchain/semantics/semantics_ir_test_helpers.h"
- #include "toolchain/source/source_buffer.h"
- namespace Carbon::Testing {
- namespace {
- using ::testing::_;
- using ::testing::ElementsAre;
- using ::testing::Eq;
- using ::testing::IsEmpty;
- using ::testing::Optional;
- using ::testing::UnorderedElementsAre;
- class SemanticsIRFactoryTest : public ::testing::Test {
- protected:
- void Build(llvm::Twine t) {
- source_buffer.emplace(std::move(*SourceBuffer::CreateFromText(t)));
- tokenized_buffer = TokenizedBuffer::Lex(*source_buffer, consumer);
- EXPECT_FALSE(tokenized_buffer->has_errors());
- parse_tree = ParseTree::Parse(*tokenized_buffer, consumer);
- EXPECT_FALSE(parse_tree->has_errors());
- SemanticsIRForTest::set_semantics(SemanticsIRFactory::Build(*parse_tree));
- }
- ~SemanticsIRFactoryTest() override { SemanticsIRForTest::clear(); }
- void ExpectRootBlock(
- ::testing::Matcher<llvm::ArrayRef<Semantics::Declaration>> decls,
- ::testing::Matcher<llvm::StringMap<Semantics::Declaration>> name_lookup) {
- EXPECT_THAT(SemanticsIRForTest::semantics().root_block().nodes(), decls);
- EXPECT_THAT(SemanticsIRForTest::semantics().root_block().name_lookup(),
- name_lookup);
- }
- llvm::Optional<SourceBuffer> source_buffer;
- llvm::Optional<TokenizedBuffer> tokenized_buffer;
- llvm::Optional<ParseTree> parse_tree;
- MockDiagnosticConsumer consumer;
- };
- /*
- TEST_F(SemanticsIRFactoryTest, SimpleProgram) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(// package FactoryTest api;
- fn Add(x: i32, y: i32) -> i32 {
- return x + y;
- }
- fn Main() -> i32 {
- var x: i32 = Add(3, 10);
- x *= 5;
- return x;
- }
- )");
- ExpectRootBlock(
- ElementsAre(
- Function(
- Eq("Add"),
- ElementsAre(PatternBinding(Eq("x"), Literal("i32")),
- PatternBinding(Eq("y"), Literal("i32"))),
- Optional(Literal("i32"))),
- Function(Eq("Main"), IsEmpty(), Optional(Literal("i32")))),
- UnorderedElementsAre(MappedNode("Add", FunctionName("Add")),
- MappedNode("Main", FunctionName("Main"))));
- }
- */
- TEST_F(SemanticsIRFactoryTest, Empty) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build("");
- ExpectRootBlock(IsEmpty(), IsEmpty());
- }
- TEST_F(SemanticsIRFactoryTest, FunctionBasic) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build("fn Foo() {}");
- ExpectRootBlock(ElementsAre(Function(Eq("Foo"), IsEmpty(), IsNone(),
- StatementBlock(IsEmpty(), IsEmpty()))),
- UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
- }
- TEST_F(SemanticsIRFactoryTest, FunctionParams) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build("fn Foo(x: i32, y: i64) {}");
- ExpectRootBlock(
- ElementsAre(Function(Eq("Foo"),
- ElementsAre(PatternBinding(Eq("x"), Literal("i32")),
- PatternBinding(Eq("y"), Literal("i64"))),
- IsNone(), StatementBlock(IsEmpty(), IsEmpty()))),
- UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
- }
- TEST_F(SemanticsIRFactoryTest, FunctionReturnType) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build("fn Foo() -> i32 {}");
- ExpectRootBlock(
- ElementsAre(Function(Eq("Foo"), IsEmpty(), Optional(Literal("i32")),
- StatementBlock(IsEmpty(), IsEmpty()))),
- UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
- }
- TEST_F(SemanticsIRFactoryTest, FunctionDuplicate) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(fn Foo() {}
- fn Foo() {}
- )");
- ExpectRootBlock(ElementsAre(FunctionName("Foo"), FunctionName("Foo")),
- UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
- }
- TEST_F(SemanticsIRFactoryTest, FunctionOrder) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(fn Foo() {}
- fn Bar() {}
- )");
- ExpectRootBlock(ElementsAre(FunctionName("Foo"), FunctionName("Bar")),
- UnorderedElementsAre(MappedNode("Bar", FunctionName("Bar")),
- MappedNode("Foo", FunctionName("Foo"))));
- }
- TEST_F(SemanticsIRFactoryTest, TrivialReturn) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(fn Main() {
- return;
- }
- )");
- ExpectRootBlock(
- ElementsAre(
- Function(Eq("Main"), IsEmpty(), IsNone(),
- StatementBlock(ElementsAre(Return(IsNone())), IsEmpty()))),
- UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
- }
- TEST_F(SemanticsIRFactoryTest, ReturnLiteral) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(fn Main() {
- return 1;
- }
- )");
- ExpectRootBlock(
- ElementsAre(
- Function(Eq("Main"), IsEmpty(), IsNone(),
- StatementBlock(ElementsAre(Return(Optional(Literal("1")))),
- IsEmpty()))),
- UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
- }
- TEST_F(SemanticsIRFactoryTest, ReturnArithmetic) {
- EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
- Build(R"(fn Main() {
- return 1 + 2;
- }
- )");
- ExpectRootBlock(
- ElementsAre(
- Function(Eq("Main"), IsEmpty(), IsNone(),
- StatementBlock(ElementsAre(Return(Optional(InfixOperator(
- Literal("1"), "+", Literal("2"))))),
- IsEmpty()))),
- UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
- }
- } // namespace
- } // namespace Carbon::Testing
|