1 /* gbp-codeui-buffer-addin.c
2  *
3  * Copyright 2018-2019 Christian Hergert <chergert@redhat.com>
4  *
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 3 of the License, or
8  * (at your option) any later version.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  */
20 
21 #define G_LOG_DOMAIN "gbp-codeui-buffer-addin"
22 
23 #include "config.h"
24 
25 #include <libide-code.h>
26 
27 #include "ide-diagnostics-manager-private.h"
28 
29 #include "gbp-codeui-buffer-addin.h"
30 
31 struct _GbpCodeuiBufferAddin
32 {
33   GObject    parent_instance;
34   IdeBuffer *buffer;
35   GFile     *file;
36 };
37 
38 static void
gbp_codeui_buffer_addin_queue_diagnose(GbpCodeuiBufferAddin * self,IdeBuffer * buffer)39 gbp_codeui_buffer_addin_queue_diagnose (GbpCodeuiBufferAddin *self,
40                                         IdeBuffer            *buffer)
41 {
42   g_autoptr(IdeContext) context = NULL;
43   IdeDiagnosticsManager *manager;
44   g_autoptr(GBytes) contents = NULL;
45   const gchar *lang_id;
46   GFile *file;
47 
48   g_assert (IDE_IS_MAIN_THREAD ());
49   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
50   g_assert (IDE_IS_BUFFER (buffer));
51 
52   context = ide_buffer_ref_context (buffer);
53   manager = ide_diagnostics_manager_from_context (context);
54   file = ide_buffer_get_file (buffer);
55   lang_id = ide_buffer_get_language_id (buffer);
56   contents = ide_buffer_dup_content (buffer);
57 
58   _ide_diagnostics_manager_file_changed (manager, file, contents, lang_id);
59 }
60 
61 static void
gbp_codeui_buffer_addin_change_settled(IdeBufferAddin * addin,IdeBuffer * buffer)62 gbp_codeui_buffer_addin_change_settled (IdeBufferAddin *addin,
63                                         IdeBuffer      *buffer)
64 {
65   GbpCodeuiBufferAddin *self = (GbpCodeuiBufferAddin *)addin;
66 
67   g_assert (IDE_IS_MAIN_THREAD ());
68   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
69   g_assert (IDE_IS_BUFFER (buffer));
70 
71   gbp_codeui_buffer_addin_queue_diagnose (self, buffer);
72 }
73 
74 static void
gbp_codeui_buffer_addin_file_loaded(IdeBufferAddin * addin,IdeBuffer * buffer,GFile * file)75 gbp_codeui_buffer_addin_file_loaded (IdeBufferAddin *addin,
76                                      IdeBuffer      *buffer,
77                                      GFile          *file)
78 {
79   GbpCodeuiBufferAddin *self = (GbpCodeuiBufferAddin *)addin;
80   g_autoptr(IdeContext) context = NULL;
81   IdeDiagnosticsManager *manager;
82   const gchar *lang_id;
83 
84   g_assert (IDE_IS_MAIN_THREAD ());
85   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
86   g_assert (IDE_IS_BUFFER (buffer));
87   g_assert (G_IS_FILE (file));
88 
89   g_set_object (&self->file, file);
90 
91   context = ide_buffer_ref_context (buffer);
92   manager = ide_diagnostics_manager_from_context (context);
93   lang_id = ide_buffer_get_language_id (buffer);
94 
95   _ide_diagnostics_manager_file_opened (manager, file, lang_id);
96 }
97 
98 static void
gbp_codeui_buffer_addin_file_saved(IdeBufferAddin * addin,IdeBuffer * buffer,GFile * file)99 gbp_codeui_buffer_addin_file_saved (IdeBufferAddin *addin,
100                                     IdeBuffer      *buffer,
101                                     GFile          *file)
102 {
103   GbpCodeuiBufferAddin *self = (GbpCodeuiBufferAddin *)addin;
104 
105   g_assert (IDE_IS_MAIN_THREAD ());
106   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
107   g_assert (IDE_IS_BUFFER (buffer));
108   g_assert (G_IS_FILE (file));
109 
110   g_set_object (&self->file, file);
111 
112   gbp_codeui_buffer_addin_queue_diagnose (self, buffer);
113 }
114 
115 static void
gbp_codeui_buffer_addin_changed_cb(GbpCodeuiBufferAddin * self,IdeDiagnosticsManager * manager)116 gbp_codeui_buffer_addin_changed_cb (GbpCodeuiBufferAddin  *self,
117                                     IdeDiagnosticsManager *manager)
118 {
119   g_assert (IDE_IS_MAIN_THREAD ());
120   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
121   g_assert (IDE_IS_DIAGNOSTICS_MANAGER (manager));
122 
123   if (self->file != NULL)
124     {
125       g_autoptr(IdeDiagnostics) diagnostics = NULL;
126 
127       diagnostics = ide_diagnostics_manager_get_diagnostics_for_file (manager, self->file);
128       ide_buffer_set_diagnostics (self->buffer, diagnostics);
129     }
130 }
131 
132 static void
gbp_codeui_buffer_addin_language_set(IdeBufferAddin * addin,IdeBuffer * buffer,const gchar * language_id)133 gbp_codeui_buffer_addin_language_set (IdeBufferAddin *addin,
134                                       IdeBuffer      *buffer,
135                                       const gchar    *language_id)
136 {
137   g_autoptr(IdeContext) context = NULL;
138   IdeDiagnosticsManager *diagnostics_manager;
139   GFile *file;
140 
141   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (addin));
142   g_assert (IDE_IS_BUFFER (buffer));
143 
144   context = ide_buffer_ref_context (buffer);
145   file = ide_buffer_get_file (buffer);
146 
147   g_assert (IDE_IS_CONTEXT (context));
148   g_assert (file != NULL);
149   g_assert (G_IS_FILE (file));
150 
151   diagnostics_manager = ide_diagnostics_manager_from_context (context);
152   _ide_diagnostics_manager_language_changed (diagnostics_manager, file, language_id);
153 }
154 
155 static void
gbp_codeui_buffer_addin_load(IdeBufferAddin * addin,IdeBuffer * buffer)156 gbp_codeui_buffer_addin_load (IdeBufferAddin *addin,
157                               IdeBuffer      *buffer)
158 {
159   GbpCodeuiBufferAddin *self = (GbpCodeuiBufferAddin *)addin;
160   g_autoptr(IdeContext) context = NULL;
161   IdeDiagnosticsManager *manager;
162 
163   g_assert (IDE_IS_MAIN_THREAD ());
164   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
165   g_assert (IDE_IS_BUFFER (buffer));
166 
167   context = ide_buffer_ref_context (buffer);
168   manager = ide_diagnostics_manager_from_context (context);
169 
170   self->buffer = g_object_ref (buffer);
171 
172   g_signal_connect_object (manager,
173                            "changed",
174                            G_CALLBACK (gbp_codeui_buffer_addin_changed_cb),
175                            self,
176                            G_CONNECT_SWAPPED);
177 }
178 
179 static void
gbp_codeui_buffer_addin_unload(IdeBufferAddin * addin,IdeBuffer * buffer)180 gbp_codeui_buffer_addin_unload (IdeBufferAddin *addin,
181                                 IdeBuffer      *buffer)
182 {
183   GbpCodeuiBufferAddin *self = (GbpCodeuiBufferAddin *)addin;
184   g_autoptr(IdeContext) context = NULL;
185   IdeDiagnosticsManager *manager;
186   GFile *file;
187 
188   g_assert (IDE_IS_MAIN_THREAD ());
189   g_assert (GBP_IS_CODEUI_BUFFER_ADDIN (self));
190   g_assert (IDE_IS_BUFFER (buffer));
191 
192   context = ide_buffer_ref_context (buffer);
193   manager = ide_diagnostics_manager_from_context (context);
194   file = ide_buffer_get_file (buffer);
195 
196   g_signal_handlers_disconnect_by_func (manager,
197                                         G_CALLBACK (gbp_codeui_buffer_addin_changed_cb),
198                                         self);
199 
200   _ide_diagnostics_manager_file_closed (manager, file);
201 
202   g_clear_object (&self->file);
203 }
204 
205 static void
buffer_addin_iface_init(IdeBufferAddinInterface * iface)206 buffer_addin_iface_init (IdeBufferAddinInterface *iface)
207 {
208   iface->change_settled = gbp_codeui_buffer_addin_change_settled;
209   iface->file_saved = gbp_codeui_buffer_addin_file_saved;
210   iface->file_loaded = gbp_codeui_buffer_addin_file_loaded;
211   iface->language_set = gbp_codeui_buffer_addin_language_set;
212   iface->load = gbp_codeui_buffer_addin_load;
213   iface->unload = gbp_codeui_buffer_addin_unload;
214 }
215 
G_DEFINE_FINAL_TYPE_WITH_CODE(GbpCodeuiBufferAddin,gbp_codeui_buffer_addin,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (IDE_TYPE_BUFFER_ADDIN,buffer_addin_iface_init))216 G_DEFINE_FINAL_TYPE_WITH_CODE (GbpCodeuiBufferAddin, gbp_codeui_buffer_addin, G_TYPE_OBJECT,
217                          G_IMPLEMENT_INTERFACE (IDE_TYPE_BUFFER_ADDIN, buffer_addin_iface_init))
218 
219 static void
220 gbp_codeui_buffer_addin_class_init (GbpCodeuiBufferAddinClass *klass)
221 {
222 }
223 
224 static void
gbp_codeui_buffer_addin_init(GbpCodeuiBufferAddin * self)225 gbp_codeui_buffer_addin_init (GbpCodeuiBufferAddin *self)
226 {
227 }
228