brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · e043cc8 Raw
252 lines · cpp
1//===-- PopulateSwitchTest.cpp ----------------------------------*- C++ -*-===//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#include "TweakTesting.h"10#include "gmock/gmock.h"11#include "gtest/gtest.h"12 13namespace clang {14namespace clangd {15namespace {16 17TWEAK_TEST(PopulateSwitch);18 19TEST_F(PopulateSwitchTest, Test) {20  struct Case {21    CodeContext Context;22    llvm::StringRef TestSource;23    llvm::StringRef ExpectedSource;24    llvm::StringRef FileName = "TestTU.cpp";25  };26 27  Case Cases[]{28      {29          // No enumerators30          Function,31          R""(enum Enum {}; ^switch ((Enum)0) {})"",32          "unavailable",33      },34      {35          // All enumerators already in switch (unscoped)36          Function,37          R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",38          "unavailable",39      },40      {41          // All enumerators already in switch (scoped)42          Function,43          R""(44            enum class Enum {A,B};45            ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}46          )"",47          "unavailable",48      },49      {50          // Default case in switch51          Function,52          R""(53            enum class Enum {A,B};54            ^switch (Enum::A) {default:break;}55          )"",56          "unavailable",57      },58      {59          // GNU range in switch60          Function,61          R""(62            enum class Enum {A,B};63            ^switch (Enum::A) {case Enum::A ... Enum::B:break;}64          )"",65          "unavailable",66      },67      {68          // Value dependent case expression69          File,70          R""(71            enum class Enum {A,B};72            template<Enum Value>73            void function() {74                ^switch (Enum::A) {case Value:break;}75            }76          )"",77          "unavailable",78      },79      {80          // Body not CompoundStmt81          Function,82          R""(enum Enum {A}; ^switch (A);)"",83          "unavailable",84      },85      {86          // Selection on switch token87          Function,88          R""(enum Enum {A}; ^switch (A) {})"",89          R""(enum Enum {A}; switch (A) {case A:break;})"",90      },91      {92          // Selection on switch condition93          Function,94          R""(enum Enum {A}; switch (^A) {})"",95          R""(enum Enum {A}; switch (A) {case A:break;})"",96      },97      {98          // Selection of whole switch condition99          Function,100          R""(enum Enum {A}; switch ([[A]]) {})"",101          R""(enum Enum {A}; switch (A) {case A:break;})"",102      },103      {104          // Selection in switch body105          Function,106          R""(enum Enum {A}; switch (A) {^})"",107          R""(enum Enum {A}; switch (A) {case A:break;})"",108      },109      {110          // Scoped enumeration111          Function,112          R""(enum class Enum {A}; ^switch (Enum::A) {})"",113          R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",114      },115      {116          // Scoped enumeration with multiple enumerators117          Function,118          R""(119            enum class Enum {A,B};120            ^switch (Enum::A) {}121          )"",122          R""(123            enum class Enum {A,B};124            switch (Enum::A) {case Enum::A:case Enum::B:break;}125          )"",126      },127      {128          // Only filling in missing enumerators (unscoped)129          Function,130          R""(131            enum Enum {A,B,C};132            ^switch (A) {case B:break;}133          )"",134          R""(135            enum Enum {A,B,C};136            switch (A) {case B:break;case A:case C:break;}137          )"",138      },139      {140          // Only filling in missing enumerators,141          // even when using integer literals142          Function,143          R""(144            enum Enum {A,B=1,C};145            ^switch (A) {case 1:break;}146          )"",147          R""(148            enum Enum {A,B=1,C};149            switch (A) {case 1:break;case A:case C:break;}150          )"",151      },152      {153          // Only filling in missing enumerators (scoped)154          Function,155          R""(156            enum class Enum {A,B,C};157            ^switch (Enum::A)158            {case Enum::B:break;}159          )"",160          R""(161            enum class Enum {A,B,C};162            switch (Enum::A)163            {case Enum::B:break;case Enum::A:case Enum::C:break;}164          )"",165      },166      {167          // Scoped enumerations in namespace168          File,169          R""(170            namespace ns { enum class Enum {A}; }171            void function() { ^switch (ns::Enum::A) {} }172          )"",173          R""(174            namespace ns { enum class Enum {A}; }175            void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }176          )"",177      },178      {179          // Unscoped enumerations in namespace180          File,181          R""(182            namespace ns { enum Enum {A}; }183            void function() { ^switch (ns::A) {} }184          )"",185          R""(186            namespace ns { enum Enum {A}; }187            void function() { switch (ns::A) {case ns::A:break;} }188          )"",189      },190      {191          // Duplicated constant names192          Function,193          R""(enum Enum {A,B,b=B}; ^switch (A) {})"",194          R""(enum Enum {A,B,b=B}; switch (A) {case A:case B:break;})"",195      },196      {197          // Duplicated constant names all in switch198          Function,199          R""(enum Enum {A,B,b=B}; ^switch (A) {case A:case B:break;})"",200          "unavailable",201      },202      {203          // Enum is dependent type204          File,205          R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",206          "unavailable",207      },208      {// C: Only filling in missing enumerators209       Function,210       R""(211            enum CEnum {A,B,C};212            enum CEnum val = A;213            ^switch (val) {case B:break;}214          )"",215       R""(216            enum CEnum {A,B,C};217            enum CEnum val = A;218            switch (val) {case B:break;case A:case C:break;}219          )"",220       "TestTU.c"},221      {// C: Only filling in missing enumerators w/ typedefs222       Function,223       R""(224            typedef unsigned long UInteger;225            enum ControlState : UInteger;226            typedef enum ControlState ControlState;227            enum ControlState : UInteger {A,B,C};228            ControlState controlState = A;229            switch (^controlState) {case A:break;}230          )"",231       R""(232            typedef unsigned long UInteger;233            enum ControlState : UInteger;234            typedef enum ControlState ControlState;235            enum ControlState : UInteger {A,B,C};236            ControlState controlState = A;237            switch (controlState) {case A:break;case B:case C:break;}238          )"",239       "TestTU.c"},240  };241 242  for (const auto &Case : Cases) {243    Context = Case.Context;244    FileName = Case.FileName;245    EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);246  }247}248 249} // namespace250} // namespace clangd251} // namespace clang252