예제 #1
0
static void
ide_langserv_rename_provider_rename_cb (GObject      *object,
                                        GAsyncResult *result,
                                        gpointer      user_data)
{
  IdeLangservClient *client = (IdeLangservClient *)object;
  IdeLangservRenameProvider *self;
  g_autoptr(JsonNode) return_value = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GTask) task = user_data;
  g_autoptr(GPtrArray) ret = NULL;
  JsonObject *changes_by_uri = NULL;
  JsonObjectIter iter;
  const gchar *uri;
  IdeContext *context;
  JsonNode *changes;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_CLIENT (client));
  g_assert (G_IS_ASYNC_RESULT (result));
  g_assert (G_IS_TASK (task));
  self = g_task_get_source_object (task);
  g_assert (IDE_IS_LANGSERV_RENAME_PROVIDER (self));

  if (!ide_langserv_client_call_finish (client, result, &return_value, &error))
    {
      g_task_return_error (task, g_steal_pointer (&error));
      IDE_EXIT;
    }

  if (!JCON_EXTRACT (return_value, "changes", JCONE_OBJECT (changes_by_uri)))
    IDE_EXIT;

  context = ide_object_get_context (IDE_OBJECT (self));

  ret = g_ptr_array_new_with_free_func (g_object_unref);

  json_object_iter_init (&iter, changes_by_uri);

  while (json_object_iter_next (&iter, &uri, &changes))
    {
      g_autoptr(GFile) gfile = g_file_new_for_uri (uri);
      g_autoptr(IdeFile) ifile = ide_file_new (context, gfile);
      JsonArray *array;
      guint length;

      if (!JSON_NODE_HOLDS_ARRAY (changes))
        continue;

      array = json_node_get_array (changes);
      length = json_array_get_length (array);

      for (guint i = 0; i < length; i++)
        {
          JsonNode *change = json_array_get_element (array, i);
          g_autoptr(IdeSourceLocation) begin_location = NULL;
          g_autoptr(IdeSourceLocation) end_location = NULL;
          g_autoptr(IdeSourceRange) range = NULL;
          g_autoptr(IdeProjectEdit) edit = NULL;
          const gchar *new_text = NULL;
          gboolean success;
          struct {
            gint line;
            gint column;
          } begin, end;

          success = JCON_EXTRACT (change,
            "range", "{",
              "start", "{",
                "line", JCONE_INT (begin.line),
                "character", JCONE_INT (begin.column),
              "}",
              "end", "{",
                "line", JCONE_INT (end.line),
                "character", JCONE_INT (end.column),
              "}",
            "}",
            "newText", JCONE_STRING (new_text)
          );

          if (!success)
            continue;

          begin_location = ide_source_location_new (ifile, begin.line, begin.column, 0);
          end_location = ide_source_location_new (ifile, end.line, end.column, 0);
          range = ide_source_range_new (begin_location, end_location);

          edit = g_object_new (IDE_TYPE_PROJECT_EDIT,
                               "range", range,
                               "replacement", new_text,
                               NULL);

          g_ptr_array_add (ret, g_steal_pointer (&edit));
        }
    }

  g_task_return_pointer (task, g_steal_pointer (&ret), (GDestroyNotify)g_ptr_array_unref);

  IDE_EXIT;
}
예제 #2
0
static void
ide_langserv_symbol_resolver_find_references_cb (GObject      *object,
                                                 GAsyncResult *result,
                                                 gpointer      user_data)
{
  IdeLangservClient *client = (IdeLangservClient *)object;
  g_autoptr(GTask) task = user_data;
  g_autoptr(GVariant) reply = NULL;
  g_autoptr(GPtrArray) references = NULL;
  g_autoptr(GError) error = NULL;
  IdeLangservSymbolResolver *self;
  GVariant *locationv;
  GVariantIter iter;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_CLIENT (client));
  g_assert (G_IS_ASYNC_RESULT (result));
  g_assert (G_IS_TASK (task));

  self = g_task_get_source_object (task);

  if (!ide_langserv_client_call_finish (client, result, &reply, &error))
    {
      g_task_return_error (task, g_steal_pointer (&error));
      IDE_EXIT;
    }

  if (!g_variant_is_of_type (reply, G_VARIANT_TYPE ("av")))
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_INVALID_DATA,
                               "Invalid reply type from peer: %s",
                               g_variant_get_type_string (reply));
      IDE_EXIT;
    }

  references = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_source_range_unref);

  g_variant_iter_init (&iter, reply);

  while (g_variant_iter_loop (&iter, "v", &locationv))
    {
      g_autoptr(IdeSourceLocation) begin_loc = NULL;
      g_autoptr(IdeSourceLocation) end_loc = NULL;
      g_autoptr(IdeSourceRange) range = NULL;
      g_autoptr(IdeFile) ifile = NULL;
      const gchar *uri = NULL;
      GFile *gfile;
      gboolean success;
      struct {
        gint64 line;
        gint64 line_offset;
      } begin, end;

      success = JSONRPC_MESSAGE_PARSE (locationv,
        "uri", JSONRPC_MESSAGE_GET_STRING (&uri),
        "range", "{",
          "start", "{",
            "line", JSONRPC_MESSAGE_GET_INT64 (&begin.line),
            "character", JSONRPC_MESSAGE_GET_INT64 (&begin.line_offset),
          "}",
          "end", "{",
            "line", JSONRPC_MESSAGE_GET_INT64 (&end.line),
            "character", JSONRPC_MESSAGE_GET_INT64 (&end.line_offset),
          "}",
        "}"
      );

      if (!success)
        {
          g_task_return_new_error (task,
                                   G_IO_ERROR,
                                   G_IO_ERROR_INVALID_DATA,
                                   "Failed to parse location object");
          IDE_EXIT;
        }

      gfile = g_file_new_for_uri (uri);
      ifile = ide_file_new (ide_object_get_context (IDE_OBJECT (self)), gfile);

      begin_loc = ide_source_location_new (ifile, begin.line, begin.line_offset, 0);
      end_loc = ide_source_location_new (ifile, end.line, end.line_offset, 0);
      range = ide_source_range_new (begin_loc, end_loc);

      g_ptr_array_add (references, g_steal_pointer (&range));
    }

  g_task_return_pointer (task, g_steal_pointer (&references), (GDestroyNotify)g_ptr_array_unref);

  IDE_EXIT;
}