namespaces

G. Jungman jungman at lanl.gov
Sun Sep 26 05:15:34 BST 1999


Hi Folks. I added rudimentary namespace support to the classparser
directory.
I have no idea if anybody is working on this, but it only took an hour,
and I
needed it since I can't live without namespaces. The patch file is
attached
(diffs from the beta3 sources).

What it does:
  - keeps track of namespace, including nesting
  - applies current namespace to create fully-qualified
    names for classes (i.e. foo::bar::MyClass)
  - so fully-qualified class names appear in the class viewer,
    and everything works as before
  - classes in the anonymous namespace have the filename
    prepended instead; this assumes translation unit = file,
    not a problem at the moment.

Obviously this is not a final solution. I did it partly to see how
hard it would be to get something working and to stimulate discussion
about how it should be done. Obviously classes need to be tracked
internally using their fully-qualified names to prevent ambiguity;
directly renaming the classes was the easiest way to do it. An option
could be added to strip away layers of namespace when the names are
displayed. People might also want to be able to browse the classes
by namespace.

Anyway, there you have it. If somebody is already working on
this, please let me know. I couldn't find anything on the mailing
list.

--
G. Jungman


-------------- next part --------------
diff -Naur classparser-OLD/ClassParser.cc classparser/ClassParser.cc
--- classparser-OLD/ClassParser.cc	Sat Sep 25 21:39:13 1999
+++ classparser/ClassParser.cc	Sat Sep 25 21:42:07 1999
@@ -276,6 +276,48 @@
     getNextLexem();
 }
 
+
+void CClassParser::parseNamespace()
+{
+  getNextLexem();
+
+  // cerr << "parsing namespace" << endl;
+  // cerr << "lexem = " << lexem << ":" << static_cast<char>(lexem) << endl;
+
+  if( lexem == '{' ) {
+    // anonymous namespace
+    // assume 1-1 correspondence between file name and translation unit
+    QString short_file_name(currentFile);
+    short_file_name.replace( QRegExp(".*/"), "");
+    QString trans_unit_ident("(");
+    trans_unit_ident += short_file_name;
+    trans_unit_ident += ")";
+    namespace_stack.push_back(trans_unit_ident);
+  }
+  else {
+    // extract name of namespace
+    CParsedLexem alex( lexem, getText() );
+    namespace_stack.push_back(alex.text);
+
+    // check that it is well-formed, moving to beginning of block
+    getNextLexem();
+    while(lexem != '{') {
+      debug("Bad namespace identifier.");
+      getNextLexem();
+    }
+  }
+
+  // skip over '{'
+  getNextLexem();
+
+  while(lexem != 0 && lexem != '}') {
+    parseTopLevelLexem();
+  }
+
+  namespace_stack.pop_back();
+}
+
+
 /*---------------------------------------- CClassParser::parseUnion()
  * parseUnion()
  *   Parse an union.
@@ -1088,9 +1130,20 @@
     getNextLexem();
   }
 
+  QString fully_qualified_name;
+
+  for( list<QString>::const_iterator i = namespace_stack.begin();
+       i != namespace_stack.end();
+       ++i
+      ) {
+    fully_qualified_name += *i;
+    fully_qualified_name += QString("::");
+  }
+
   // The classname is at the top of the stack.
   aLexem = lexemStack.pop();
-  aClass->setName( aLexem->text );
+  fully_qualified_name += aLexem->text;
+  aClass->setName( fully_qualified_name /* aLexem->text */);
   delete aLexem;
 
   // Check if this a implementation of a nested class.
@@ -1438,6 +1491,9 @@
 
   switch( lexem )
   {
+    case NAMESPACE:
+      parseNamespace();
+      break;
     case CPCLASS:
       aClass = parseClass();
       
diff -Naur classparser-OLD/ClassParser.h classparser/ClassParser.h
--- classparser-OLD/ClassParser.h	Sat Sep 25 21:39:13 1999
+++ classparser/ClassParser.h	Fri Sep 24 23:05:39 1999
@@ -18,6 +18,8 @@
 #ifndef _CLASSPARSER_H_INCLUDED
 #define _CLASSPARSER_H_INCLUDED
 
+#include <list>
+
 #include <qstring.h>
 #include <qlist.h>
 #include <qstack.h>
@@ -105,6 +107,9 @@
   /** Start of a declaration that has been pushed on the stack. */
   int declStart;
 
+  /** Stores the namespace stack. */
+  list<QString> namespace_stack;
+
 private: // Private methods
 
   /** Get the next lexem from the lexer. */
@@ -148,6 +153,9 @@
 
   /** Parse an union. */
   void parseUnion();
+
+  /** Parse a namespace. */
+  void parseNamespace();
 
   /** Skip a throw() statement. */
   void skipThrowStatement();
diff -Naur classparser-OLD/tokenizer.h classparser/tokenizer.h
--- classparser-OLD/tokenizer.h	Sat Sep 25 21:39:13 1999
+++ classparser/tokenizer.h	Fri Sep 24 22:17:30 1999
@@ -62,6 +62,7 @@
 #define CPTEMPLATE     279
 #define NUM            280
 #define CPTHROW        281
+#define NAMESPACE      282
 
 typedef const char * YYSTYPE;
 
diff -Naur classparser-OLD/tokenizer.l classparser/tokenizer.l
--- classparser-OLD/tokenizer.l	Sat Sep 25 21:39:13 1999
+++ classparser/tokenizer.l	Fri Sep 24 22:16:25 1999
@@ -85,6 +85,7 @@
 "operator"      {return CPOPERATOR;}
 "template"      {return CPTEMPLATE;}
 "throw"         {return CPTHROW;}
+"namespace"     {return NAMESPACE;}
 
     /*==============> Ignored stuff <==============*/
 "Q_EXPORT"       {}


More information about the KDevelop mailing list