class-gen: Use a simple hash table instead of NPWValue
[anjuta.git] / plugins / language-support-js / code-completion.c
blobbd6594e451754ee44c46a42201c75c179d5fe402
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
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
20 #include <libanjuta/anjuta-shell.h>
21 #include <libanjuta/anjuta-debug.h>
22 #include <libanjuta/interfaces/ianjuta-document-manager.h>
23 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
24 #include <ctype.h>
25 #include <glib.h>
27 #include "code-completion.h"
28 #include "database-symbol.h"
29 #include "plugin.h"
30 #include "util.h"
32 GList*
33 filter_list (GList *list, gchar *prefix)
35 GList *ret = NULL, *i;
36 for (i = list; i; i = g_list_next (i))
38 if (!i->data)
39 continue;
40 if (strncmp ((gchar*)i->data, prefix, strlen (prefix)) == 0)
42 ret = g_list_append (ret, i->data);
45 return ret;
48 gchar*
49 file_completion (IAnjutaEditor *editor, gint *cur_depth)
51 int i;
52 IAnjutaIterable *position = ianjuta_editor_get_position (IANJUTA_EDITOR (editor), NULL);
53 int line = ianjuta_editor_get_line_from_position (IANJUTA_EDITOR (editor), position, NULL);
54 gchar *text = ianjuta_editor_get_text (editor,
55 ianjuta_editor_get_start_position (editor, NULL),
56 ianjuta_editor_get_line_begin_position (editor, line, NULL),
57 NULL);
58 int k, j;
59 if (strncmp (text, "#!/", 3) == 0) // For Seed support (Remove "#!/usr/bin/env seed" )
60 strncpy (text, "//", 2);
61 for (j = 0, i = 0, k = strlen (text); i < k; i++)
63 if (text[i] == '{')
64 j++;
65 if (text[i] == '}')
66 j--;
67 if (j < 0)
68 return NULL;/*ERROR*/
70 gchar *tmp = g_new (gchar, j + 1);
71 for (i = 0; i < j; i++)
72 tmp[i] = '}';
73 tmp [j] = '\0';
74 tmp = g_strconcat (text, tmp, NULL);
75 g_free (text);
76 text = tmp;
77 gchar *tmp_file = tmpnam (NULL);
78 FILE *f1 = fopen (tmp_file, "w");
79 fprintf (f1, "%s", text);
80 fclose (f1);
81 return tmp_file;
84 gchar*
85 code_completion_get_str (IAnjutaEditor *editor, gboolean last_dot)
87 IAnjutaIterable *position = ianjuta_editor_get_position (IANJUTA_EDITOR (editor), NULL);
89 gchar *text = ianjuta_editor_get_text (editor,
90 ianjuta_editor_get_line_begin_position (editor, 1, NULL),
91 position, NULL);
93 if (code_is_in_comment_or_str (text, TRUE))
95 g_free (text);
96 return NULL;
99 gchar *i = strlen (text) - 1 + text;
100 gchar *k = i;
101 if (last_dot)
102 if (*i == '.')
104 *i = '\0';
105 i--;
107 enum zstate
109 IDENT,
110 BRACE,
111 AFTER_BRACE,
112 EXIT
113 } s;
114 for (s = IDENT; i != text; i--)
116 switch (s)
118 case IDENT:
119 if (*i == ')')
121 *k = *i;
122 k--;
123 s = BRACE;
124 continue;
126 if (!isalnum (*i) && *i != '.' && *i != '_')
128 s = EXIT;
129 break;
131 if (*i == ' ')
133 s = EXIT;
134 break;
136 *k = *i;
137 k--;
138 break;
139 case AFTER_BRACE:
140 if (*i == ' ' || *i == '\t' || *i == '\n')
142 break;
144 i++;
145 s = IDENT;
146 break;
147 case BRACE:
148 if (*i == '(')
150 *k = *i;
151 k--;
152 s = AFTER_BRACE;
154 break;
155 default:
156 g_assert_not_reached ();
158 if (s == EXIT)
159 break;
161 k++;
162 i = g_strdup (k);
163 g_free (text);
164 g_assert (i != NULL);
165 return i;
168 gchar*
169 code_completion_get_func_tooltip (JSLang *plugin, const gchar *var_name)
171 if (plugin->symbol == NULL)
172 plugin->symbol = database_symbol_new ();
173 if (plugin->symbol == NULL)
174 return NULL;
176 IJsSymbol *symbol= ijs_symbol_get_member (IJS_SYMBOL (plugin->symbol), var_name);
177 if (!symbol)
179 DEBUG_PRINT ("Can't find symbol %s", var_name);
180 return NULL;
183 GList *args = ijs_symbol_get_arg_list (symbol);
185 GList *i;
186 gchar *res = NULL;
187 for (i = args; i; i = g_list_next (i))
189 if (!res)
190 res = i->data;
191 else
193 gchar * t = g_strdup_printf ("%s, %s", res, (gchar*)i->data);
194 g_free (res);
195 res = t;
198 g_object_unref (symbol);
199 return res;
202 gboolean
203 code_completion_is_symbol_func (JSLang *plugin, const gchar *var_name)
205 if (plugin->symbol == NULL)
206 plugin->symbol = database_symbol_new ();
207 if (plugin->symbol == NULL)
208 return FALSE;
210 IJsSymbol *symbol= ijs_symbol_get_member (IJS_SYMBOL (plugin->symbol), var_name);
211 if (!symbol)
213 DEBUG_PRINT ("Can't find symbol %s", var_name);
214 return FALSE;
216 g_object_unref (symbol);
217 return ijs_symbol_get_base_type (symbol) == BASE_FUNC;
220 GList*
221 code_completion_get_list (JSLang *plugin, const gchar *tmp_file, const gchar *var_name, gint depth_level)
223 GList *suggestions = NULL;
224 if (plugin->symbol == NULL)
225 plugin->symbol = database_symbol_new ();
226 if (plugin->symbol == NULL)
227 return NULL;
228 database_symbol_set_file (plugin->symbol, tmp_file);
230 if (!var_name || strlen (var_name) == 0)
231 return database_symbol_list_member_with_line (plugin->symbol,
232 ianjuta_editor_get_lineno (IANJUTA_EDITOR (plugin->current_editor), NULL));
233 IJsSymbol *t = ijs_symbol_get_member (IJS_SYMBOL (plugin->symbol), var_name);//TODO:Corect
234 if (t)
236 suggestions = ijs_symbol_list_member (IJS_SYMBOL (t));
237 g_object_unref (t);
239 return suggestions;