gem-graph-client/libide/code/ide-symbol-resolver.c

362 lines
14 KiB
C

/* ide-symbol-resolver.c
*
* Copyright 2015-2019 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#define G_LOG_DOMAIN "ide-symbol-resolver"
#include "config.h"
#include <libide-core.h>
#include <libide-threading.h>
#include "ide-symbol-resolver.h"
G_DEFINE_INTERFACE (IdeSymbolResolver, ide_symbol_resolver, IDE_TYPE_OBJECT)
static void
ide_symbol_resolver_real_get_symbol_tree_async (IdeSymbolResolver *self,
GFile *file,
GBytes *contents,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(IdeTask) task = NULL;
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (G_IS_FILE (file));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_symbol_resolver_get_symbol_tree_async);
ide_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Symbol tree is not supported on this symbol resolver");
}
static IdeSymbolTree *
ide_symbol_resolver_real_get_symbol_tree_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (IDE_IS_TASK (result));
return ide_task_propagate_pointer (IDE_TASK (result), error);
}
static void
ide_symbol_resolver_real_find_references_async (IdeSymbolResolver *self,
IdeLocation *location,
const gchar *language_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (location != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
ide_task_report_new_error (self,
callback,
user_data,
ide_symbol_resolver_real_find_references_async,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Finding references is not supported for this language");
}
static GPtrArray *
ide_symbol_resolver_real_find_references_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (IDE_IS_TASK (result));
return ide_task_propagate_pointer (IDE_TASK (result), error);
}
static void
ide_symbol_resolver_real_find_nearest_scope_async (IdeSymbolResolver *self,
IdeLocation *location,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (location != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
ide_task_report_new_error (self,
callback,
user_data,
ide_symbol_resolver_real_find_nearest_scope_async,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Finding nearest scope is not supported for this language");
}
static IdeSymbol *
ide_symbol_resolver_real_find_nearest_scope_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_assert (IDE_IS_SYMBOL_RESOLVER (self));
g_assert (IDE_IS_TASK (result));
return ide_task_propagate_pointer (IDE_TASK (result), error);
}
static void
ide_symbol_resolver_default_init (IdeSymbolResolverInterface *iface)
{
iface->get_symbol_tree_async = ide_symbol_resolver_real_get_symbol_tree_async;
iface->get_symbol_tree_finish = ide_symbol_resolver_real_get_symbol_tree_finish;
iface->find_references_async = ide_symbol_resolver_real_find_references_async;
iface->find_references_finish = ide_symbol_resolver_real_find_references_finish;
iface->find_nearest_scope_async = ide_symbol_resolver_real_find_nearest_scope_async;
iface->find_nearest_scope_finish = ide_symbol_resolver_real_find_nearest_scope_finish;
}
/**
* ide_symbol_resolver_lookup_symbol_async:
* @self: An #IdeSymbolResolver.
* @location: An #IdeLocation.
* @cancellable: (allow-none): a #GCancellable or %NULL.
* @callback: A callback to execute upon completion.
* @user_data: user data for @callback.
*
* Asynchronously requests that @self determine the symbol existing at the source location
* denoted by @self. @callback should call ide_symbol_resolver_lookup_symbol_finish() to
* retrieve the result.
*
* Since: 3.32
*/
void
ide_symbol_resolver_lookup_symbol_async (IdeSymbolResolver *self,
IdeLocation *location,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
g_return_if_fail (location != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->lookup_symbol_async (self, location, cancellable, callback, user_data);
}
/**
* ide_symbol_resolver_lookup_symbol_finish:
* @self: An #IdeSymbolResolver.
* @result: a #GAsyncResult provided to the callback.
* @error: (out): A location for an @error or %NULL.
*
* Completes an asynchronous call to lookup a symbol using
* ide_symbol_resolver_lookup_symbol_async().
*
* Returns: (transfer full) (nullable): An #IdeSymbol if successful; otherwise %NULL.
*
* Since: 3.32
*/
IdeSymbol *
ide_symbol_resolver_lookup_symbol_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (IDE_IS_SYMBOL_RESOLVER (self), NULL);
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
return IDE_SYMBOL_RESOLVER_GET_IFACE (self)->lookup_symbol_finish (self, result, error);
}
/**
* ide_symbol_resolver_get_symbol_tree_async:
* @self: An #IdeSymbolResolver
* @file: a #GFile
* @contents: (nullable): a #GBytes or %NULL
* @cancellable: (allow-none): a #GCancellable or %NULL.
* @callback: (allow-none): a callback to execute upon completion
* @user_data: user data for @callback
*
* Asynchronously fetch an up to date symbol tree for @file.
*
* Since: 3.32
*/
void
ide_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver *self,
GFile *file,
GBytes *contents,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
g_return_if_fail (G_IS_FILE (file));
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->get_symbol_tree_async (self, file, contents, cancellable, callback, user_data);
}
/**
* ide_symbol_resolver_get_symbol_tree_finish:
*
* Completes an asynchronous request to get the symbol tree for the
* requested file.
*
* Returns: (nullable) (transfer full): An #IdeSymbolTree; otherwise
* %NULL and @error is set.
*
* Since: 3.32
*/
IdeSymbolTree *
ide_symbol_resolver_get_symbol_tree_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (IDE_IS_SYMBOL_RESOLVER (self), NULL);
g_return_val_if_fail (!result || G_IS_ASYNC_RESULT (result), NULL);
return IDE_SYMBOL_RESOLVER_GET_IFACE (self)->get_symbol_tree_finish (self, result, error);
}
void
ide_symbol_resolver_load (IdeSymbolResolver *self)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
if (IDE_SYMBOL_RESOLVER_GET_IFACE (self)->load)
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->load (self);
}
void
ide_symbol_resolver_unload (IdeSymbolResolver *self)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
if (IDE_SYMBOL_RESOLVER_GET_IFACE (self)->unload)
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->unload (self);
}
/**
* ide_symbol_resolver_find_references_async:
* @self: a #IdeSymbolResolver
* @location: an #IdeLocation
* @language_id: (nullable): a language identifier or %NULL
* @cancellable: (nullable): a #GCancellable or %NULL
* @callback: a callback to execute
* @user_data: user data for @callback
*
*/
void
ide_symbol_resolver_find_references_async (IdeSymbolResolver *self,
IdeLocation *location,
const gchar *language_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
g_return_if_fail (location != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->find_references_async (self, location, language_id, cancellable, callback, user_data);
}
/**
* ide_symbol_resolver_find_references_finish:
* @self: a #IdeSymbolResolver
* @result: a #GAsyncResult
* @error: a #GError or %NULL
*
* Completes an asynchronous request to ide_symbol_resolver_find_references_async().
*
* Returns: (transfer full) (element-type IdeRange): a #GPtrArray
* of #IdeRange if successful; otherwise %NULL and @error is set.
*
* Since: 3.32
*/
GPtrArray *
ide_symbol_resolver_find_references_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (IDE_IS_SYMBOL_RESOLVER (self), NULL);
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
return IDE_SYMBOL_RESOLVER_GET_IFACE (self)->find_references_finish (self, result, error);
}
/**
* ide_symbol_resolver_find_nearest_scope_async:
* @self: a #IdeSymbolResolver
* @location: an #IdeLocation
* @cancellable: (nullable): a #GCancellable or %NULL
* @callback: (scope async) (closure user_data): an async callback
* @user_data: user data for @callback
*
* This function asynchronously requests to locate the containing
* scope for a given source location.
*
* See ide_symbol_resolver_find_nearest_scope_finish() for how to
* complete the operation.
*
* Since: 3.32
*/
void
ide_symbol_resolver_find_nearest_scope_async (IdeSymbolResolver *self,
IdeLocation *location,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (IDE_IS_SYMBOL_RESOLVER (self));
g_return_if_fail (location != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
IDE_SYMBOL_RESOLVER_GET_IFACE (self)->find_nearest_scope_async (self, location, cancellable, callback, user_data);
}
/**
* ide_symbol_resolver_find_nearest_scope_finish:
* @self: a #IdeSymbolResolver
* @result: a #GAsyncResult
* @error: a location for a #GError or %NULL
*
* This function completes an asynchronous operation to locate the containing
* scope for a given source location.
*
* See ide_symbol_resolver_find_nearest_scope_async() for more information.
*
* Returns: (transfer full) (nullable): An #IdeSymbol or %NULL
*
* Since: 3.32
*/
IdeSymbol *
ide_symbol_resolver_find_nearest_scope_finish (IdeSymbolResolver *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (IDE_IS_SYMBOL_RESOLVER (self), NULL);
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
return IDE_SYMBOL_RESOLVER_GET_IFACE (self)->find_nearest_scope_finish (self, result, error);
}