brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · ccfdcd0 Raw
273 lines · cpp
1//===- SynthesisTest.cpp --------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file tests synthesis API for syntax trees.10//11//===----------------------------------------------------------------------===//12 13#include "TreeTestBase.h"14#include "clang/Tooling/Syntax/BuildTree.h"15#include "clang/Tooling/Syntax/Nodes.h"16#include "gtest/gtest.h"17 18using namespace clang;19using namespace clang::syntax;20 21namespace {22 23class SynthesisTest : public SyntaxTreeTest {24protected:25  ::testing::AssertionResult treeDumpEqual(syntax::Node *Root, StringRef Dump) {26    if (!Root)27      return ::testing::AssertionFailure()28             << "Root was not built successfully.";29 30    auto Actual = StringRef(Root->dump(*TM)).trim().str();31    auto Expected = Dump.trim().str();32    // EXPECT_EQ shows the diff between the two strings if they are different.33    EXPECT_EQ(Expected, Actual);34    if (Actual != Expected) {35      return ::testing::AssertionFailure();36    }37    return ::testing::AssertionSuccess();38  }39};40 41INSTANTIATE_TEST_SUITE_P(42    SynthesisTests, SynthesisTest, ::testing::ValuesIn(allTestClangConfigs()),43    [](const testing::TestParamInfo<TestClangConfig> &Info) {44      return Info.param.toShortString();45    });46 47TEST_P(SynthesisTest, Leaf_Punctuation) {48  buildTree("", GetParam());49 50  auto *Leaf = createLeaf(*Arena, *TM, tok::comma);51 52  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(53',' Detached synthesized54  )txt"));55}56 57TEST_P(SynthesisTest, Leaf_Punctuation_CXX) {58  if (!GetParam().isCXX())59    return;60 61  buildTree("", GetParam());62 63  auto *Leaf = createLeaf(*Arena, *TM, tok::coloncolon);64 65  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(66'::' Detached synthesized67  )txt"));68}69 70TEST_P(SynthesisTest, Leaf_Keyword) {71  buildTree("", GetParam());72 73  auto *Leaf = createLeaf(*Arena, *TM, tok::kw_if);74 75  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(76'if' Detached synthesized77  )txt"));78}79 80TEST_P(SynthesisTest, Leaf_Keyword_CXX11) {81  if (!GetParam().isCXX11OrLater())82    return;83 84  buildTree("", GetParam());85 86  auto *Leaf = createLeaf(*Arena, *TM, tok::kw_nullptr);87 88  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(89'nullptr' Detached synthesized90  )txt"));91}92 93TEST_P(SynthesisTest, Leaf_Identifier) {94  buildTree("", GetParam());95 96  auto *Leaf = createLeaf(*Arena, *TM, tok::identifier, "a");97 98  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(99'a' Detached synthesized100  )txt"));101}102 103TEST_P(SynthesisTest, Leaf_Number) {104  buildTree("", GetParam());105 106  auto *Leaf = createLeaf(*Arena, *TM, tok::numeric_constant, "1");107 108  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(109'1' Detached synthesized110  )txt"));111}112 113TEST_P(SynthesisTest, Tree_Empty) {114  buildTree("", GetParam());115 116  auto *Tree = createTree(*Arena, {}, NodeKind::UnknownExpression);117 118  EXPECT_TRUE(treeDumpEqual(Tree, R"txt(119UnknownExpression Detached synthesized120  )txt"));121}122 123TEST_P(SynthesisTest, Tree_Flat) {124  buildTree("", GetParam());125 126  auto *LeafLParen = createLeaf(*Arena, *TM, tok::l_paren);127  auto *LeafRParen = createLeaf(*Arena, *TM, tok::r_paren);128  auto *TreeParen = createTree(*Arena,129                               {{LeafLParen, NodeRole::LeftHandSide},130                                {LeafRParen, NodeRole::RightHandSide}},131                               NodeKind::ParenExpression);132 133  EXPECT_TRUE(treeDumpEqual(TreeParen, R"txt(134ParenExpression Detached synthesized135|-'(' LeftHandSide synthesized136`-')' RightHandSide synthesized137  )txt"));138}139 140TEST_P(SynthesisTest, Tree_OfTree) {141  buildTree("", GetParam());142 143  auto *Leaf1 = createLeaf(*Arena, *TM, tok::numeric_constant, "1");144  auto *Int1 = createTree(*Arena, {{Leaf1, NodeRole::LiteralToken}},145                          NodeKind::IntegerLiteralExpression);146 147  auto *LeafPlus = createLeaf(*Arena, *TM, tok::plus);148 149  auto *Leaf2 = createLeaf(*Arena, *TM, tok::numeric_constant, "2");150  auto *Int2 = createTree(*Arena, {{Leaf2, NodeRole::LiteralToken}},151                          NodeKind::IntegerLiteralExpression);152 153  auto *TreeBinaryOperator = createTree(*Arena,154                                        {{Int1, NodeRole::LeftHandSide},155                                         {LeafPlus, NodeRole::OperatorToken},156                                         {Int2, NodeRole::RightHandSide}},157                                        NodeKind::BinaryOperatorExpression);158 159  EXPECT_TRUE(treeDumpEqual(TreeBinaryOperator, R"txt(160BinaryOperatorExpression Detached synthesized161|-IntegerLiteralExpression LeftHandSide synthesized162| `-'1' LiteralToken synthesized163|-'+' OperatorToken synthesized164`-IntegerLiteralExpression RightHandSide synthesized165  `-'2' LiteralToken synthesized166  )txt"));167}168 169TEST_P(SynthesisTest, DeepCopy_Synthesized) {170  buildTree("", GetParam());171 172  auto *LeafContinue = createLeaf(*Arena, *TM, tok::kw_continue);173  auto *LeafSemiColon = createLeaf(*Arena, *TM, tok::semi);174  auto *StatementContinue = createTree(*Arena,175                                       {{LeafContinue, NodeRole::LiteralToken},176                                        {LeafSemiColon, NodeRole::Unknown}},177                                       NodeKind::ContinueStatement);178 179  auto *Copy = deepCopyExpandingMacros(*Arena, *TM, StatementContinue);180  EXPECT_TRUE(treeDumpEqual(Copy, StatementContinue->dump(*TM)));181  // FIXME: Test that copy is independent of original, once the Mutations API is182  // more developed.183}184 185TEST_P(SynthesisTest, DeepCopy_Original) {186  auto *OriginalTree = buildTree("int a;", GetParam());187 188  auto *Copy = deepCopyExpandingMacros(*Arena, *TM, OriginalTree);189  EXPECT_TRUE(treeDumpEqual(Copy, R"txt(190TranslationUnit Detached synthesized191`-SimpleDeclaration synthesized192  |-'int' synthesized193  |-DeclaratorList Declarators synthesized194  | `-SimpleDeclarator ListElement synthesized195  |   `-'a' synthesized196  `-';' synthesized197  )txt"));198}199 200TEST_P(SynthesisTest, DeepCopy_Child) {201  auto *OriginalTree = buildTree("int a;", GetParam());202 203  auto *Copy =204      deepCopyExpandingMacros(*Arena, *TM, OriginalTree->getFirstChild());205  EXPECT_TRUE(treeDumpEqual(Copy, R"txt(206SimpleDeclaration Detached synthesized207|-'int' synthesized208|-DeclaratorList Declarators synthesized209| `-SimpleDeclarator ListElement synthesized210|   `-'a' synthesized211`-';' synthesized212  )txt"));213}214 215TEST_P(SynthesisTest, DeepCopy_Macro) {216  auto *OriginalTree = buildTree(R"cpp(217#define HALF_IF if (1+218#define HALF_IF_2 1) {}219void test() {220  HALF_IF HALF_IF_2 else {}221})cpp",222                                 GetParam());223 224  auto *Copy = deepCopyExpandingMacros(*Arena, *TM, OriginalTree);225 226  // The syntax tree stores already expanded Tokens, we can only see whether the227  // macro was expanded when computing replacements. The dump does show that228  // nodes in the copy are `modifiable`.229  EXPECT_TRUE(treeDumpEqual(Copy, R"txt(230TranslationUnit Detached synthesized231`-SimpleDeclaration synthesized232  |-'void' synthesized233  |-DeclaratorList Declarators synthesized234  | `-SimpleDeclarator ListElement synthesized235  |   |-'test' synthesized236  |   `-ParametersAndQualifiers synthesized237  |     |-'(' OpenParen synthesized238  |     `-')' CloseParen synthesized239  `-CompoundStatement synthesized240    |-'{' OpenParen synthesized241    |-IfStatement Statement synthesized242    | |-'if' IntroducerKeyword synthesized243    | |-'(' synthesized244    | |-ExpressionStatement Condition synthesized245    | | `-BinaryOperatorExpression Expression synthesized246    | |   |-IntegerLiteralExpression LeftHandSide synthesized247    | |   | `-'1' LiteralToken synthesized248    | |   |-'+' OperatorToken synthesized249    | |   `-IntegerLiteralExpression RightHandSide synthesized250    | |     `-'1' LiteralToken synthesized251    | |-')' synthesized252    | |-CompoundStatement ThenStatement synthesized253    | | |-'{' OpenParen synthesized254    | | `-'}' CloseParen synthesized255    | |-'else' ElseKeyword synthesized256    | `-CompoundStatement ElseStatement synthesized257    |   |-'{' OpenParen synthesized258    |   `-'}' CloseParen synthesized259    `-'}' CloseParen synthesized260  )txt"));261}262 263TEST_P(SynthesisTest, Statement_EmptyStatement) {264  buildTree("", GetParam());265 266  auto *S = createEmptyStatement(*Arena, *TM);267  EXPECT_TRUE(treeDumpEqual(S, R"txt(268EmptyStatement Detached synthesized269`-';' synthesized270  )txt"));271}272} // namespace273