1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 Copyright (C) 2009 Maxim Ermilov <zaspire@rambler.ru>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "local-symbol.h"
23 #include "std-symbol.h"
24 #include "import-symbol.h"
25 #include "database-symbol.h"
28 static void database_symbol_interface_init (IJsSymbolIface
*iface
);
29 static GList
* database_symbol_get_arg_list (IJsSymbol
*obj
);
30 static gint
database_symbol_get_base_type (IJsSymbol
*obj
);
31 static GList
* database_symbol_get_func_ret_type (IJsSymbol
*obj
);
32 static IJsSymbol
* database_symbol_get_member (IJsSymbol
*obj
, const gchar
* name
);
33 static const gchar
* database_symbol_get_name (IJsSymbol
*obj
);
34 static GList
* database_symbol_list_member (IJsSymbol
*obj
);
36 static IJsSymbol
* find (const gchar
* name
, IJsSymbol
*sym
);
38 typedef struct _DatabaseSymbolPrivate DatabaseSymbolPrivate
;
39 struct _DatabaseSymbolPrivate
46 #define DATABASE_SYMBOL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DATABASE_TYPE_SYMBOL, DatabaseSymbolPrivate))
48 G_DEFINE_TYPE_WITH_CODE (DatabaseSymbol
, database_symbol
, G_TYPE_OBJECT
,
49 G_IMPLEMENT_INTERFACE (IJS_TYPE_SYMBOL
,
50 database_symbol_interface_init
));
53 database_symbol_init (DatabaseSymbol
*object
)
55 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE(object
);
62 database_symbol_finalize (GObject
*object
)
64 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE(object
);
66 g_object_unref (priv
->local
);
67 g_object_unref (priv
->global
);
68 g_list_foreach (priv
->symbols
, (GFunc
)g_object_unref
, NULL
);
69 g_list_free (priv
->symbols
);
70 G_OBJECT_CLASS (database_symbol_parent_class
)->finalize (object
);
74 database_symbol_class_init (DatabaseSymbolClass
*klass
)
76 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
77 /* GObjectClass* parent_class = G_OBJECT_CLASS (klass);*/
79 g_type_class_add_private (klass
, sizeof (DatabaseSymbolPrivate
));
81 object_class
->finalize
= database_symbol_finalize
;
85 database_symbol_set_file (DatabaseSymbol
*object
, const gchar
* filename
)
88 g_assert (DATABASE_IS_SYMBOL (object
));
89 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (object
);
93 g_object_unref (priv
->local
);
96 priv
->local
= local_symbol_new (filename
);
97 missed
= local_symbol_get_missed_semicolons (priv
->local
);
98 highlight_lines (missed
);
102 database_symbol_new ()
104 DatabaseSymbol
* self
= DATABASE_SYMBOL (g_object_new (DATABASE_TYPE_SYMBOL
, NULL
));
105 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (self
);
107 priv
->global
= std_symbol_new ();
109 priv
->symbols
= g_list_append (NULL
, import_symbol_new ());
115 database_symbol_interface_init (IJsSymbolIface
*iface
)
117 iface
->get_arg_list
= database_symbol_get_arg_list
;
118 iface
->get_base_type
= database_symbol_get_base_type
;
119 iface
->get_func_ret_type
= database_symbol_get_func_ret_type
;
121 iface
->get_member
= database_symbol_get_member
;
122 iface
->get_name
= database_symbol_get_name
;
123 iface
->list_member
= database_symbol_list_member
;
127 database_symbol_get_arg_list (IJsSymbol
*obj
)
129 g_assert_not_reached ();
134 database_symbol_get_base_type (IJsSymbol
*obj
)
140 database_symbol_get_func_ret_type (IJsSymbol
*obj
)
142 g_assert_not_reached ();
147 database_symbol_get_member (IJsSymbol
*obj
, const gchar
* name
)
149 DatabaseSymbol
* self
= DATABASE_SYMBOL (obj
);
150 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (self
);
152 if (!name
|| strlen (name
) == 0)
154 g_object_ref (priv
->local
);
155 return IJS_SYMBOL (priv
->local
);
159 for (i
= priv
->symbols
; i
; i
= g_list_next (i
))
161 IJsSymbol
*t
= IJS_SYMBOL (i
->data
);
162 if (strncmp (name
, ijs_symbol_get_name (t
), strlen (ijs_symbol_get_name (t
))) != 0 )
164 if (strlen (name
+ strlen (ijs_symbol_get_name (t
))) == 0)
169 return find (name
+ strlen (ijs_symbol_get_name (t
)) + 1, t
);
172 IJsSymbol
*ret
= find (name
, IJS_SYMBOL (priv
->local
));
174 ret
= find (name
, IJS_SYMBOL (priv
->global
));
180 database_symbol_get_name (IJsSymbol
*obj
)
182 g_assert_not_reached ();
187 database_symbol_list_member (IJsSymbol
*obj
)
189 DatabaseSymbol
* self
= DATABASE_SYMBOL (obj
);
190 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (self
);
193 ret
= ijs_symbol_list_member (IJS_SYMBOL (priv
->global
));
195 ret
= g_list_concat (ret
, ijs_symbol_list_member (IJS_SYMBOL (priv
->local
)));
196 ret
= g_list_append (ret
, g_strdup ("imports"));
201 database_symbol_list_local_member (DatabaseSymbol
*object
, gint line
)
203 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (object
);
204 return local_symbol_list_member_with_line (priv
->local
, line
);
208 database_symbol_list_member_with_line (DatabaseSymbol
*object
, gint line
)
210 g_assert (DATABASE_IS_SYMBOL (object
));
211 DatabaseSymbolPrivate
*priv
= DATABASE_SYMBOL_PRIVATE (object
);
214 ret
= ijs_symbol_list_member (IJS_SYMBOL (priv
->global
));
216 ret
= g_list_concat (ret
, local_symbol_list_member_with_line (priv
->local
, line
));
217 ret
= g_list_append (ret
, g_strdup ("imports"));
222 find (const gchar
* name
, IJsSymbol
*sym
)
224 gchar
*vname
= NULL
, *left
= NULL
;
230 for (i
= 0; i
< strlen (name
); i
++)
234 vname
= g_strndup (name
, i
);
235 left
= g_strdup (name
+ i
+ 1);
239 vname
= g_strdup (name
);
240 if (strlen (vname
) == 0)
246 gboolean is_func_call
= *((vname
+ strlen (vname
)) - 1) == ')';
248 vname
[strlen (vname
) - 2] = '\0';
250 for (j
= ijs_symbol_list_member (sym
); j
; j
= g_list_next (j
))
252 gchar
*t
= (gchar
*)j
->data
;
254 if (strcmp (vname
, t
) != 0 )
259 return ijs_symbol_get_member (sym
, t
);
260 IJsSymbol
*tjs
= ijs_symbol_get_member (sym
, t
);
261 IJsSymbol
*ret
= find (left
, tjs
);
262 g_object_unref (tjs
);
267 IJsSymbol
*s
= ijs_symbol_get_member (sym
, t
);
270 if (ijs_symbol_get_base_type (s
) != BASE_FUNC
)
275 GList
* rets
= ijs_symbol_get_func_ret_type (s
);
282 IJsSymbol
*ret
= global_search (rets
->data
);
287 s
= find (left
, ret
);
288 g_object_unref (ret
);