From 5b989680ffd8807b7b052f94027118b8c1db71b1 Mon Sep 17 00:00:00 2001
From: con <qtc-committer@nokia.com>
Date: Mon, 19 Jul 2010 16:03:49 +0200
Subject: [PATCH] Fixes: Completing switch statements with enums in namespaces
 or classes.

We need to add the fully qualified name to the case statements.

Reviewed-by: Roberto Raggi
---
 src/libs/cplusplus/Overview.cpp               | 12 +++++++
 src/libs/cplusplus/Overview.h                 |  4 +++
 src/plugins/cppeditor/cpphoverhandler.cpp     | 10 ++----
 src/plugins/cppeditor/cppquickfix.cpp         | 31 +++++++++++++++----
 .../completeswitchcasestatement.cpp           | 30 ++++++++++++++++++
 5 files changed, 73 insertions(+), 14 deletions(-)

diff --git a/src/libs/cplusplus/Overview.cpp b/src/libs/cplusplus/Overview.cpp
index 48cdb009b75..78d5373b747 100644
--- a/src/libs/cplusplus/Overview.cpp
+++ b/src/libs/cplusplus/Overview.cpp
@@ -137,6 +137,18 @@ QString Overview::prettyName(const Name *name) const
     return pp(name);
 }
 
+QString Overview::prettyName(const QList<const Name *> &fullyQualifiedName) const
+{
+    QString result;
+    const int size = fullyQualifiedName.size();
+    for (int i = 0; i < size; ++i) {
+        result.append(prettyName(fullyQualifiedName.at(i)));
+        if (i < size - 1)
+            result.append(QLatin1String("::"));
+    }
+    return result;
+}
+
 QString Overview::prettyType(const FullySpecifiedType &ty, const Name *name) const
 {
     return prettyType(ty, prettyName(name));
diff --git a/src/libs/cplusplus/Overview.h b/src/libs/cplusplus/Overview.h
index 7471f306a12..3982aca7dab 100644
--- a/src/libs/cplusplus/Overview.h
+++ b/src/libs/cplusplus/Overview.h
@@ -72,10 +72,14 @@ public:
     QString operator()(const Name *name) const
     { return prettyName(name); }
 
+    QString operator()(const QList<const Name *> &fullyQualifiedName) const
+    { return prettyName(fullyQualifiedName); }
+
     QString operator()(const FullySpecifiedType &type, const Name *name = 0) const
     { return prettyType(type, name); }
 
     QString prettyName(const Name *name) const;
+    QString prettyName(const QList<const Name *> &fullyQualifiedName) const;
     QString prettyType(const FullySpecifiedType &type, const Name *name = 0) const;
     QString prettyType(const FullySpecifiedType &type, const QString &name) const;
 
diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp
index 5c84e868412..5e46c19c9ea 100644
--- a/src/plugins/cppeditor/cpphoverhandler.cpp
+++ b/src/plugins/cppeditor/cpphoverhandler.cpp
@@ -289,14 +289,8 @@ void CppHoverHandler::handleLookupItemMatch(const LookupItem &lookupItem, const
         if (matchingDeclaration->enclosingSymbol()->isClass() ||
             matchingDeclaration->enclosingSymbol()->isNamespace() ||
             matchingDeclaration->enclosingSymbol()->isEnum()) {
-            const QList<const Name *> &names =
-                LookupContext::fullyQualifiedName(matchingDeclaration);
-            const int size = names.size();
-            for (int i = 0; i < size; ++i) {
-                qualifiedName.append(overview.prettyName(names.at(i)));
-                if (i < size - 1)
-                    qualifiedName.append(QLatin1String("::"));
-            }
+            qualifiedName.append(overview.prettyName(
+                    LookupContext::fullyQualifiedName(matchingDeclaration)));
         } else {
             qualifiedName.append(overview.prettyName(matchingDeclaration->name()));
         }
diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp
index 15c827bc89b..4f17fe1e6ae 100644
--- a/src/plugins/cppeditor/cppquickfix.cpp
+++ b/src/plugins/cppeditor/cppquickfix.cpp
@@ -1257,11 +1257,13 @@ public:
                     Overview prettyPrint;
                     for (unsigned i = 0; i < e->memberCount(); ++i) {
                         if (Declaration *decl = e->memberAt(i)->asDeclaration()) {
-                            values << prettyPrint(decl->name());
+                            values << prettyPrint(LookupContext::fullyQualifiedName(decl));
                         }
                     }
                     // Get the used values
-                    CaseStatementCollector caseValues(document()->translationUnit());
+                    Block *block = switchStatement->symbol;
+                    CaseStatementCollector caseValues(document(), snapshot(),
+                        document()->scopeAt(block->line(), block->column()));
                     QStringList usedValues = caseValues(switchStatement);
                     // save the values that would be added
                     foreach (const QString &usedValue, usedValues)
@@ -1318,7 +1320,15 @@ protected:
     class CaseStatementCollector : public ASTVisitor
     {
     public:
-        CaseStatementCollector(TranslationUnit *unit) : ASTVisitor(unit) {}
+        CaseStatementCollector(Document::Ptr document, const Snapshot &snapshot,
+                               Scope *scope)
+            : ASTVisitor(document->translationUnit()),
+            document(document),
+            scope(scope)
+        {
+            typeOfExpression.init(document, snapshot);
+        }
+
         QStringList operator ()(AST *ast)
         {
             values.clear();
@@ -1330,9 +1340,14 @@ protected:
         bool preVisit(AST *ast) {
             if (CaseStatementAST *cs = ast->asCaseStatement()) {
                 foundCaseStatementLevel = true;
-                if (SimpleNameAST *sm = cs->expression->asSimpleName()) {
-                    Overview prettyPrint;
-                    values << prettyPrint(sm->name);
+                ExpressionAST *expression = cs->expression->asSimpleName();
+                if (!expression)
+                    expression = cs->expression->asQualifiedName();
+                if (expression) {
+                    LookupItem item = typeOfExpression(expression,
+                                                       document,
+                                                       scope).first();
+                    values << prettyPrint(LookupContext::fullyQualifiedName(item.declaration()));
                 }
                 return true;
             } else if (foundCaseStatementLevel) {
@@ -1341,8 +1356,12 @@ protected:
             return true;
         }
 
+        Overview prettyPrint;
         bool foundCaseStatementLevel;
         QStringList values;
+        TypeOfExpression typeOfExpression;
+        Document::Ptr document;
+        Scope *scope;
     };
 
 protected:
diff --git a/tests/manual/cppquickfix/completeswitchcasestatement.cpp b/tests/manual/cppquickfix/completeswitchcasestatement.cpp
index 2ddf307315a..edc4b087282 100644
--- a/tests/manual/cppquickfix/completeswitchcasestatement.cpp
+++ b/tests/manual/cppquickfix/completeswitchcasestatement.cpp
@@ -1,3 +1,17 @@
+namespace Foo {
+enum Orientation {
+    Vertical,
+    Horizontal
+};
+}
+
+class Bar {
+    enum AnEnum {
+        AValue,
+        AnotherValue
+    };
+};
+
 enum Types {
     TypeA,
     TypeC,
@@ -6,6 +20,8 @@ enum Types {
     TypeE = TypeD
 };
 
+using namespace Foo;
+
 int main()
 {
     int j;
@@ -44,6 +60,20 @@ int main()
     case TypeA:;
     }
 
+    // Namespaces
+    Foo::Orientation o;
+    switch (o) {
+    case Vertical:
+        break;
+    }
+
+    // Class members
+    Bar::AnEnum a;
+    switch (a) {
+    case Bar::AnotherValue:
+        break;
+    }
+
     // Not a named type
     switch (i) {
     case bla:
-- 
GitLab