From 33b19f0210cd6ab1504071912caee91a95515c7c Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Mon, 19 Jul 2010 20:12:16 +0200
Subject: [PATCH] Try to fix the type rewriter.

---
 src/libs/cplusplus/CppRewriter.cpp       | 104 ++++++++++++++++++-----
 src/libs/cplusplus/CppRewriter.h         |  59 +++++--------
 src/libs/cplusplus/ResolveExpression.cpp |   5 +-
 src/plugins/cppeditor/cppquickfix.cpp    |  13 ++-
 4 files changed, 121 insertions(+), 60 deletions(-)

diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp
index 26c11596ddb..9b28a8102c9 100644
--- a/src/libs/cplusplus/CppRewriter.cpp
+++ b/src/libs/cplusplus/CppRewriter.cpp
@@ -34,6 +34,7 @@
 #include <Literals.h>
 #include <Names.h>
 #include <Scope.h>
+#include <cplusplus/Overview.h>
 
 #include <QtCore/QVarLengthArray>
 #include <QtCore/QDebug>
@@ -120,7 +121,7 @@ public:
         {
             FullySpecifiedType ty = rewrite->env->apply(type->name(), rewrite);
             if (! ty->isUndefinedType())
-                temps.append(rewrite->rewriteType(ty));
+                temps.append(ty);
             else {
                 const Name *name = rewrite->rewriteName(type->name());
                 temps.append(control()->namedType(name));
@@ -286,39 +287,57 @@ public: // attributes
     RewriteName rewriteName;
 };
 
-ContextSubstitution::ContextSubstitution(const LookupContext &context, Scope *scope)
-    : _context(context), _scope(scope)
+SubstitutionEnvironment::SubstitutionEnvironment()
+    : _scope(0)
 {
 }
 
-ContextSubstitution::~ContextSubstitution()
+FullySpecifiedType SubstitutionEnvironment::apply(const Name *name, Rewrite *rewrite) const
 {
+    if (name) {
+        for (int index = _substs.size() - 1; index != -1; --index) {
+            const Substitution *subst = _substs.at(index);
+
+            FullySpecifiedType ty = subst->apply(name, rewrite);
+            if (! ty->isUndefinedType())
+                return ty;
+        }
+    }
+
+    return FullySpecifiedType();
 }
 
-FullySpecifiedType ContextSubstitution::apply(const Name *name, Rewrite *rewrite) const
+void SubstitutionEnvironment::enter(Substitution *subst)
 {
-    const QList<LookupItem> candidates = _context.lookup(name, _scope);
+    _substs.append(subst);
+}
 
-    foreach (const LookupItem &r, candidates) {
-        Symbol *s = r.declaration();
-        if (s->isDeclaration() && s->isTypedef()) {
-            qDebug() << "resolved typedef:" << s->fileName() << s->line() << s->column();
+void SubstitutionEnvironment::leave()
+{
+    _substs.removeLast();
+}
 
-            qDebug() << "scope is:" << r.scope()->owner()->fileName()
-                     << r.scope()->owner()->line()
-                     << r.scope()->owner()->column();
+Scope *SubstitutionEnvironment::scope() const
+{
+    return _scope;
+}
 
-            ContextSubstitution subst(_context, s->scope());
-            rewrite->env->enter(&subst);
-            FullySpecifiedType ty = rewrite->rewriteType(s->type());
-            rewrite->env->leave();
+Scope *SubstitutionEnvironment::switchScope(Scope *scope)
+{
+    Scope *previous = _scope;
+    _scope = scope;
+    return previous;
+}
 
-            return ty;
-        }
-    }
-    return FullySpecifiedType();
+const LookupContext &SubstitutionEnvironment::context() const
+{
+    return _context;
 }
 
+void SubstitutionEnvironment::setContext(const LookupContext &context)
+{
+    _context = context;
+}
 
 SubstitutionMap::SubstitutionMap()
 {
@@ -347,6 +366,49 @@ FullySpecifiedType SubstitutionMap::apply(const Name *name, Rewrite *) const
     return FullySpecifiedType();
 }
 
+
+UseQualifiedNames::UseQualifiedNames()
+{
+
+}
+
+UseQualifiedNames::~UseQualifiedNames()
+{
+
+}
+
+FullySpecifiedType UseQualifiedNames::apply(const Name *name, Rewrite *rewrite) const
+{
+    SubstitutionEnvironment *env = rewrite->env;
+    Scope *scope = env->scope();
+
+    if (! scope)
+        return FullySpecifiedType();
+
+    const LookupContext &context = env->context();
+    Control *control = rewrite->control;
+
+    const QList<LookupItem> results = context.lookup(name, scope);
+    foreach (const LookupItem &r, results) {
+        if (Symbol *d = r.declaration()) {
+            const Name *n = 0;
+            foreach (const Name *c,  LookupContext::fullyQualifiedName(d)) {
+                if (! n)
+                    n = c;
+                else
+                    n = control->qualifiedNameId(n, c);
+            }
+
+            return control->namedType(n);
+        }
+
+        return r.type();
+    }
+
+    return FullySpecifiedType();
+}
+
+
 FullySpecifiedType CPlusPlus::rewriteType(const FullySpecifiedType &type,
                                           SubstitutionEnvironment *env,
                                           Control *control)
diff --git a/src/libs/cplusplus/CppRewriter.h b/src/libs/cplusplus/CppRewriter.h
index 0e210611281..988b92f3a62 100644
--- a/src/libs/cplusplus/CppRewriter.h
+++ b/src/libs/cplusplus/CppRewriter.h
@@ -51,51 +51,27 @@ public:
 class CPLUSPLUS_EXPORT SubstitutionEnvironment
 {
     Q_DISABLE_COPY(SubstitutionEnvironment)
-    QList<Substitution *> substs;
 
 public:
-    SubstitutionEnvironment() {}
-
-    FullySpecifiedType apply(const Name *name, Rewrite *rewrite) const
-    {
-        if (name) {
-            for (int index = substs.size() - 1; index != -1; --index) {
-                const Substitution *subst = substs.at(index);
-
-                FullySpecifiedType ty = subst->apply(name, rewrite);
-                if (! ty->isUndefinedType())
-                    return ty;
-            }
-        }
-
-        return FullySpecifiedType();
-    }
-
-    void enter(Substitution *subst)
-    {
-        substs.append(subst);
-    }
-
-    void leave()
-    {
-        substs.removeLast();
-    }
-};
+    SubstitutionEnvironment();
 
-class CPLUSPLUS_EXPORT ContextSubstitution: public Substitution
-{
-public:
-    ContextSubstitution(const LookupContext &context, Scope *scope);
-    virtual ~ContextSubstitution();
+    FullySpecifiedType apply(const Name *name, Rewrite *rewrite) const;
 
-    virtual FullySpecifiedType apply(const Name *name, Rewrite *rewrite) const;
+    void enter(Substitution *subst);
+    void leave();
+
+    Scope *scope() const;
+    Scope *switchScope(Scope *scope);
+
+    const LookupContext &context() const;
+    void setContext(const LookupContext &context);
 
 private:
-    LookupContext _context;
+    QList<Substitution *> _substs;
     Scope *_scope;
+    LookupContext _context;
 };
 
-
 class CPLUSPLUS_EXPORT SubstitutionMap: public Substitution
 {
 public:
@@ -109,6 +85,17 @@ private:
     QList<QPair<const Name *, FullySpecifiedType> > _map;
 };
 
+class CPLUSPLUS_EXPORT UseQualifiedNames: public Substitution
+{
+public:
+    UseQualifiedNames();
+    virtual ~UseQualifiedNames();
+
+    virtual FullySpecifiedType apply(const Name *name, Rewrite *rewrite) const;
+};
+
+
+
 CPLUSPLUS_EXPORT FullySpecifiedType rewriteType(const FullySpecifiedType &type,
                                                 SubstitutionEnvironment *env,
                                                 Control *control);
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 651af198717..8bbdb8f05a0 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -568,9 +568,10 @@ QList<LookupItem> ResolveExpression::getMembers(ClassOrNamespace *binding, const
                 }
 
                 SubstitutionEnvironment env;
-                ContextSubstitution ctxSubst(_context, m.scope());
+                if (m.scope())
+                    env.switchScope(m.scope());
+                env.setContext(_context);
 
-                env.enter(&ctxSubst);
                 env.enter(&map);
                 FullySpecifiedType instantiatedTy = rewriteType(decl->type(), &env, _context.control().data());
 
diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp
index 0cf74978cbd..41589f97937 100644
--- a/src/plugins/cppeditor/cppquickfix.cpp
+++ b/src/plugins/cppeditor/cppquickfix.cpp
@@ -37,6 +37,7 @@
 #include <cplusplus/Overview.h>
 #include <cplusplus/TypeOfExpression.h>
 #include <cplusplus/DependencyTable.h>
+#include <cplusplus/CppRewriter.h>
 
 #include <TranslationUnit.h>
 #include <ASTVisitor.h>
@@ -1532,8 +1533,18 @@ public:
                                                           TypeOfExpression::Preprocess);
 
         if (! result.isEmpty()) {
+
+            SubstitutionEnvironment env;
+            env.setContext(context());
+            env.switchScope(result.first().scope());
+            UseQualifiedNames q;
+            env.enter(&q);
+
+            Control *control = context().control().data();
+            FullySpecifiedType tn = rewriteType(result.first().type(), &env, control);
+
             Overview oo;
-            QString ty = oo(result.first().type());
+            QString ty = oo(tn);
             if (! ty.isEmpty()) {
                 const QChar ch = ty.at(ty.size() - 1);
 
-- 
GitLab