[anjuta/cxxparser] cxxparser: started refactoring. test-simple-struct && test-cast-simple-struct already working
- From: Massimo Cora' <mcora src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta/cxxparser] cxxparser: started refactoring. test-simple-struct && test-cast-simple-struct already working
- Date: Sat, 1 Aug 2009 00:36:46 +0000 (UTC)
commit 9982e0d2abafec643ed4334385b5ad53597be291
Author: Massimo Corà <mcora src gnome org>
Date: Sat Aug 1 02:35:35 2009 +0200
cxxparser: started refactoring. test-simple-struct && test-cast-simple-struct already working
This is the good time. Modular code rulez.
A big bugged while loop as before was an hell condition. Now it's much better.
plugins/symbol-db/cxxparser/engine-parser-priv.h | 27 ++-
plugins/symbol-db/cxxparser/engine-parser.cpp | 319 +++++++++++++++++++++-
plugins/symbol-db/cxxparser/main.c | 6 +-
3 files changed, 339 insertions(+), 13 deletions(-)
---
diff --git a/plugins/symbol-db/cxxparser/engine-parser-priv.h b/plugins/symbol-db/cxxparser/engine-parser-priv.h
index 6ab07ef..0425a6f 100644
--- a/plugins/symbol-db/cxxparser/engine-parser-priv.h
+++ b/plugins/symbol-db/cxxparser/engine-parser-priv.h
@@ -47,15 +47,26 @@ public:
/* getter for the IAnjutaSymbolManager. */
SymbolDBEngine * getSymbolManager ();
+ SymbolDBEngineIterator * getCurrentScopeChainByFileLine (const char* full_file_path,
+ int linenum);
+
+ SymbolDBEngineIterator * getCurrentSearchableScope (string &type_name,
+ string &type_scope);
+
+ bool getTypeNameAndScopeByToken (ExpressionResult &result,
+ string &token,
+ string &op,
+ const string& full_file_path,
+ unsigned long linenum,
+ const string& above_text,
+ string &out_type_name, // out
+ string &out_type_scope); // out
+
// FIXME comments.
- bool
- processExpression(const string& stmt,
- const string& above_text,
- const string& full_file_path,
- unsigned long linenum,
- string &out_type_name,
- string &out_type_scope,
- string &out_oper);
+ SymbolDBEngineIterator * processExpression (const string& stmt,
+ const string& above_text,
+ const string& full_file_path,
+ unsigned long linenum);
void testParseExpression (const string &in);
diff --git a/plugins/symbol-db/cxxparser/engine-parser.cpp b/plugins/symbol-db/cxxparser/engine-parser.cpp
index 54ee9d2..11484c2 100644
--- a/plugins/symbol-db/cxxparser/engine-parser.cpp
+++ b/plugins/symbol-db/cxxparser/engine-parser.cpp
@@ -182,6 +182,284 @@ EngineParser::trim (string& str, string trimChars /* = "{};\r\n\t\v " */)
}
}
+/**
+ * Return NULL on global
+ */
+SymbolDBEngineIterator *
+EngineParser::getCurrentScopeChainByFileLine (const char* full_file_path,
+ int linenum)
+{
+ SymbolDBEngineIterator *iter =
+ symbol_db_engine_get_scope_chain_by_file_line (_dbe,
+ full_file_path, linenum, SYMINFO_SIMPLE);
+
+ cout << "checking for completion scope..";
+ /* it's a global one if it's NULL or if it has just only one element */
+ if (iter == NULL || symbol_db_engine_iterator_get_n_items (iter) <= 1)
+ {
+ cout << "...we've a global completion scope" << endl;
+ if (iter != NULL)
+ {
+ g_object_unref (iter);
+ }
+
+ iter = NULL;
+ }
+ else
+ {
+ // DEBUG PRINT
+ do
+ {
+ SymbolDBEngineIteratorNode *node =
+ SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
+ cout << "DEBUG: got completion scope name: " <<
+ symbol_db_engine_iterator_node_get_symbol_name (node) << endl;
+ } while (symbol_db_engine_iterator_move_next (iter) == TRUE);
+ }
+
+ return iter;
+}
+
+bool
+EngineParser::getTypeNameAndScopeByToken (ExpressionResult &result,
+ string &token,
+ string &op,
+ const string& full_file_path,
+ unsigned long linenum,
+ const string& above_text,
+ string &out_type_name,
+ string &out_type_scope)
+{
+ // no tokens before this, what we need to do now, is find the TagEntry
+ // that corresponds to the result
+ if (result.m_isaType)
+ {
+ cout << "*** Found a cast expression" << endl;
+ /*
+ * Handle type (usually when casting is found)
+ */
+ if (result.m_isPtr && op == ".")
+ {
+ cout << "Did you mean to use '->' instead of '.' ?" << endl;
+ return false;
+ }
+
+ if (!result.m_isPtr && op == "->")
+ {
+ cout << "Can not use '->' operator on a non pointer object" << endl;
+ return false;
+ }
+
+ out_type_scope = result.m_scope.empty() ? "" : result.m_scope.c_str();
+ out_type_name = result.m_name.c_str();
+ return true;
+ }
+ else if (result.m_isThis)
+ {
+ cout << "*** Found 'this'" << endl;
+
+ /*
+ * special handle for 'this' keyword
+ */
+ out_type_scope = result.m_scope.empty() ? "" : result.m_scope.c_str();
+ // FIXME
+// if (scope_name.empty ())
+// {
+// cout << "'this' can not be used in the global scope" << endl;
+// return false;
+// }
+
+ if (op == "::")
+ {
+ cout << "'this' can not be used with operator ::" << endl;
+ return false;
+ }
+
+ if (result.m_isPtr && op == ".")
+ {
+ cout << "Did you mean to use '->' instead of '.' ?" << endl;
+ return false;
+ }
+
+ if (!result.m_isPtr && op == "->")
+ {
+ cout << "Can not use '->' operator on a non pointer object" << endl;
+ return false;
+ }
+// FIXME
+// out_type_name = scope_name;
+ return true;
+ }
+ else
+ {
+ /*
+ * Found an identifier (can be a local variable, a global one etc)
+ */
+ cout << "*** Found an identifier or local variable..." << endl;
+
+
+ /* this can be NULL if the scope is global */
+// SymbolDBEngineIterator *scope_chain_iter =
+// getCurrentScopeChainByFileLine (full_file_path.c_str(), linenum);
+
+ /* optimize scope'll clear the scopes leaving the local variables */
+ string optimized_scope = optimizeScope(above_text);
+ cout << "here it is the optimized buffer scope " << optimized_scope << endl;
+
+ VariableList li;
+ std::map<std::string, std::string> ignoreTokens;
+ get_variables(optimized_scope, li, ignoreTokens, false);
+
+ /* here the trick is to start from the end of the found variables
+ * up to the begin. This because the local variable declaration should be found
+ * just above to the statement line
+ */
+ cout << "variables found are..." << endl;
+ for (VariableList::reverse_iterator iter = li.rbegin(); iter != li.rend(); iter++) {
+ Variable var = (*iter);
+ var.print ();
+
+ if (token == var.m_name)
+ {
+ cout << "wh0a! we found the variable type to parse... it's \"" <<
+ var.m_type << "\"" << endl;
+ out_type_name = var.m_type;
+ out_type_scope = var.m_typeScope;
+
+ return true;
+ }
+ }
+
+ /* if we reach this point it's likely that we missed the right var type */
+ cout << "## Wrong detection of the variable type" << endl;
+ }
+ return false;
+}
+
+SymbolDBEngineIterator *
+EngineParser::getCurrentSearchableScope (string &type_name, string &type_scope)
+{
+ // FIXME: case of more results now it's hardcoded to 1
+ SymbolDBEngineIterator *curr_searchable_scope =
+ symbol_db_engine_find_symbol_by_name_pattern_filtered (
+ _dbe, type_name.c_str (),
+ SYMTYPE_SCOPE_CONTAINER, TRUE,
+ SYMSEARCH_FILESCOPE_IGNORE, NULL, 1,
+ -1, (SymExtraInfo)(SYMINFO_SIMPLE | SYMINFO_KIND));
+
+ if (curr_searchable_scope != NULL)
+ {
+ SymbolDBEngineIteratorNode *node;
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (curr_searchable_scope);
+
+ cout << "Current Searchable Scope " <<
+ symbol_db_engine_iterator_node_get_symbol_name (node) <<
+ " and id "<< symbol_db_engine_iterator_node_get_symbol_id (node) <<
+ endl;
+
+ /* is it a typedef? In that case find the parent struct */
+ if (g_strcmp0 (symbol_db_engine_iterator_node_get_symbol_extra_string (node,
+ SYMINFO_KIND), "typedef") == 0)
+ {
+ cout << "it's a struct!" << endl;
+ int struct_id = symbol_db_engine_get_parent_scope_id_by_symbol_id (_dbe,
+ symbol_db_engine_iterator_node_get_symbol_id (node),
+ NULL);
+
+ g_object_unref (curr_searchable_scope);
+ curr_searchable_scope = symbol_db_engine_get_symbol_info_by_id (_dbe,
+ struct_id,
+ (SymExtraInfo)(SYMINFO_SIMPLE | SYMINFO_KIND));
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (curr_searchable_scope);
+ cout << "(NEW) Current Searchable Scope " <<
+ symbol_db_engine_iterator_node_get_symbol_name (node) <<
+ " and id "<< symbol_db_engine_iterator_node_get_symbol_id (node) <<
+ endl;
+ }
+ }
+ else
+ {
+ cout << "Current Searchable Scope NULL" << endl;
+ }
+
+ return curr_searchable_scope;
+}
+
+SymbolDBEngineIterator *
+EngineParser::processExpression(const string& stmt,
+ const string& above_text,
+ const string& full_file_path,
+ unsigned long linenum)
+{
+ ExpressionResult result;
+ string current_token;
+ string op;
+ string type_name;
+ string type_scope;
+
+ /* first token */
+ _tokenizer->setText (stmt.c_str ());
+
+ /* get the fist one */
+ nextToken (current_token, op);
+ trim (current_token);
+
+ cout << "--------\nFirst token \"" << current_token << "\" with op \"" << op
+ << "\"" << endl;
+
+ /* parse the current sub-expression of a statement and fill up
+ * ExpressionResult object
+ */
+ result = parseExpression (current_token);
+
+ /* fine. Get the type name and type scope given the above result for the first
+ * and most important token.
+ */
+ bool process_res = getTypeNameAndScopeByToken (result,
+ current_token,
+ op,
+ full_file_path,
+ linenum,
+ above_text,
+ type_name,
+ type_scope);
+
+ if (process_res == false)
+ {
+ cout << "Well, you haven't much luck, the first token failed and then " <<
+ "I cannot continue. " << endl;
+ return NULL;
+ }
+
+ cout << "Going to search for curr_searchable_scope with type_name " << type_name <<
+ " and type_scope " << type_scope << endl;
+
+ /* at this time we're enough ready to issue a first query to out db.
+ * We absolutely need to find the searchable object scope of the first result
+ * type. From this one we can iterate the tree of scopes and reach a result.
+ */
+ SymbolDBEngineIterator *curr_searchable_scope =
+ getCurrentSearchableScope (type_name, type_scope);
+
+ if (curr_searchable_scope == NULL)
+ {
+ cout << "curr_searchable_scope failed to process, check the problem please"
+ << endl;
+ return NULL;
+ }
+
+ /* fine. Have we more tokens left? */
+ while (nextToken (current_token, op))
+ {
+
+ }
+
+ return curr_searchable_scope;
+}
+
+#if 0
/* FIXME TODO: error processing. Find out a way to notify the caller of the occurred
* error. The "cout" method cannot be used
*/
@@ -484,7 +762,7 @@ EngineParser::processExpression(const string& stmt,
return evaluation_succeed;
}
-
+#endif
/// Return the visible scope until pchStopWord is encountered
string
@@ -624,6 +902,43 @@ SymbolDBEngineIterator *
engine_parser_process_expression (const char *stmt, const char * above_text,
const char * full_file_path, unsigned long linenum)
{
+ SymbolDBEngine * dbe = EngineParser::getInstance ()->getSymbolManager ();
+
+ SymbolDBEngineIterator *iter =
+ EngineParser::getInstance ()->processExpression (stmt,
+ above_text,
+ full_file_path,
+ linenum);
+
+ if (iter == NULL)
+ {
+ cout << "## No way. Expression not parsed" << endl;
+ return NULL;
+ }
+
+ SymbolDBEngineIteratorNode *node = SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
+
+ // print the scope members
+ SymbolDBEngineIterator * children =
+ symbol_db_engine_get_scope_members_by_symbol_id (dbe,
+ symbol_db_engine_iterator_node_get_symbol_id (node),
+ -1,
+ -1,
+ SYMINFO_SIMPLE);
+
+ if (children != NULL)
+ {
+ cout << "scope children are: " << endl;
+ do {
+ SymbolDBEngineIteratorNode *child =
+ SYMBOL_DB_ENGINE_ITERATOR_NODE (children);
+ cout << "SymbolDBEngine: Searched var got name: " <<
+ symbol_db_engine_iterator_node_get_symbol_name (child) << endl;
+ }while (symbol_db_engine_iterator_move_next (children) == TRUE);
+ }
+
+
+#if 0
string out_type_name;
string out_type_scope;
string out_oper;
@@ -673,7 +988,7 @@ engine_parser_process_expression (const char *stmt, const char * above_text,
}while (symbol_db_engine_iterator_move_next (children) == TRUE);
}
}
-
+#endif
// FIXME
return NULL;
}
diff --git a/plugins/symbol-db/cxxparser/main.c b/plugins/symbol-db/cxxparser/main.c
index 8cab016..2d0c907 100644
--- a/plugins/symbol-db/cxxparser/main.c
+++ b/plugins/symbol-db/cxxparser/main.c
@@ -63,7 +63,7 @@ on_test_complex_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
gchar *file_content;
g_file_get_contents (associated_source_file, &file_content, NULL, NULL);
- engine_parser_process_expression ("((foo*)var)->asd_struct->", file_content,
+ engine_parser_process_expression ("((_foo*)var)->asd_struct->", file_content,
associated_source_file, 18);
g_free (file_content);
@@ -84,7 +84,7 @@ on_test_cast_simple_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
gchar *file_content;
g_file_get_contents (associated_source_file, &file_content, NULL, NULL);
- engine_parser_process_expression ("((foo)var).", file_content,
+ engine_parser_process_expression ("((_foo)var).", file_content,
associated_source_file, 15);
g_free (file_content);
@@ -136,7 +136,7 @@ int main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/simple_c/test-simple-struct", test_simple_struct);
-// g_test_add_func ("/simple_c/test-cast-simple-struct", test_cast_simple_struct);
+ g_test_add_func ("/simple_c/test-cast-simple-struct", test_cast_simple_struct);
// g_test_add_func ("/complex_c/test-complex-struct", test_complex_struct);
g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]