Commit f05a109a authored by Christian Hergert's avatar Christian Hergert
Browse files

project: remove IdeProjectFile and IdeProjectFiles

This wasn't really being used and certainly wont be long-term. Lets drop
it now. This ports the few places that used that code to using the
ide_file_new_for_path() which can do caching and proper relative path
resolution without the IdeProjectFiles unpurgeable cache.
parent 67d09d48
......@@ -42,6 +42,7 @@
#include "diagnostics/ide-diagnostic.h"
#include "diagnostics/ide-source-location.h"
#include "diagnostics/ide-source-range.h"
#include "files/ide-file.h"
#include "plugins/ide-extension-util.h"
#include "projects/ide-project.h"
#include "runtimes/ide-runtime.h"
......
......@@ -23,7 +23,6 @@
#include "ide-context.h"
#include "directory/ide-directory-build-system.h"
#include "projects/ide-project-file.h"
#include "projects/ide-project-item.h"
#include "projects/ide-project.h"
......
......@@ -733,7 +733,15 @@ ide_file_new_for_path (IdeContext *context,
g_return_val_if_fail (!context || IDE_IS_CONTEXT (context), NULL);
g_return_val_if_fail (path != NULL, NULL);
file = g_file_new_for_path (path);
if (context != NULL && !g_path_is_absolute (path))
{
IdeVcs *vcs = ide_context_get_vcs (context);
GFile *workdir = ide_vcs_get_working_directory (vcs);
file = g_file_get_child (workdir, path);
}
else
file = g_file_new_for_path (path);
return ide_file_new (context, file);
}
......
......@@ -44,7 +44,6 @@
#include "doap/ide-doap.h"
#include "documentation/ide-documentation.h"
#include "plugins/ide-extension-util.h"
#include "projects/ide-project-files.h"
#include "projects/ide-project-item.h"
#include "projects/ide-project.h"
#include "projects/ide-recent-projects.h"
......@@ -2129,11 +2128,12 @@ restore_in_idle (gpointer user_data)
IdeContext *self;
GPtrArray *ar;
GFile *file;
IdeWorkbenchOpenFlags flags;
g_assert (G_IS_TASK (task));
self = g_task_get_source_object (task);
g_assert (IDE_IS_CONTEXT (self));
ar = g_task_get_task_data (task);
if (ar == NULL || ar->len == 0)
......@@ -2148,15 +2148,13 @@ restore_in_idle (gpointer user_data)
uf = g_ptr_array_index (ar, ar->len - 1);
file = ide_unsaved_file_get_file (uf);
ifile = ide_project_get_project_file (self->project, file);
ifile = ide_file_new (self, file);
g_ptr_array_remove_index (ar, ar->len - 1);
flags = IDE_WORKBENCH_OPEN_FLAGS_BACKGROUND;
ide_buffer_manager_load_file_async (self->buffer_manager,
ifile,
FALSE,
flags,
IDE_WORKBENCH_OPEN_FLAGS_BACKGROUND,
NULL,
g_task_get_cancellable (task),
ide_context_restore__load_file_cb,
......
......@@ -91,10 +91,6 @@ typedef struct _IdeProjectItem IdeProjectItem;
typedef struct _IdeProjectEdit IdeProjectEdit;
typedef struct _IdeProjectFile IdeProjectFile;
typedef struct _IdeProjectFiles IdeProjectFiles;
typedef struct _IdeRenameProvider IdeRenameProvider;
typedef struct _IdeRunner IdeRunner;
......
......@@ -127,8 +127,6 @@ G_BEGIN_DECLS
#include "preferences/ide-preferences-perspective.h"
#include "preferences/ide-preferences-window.h"
#include "projects/ide-project-edit.h"
#include "projects/ide-project-file.h"
#include "projects/ide-project-files.h"
#include "projects/ide-project-info.h"
#include "projects/ide-project-item.h"
#include "projects/ide-project.h"
......
/* ide-project-file.c
*
* Copyright © 2015 Christian Hergert <christian@hergert.me>
*
* 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/>.
*/
#include <glib/gi18n.h>
#include "projects/ide-project-file.h"
typedef struct
{
GFile *file;
GFileInfo *file_info;
gchar *path;
} IdeProjectFilePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeProjectFile, ide_project_file, IDE_TYPE_PROJECT_ITEM)
enum {
PROP_0,
PROP_FILE,
PROP_FILE_INFO,
PROP_IS_DIRECTORY,
PROP_NAME,
PROP_PATH,
LAST_PROP
};
static GParamSpec *properties [LAST_PROP];
gboolean
ide_project_file_get_is_directory (IdeProjectFile *self)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
g_return_val_if_fail (IDE_IS_PROJECT_FILE (self), FALSE);
if (priv->file_info)
return (g_file_info_get_file_type (priv->file_info) == G_FILE_TYPE_DIRECTORY);
return FALSE;
}
const gchar *
ide_project_file_get_path (IdeProjectFile *self)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
g_return_val_if_fail (IDE_IS_PROJECT_FILE (self), NULL);
return priv->path;
}
static void
ide_project_file_set_path (IdeProjectFile *self,
const gchar *path)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
g_return_if_fail (IDE_IS_PROJECT_FILE (self));
if (priv->path != path)
{
g_free (priv->path);
priv->path = g_strdup (path);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PATH]);
}
}
const gchar *
ide_project_file_get_name (IdeProjectFile *self)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
const gchar *name;
g_return_val_if_fail (IDE_IS_PROJECT_FILE (self), NULL);
name = g_file_info_get_display_name (priv->file_info);
if (name == NULL)
name = g_file_info_get_name (priv->file_info);
return name;
}
/**
* ide_project_file_get_file:
*
* Retrieves the underlying #GFile represented by @file.
*
* Returns: (transfer none): Retrieves the #GFile represented by @file.
*/
GFile *
ide_project_file_get_file (IdeProjectFile *file)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (file);
g_return_val_if_fail (IDE_IS_PROJECT_FILE (file), NULL);
return priv->file;
}
void
ide_project_file_set_file (IdeProjectFile *self,
GFile *file)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
g_return_if_fail (IDE_IS_PROJECT_FILE (self));
g_return_if_fail (!file || G_IS_FILE (file));
if (g_set_object (&priv->file, file))
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FILE]);
}
/**
* ide_project_file_get_file_info:
*
* Retrieves a #GFileInfo containing the basic information about @file. This
* includes the name, display name, and file type.
*
* Returns: (transfer none): a #GFileInfo
*/
GFileInfo *
ide_project_file_get_file_info (IdeProjectFile *file)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (file);
g_return_val_if_fail (IDE_IS_PROJECT_FILE (file), NULL);
return priv->file_info;
}
void
ide_project_file_set_file_info (IdeProjectFile *file,
GFileInfo *file_info)
{
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (file);
g_return_if_fail (IDE_IS_PROJECT_FILE (file));
g_return_if_fail (!file_info || G_IS_FILE_INFO (file_info));
if (g_set_object (&priv->file_info, file_info))
{
g_object_notify_by_pspec (G_OBJECT (file), properties [PROP_FILE_INFO]);
g_object_notify_by_pspec (G_OBJECT (file), properties [PROP_NAME]);
}
}
static void
ide_project_file_finalize (GObject *object)
{
IdeProjectFile *self = (IdeProjectFile *)object;
IdeProjectFilePrivate *priv = ide_project_file_get_instance_private (self);
g_clear_pointer (&priv->path, g_free);
g_clear_object (&priv->file);
g_clear_object (&priv->file_info);
G_OBJECT_CLASS (ide_project_file_parent_class)->finalize (object);
}
static void
ide_project_file_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
IdeProjectFile *self = IDE_PROJECT_FILE (object);
switch (prop_id)
{
case PROP_FILE:
g_value_set_object (value, ide_project_file_get_file (self));
break;
case PROP_FILE_INFO:
g_value_set_object (value, ide_project_file_get_file_info (self));
break;
case PROP_IS_DIRECTORY:
g_value_set_boolean (value, ide_project_file_get_is_directory (self));
break;
case PROP_NAME:
g_value_set_string (value, ide_project_file_get_name (self));
break;
case PROP_PATH:
g_value_set_string (value, ide_project_file_get_path (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
ide_project_file_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
IdeProjectFile *self = IDE_PROJECT_FILE (object);
switch (prop_id)
{
case PROP_FILE:
ide_project_file_set_file (self, g_value_get_object (value));
break;
case PROP_FILE_INFO:
ide_project_file_set_file_info (self, g_value_get_object (value));
break;
case PROP_PATH:
ide_project_file_set_path (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
ide_project_file_class_init (IdeProjectFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = ide_project_file_finalize;
object_class->get_property = ide_project_file_get_property;
object_class->set_property = ide_project_file_set_property;
properties [PROP_FILE] =
g_param_spec_object ("file",
"File",
"A GFile to the underlying file.",
G_TYPE_FILE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_FILE_INFO] =
g_param_spec_object ("file-info",
"File Info",
"The file information for the project file.",
G_TYPE_FILE_INFO,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_IS_DIRECTORY] =
g_param_spec_boolean ("is-directory",
"Is Directory",
"Is Directory",
FALSE,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties [PROP_NAME] =
g_param_spec_string ("name",
"Name",
"The short name of the file.",
NULL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties [PROP_PATH] =
g_param_spec_string ("path",
"Path",
"The path for the file within the project tree.",
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
static void
ide_project_file_init (IdeProjectFile *self)
{
}
/* ide-project-file.h
*
* Copyright © 2015 Christian Hergert <christian@hergert.me>
*
* 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/>.
*/
#pragma once
#include <gio/gio.h>
#include "ide-version-macros.h"
#include "files/ide-file.h"
#include "projects/ide-project-item.h"
G_BEGIN_DECLS
#define IDE_TYPE_PROJECT_FILE (ide_project_file_get_type())
G_DECLARE_DERIVABLE_TYPE (IdeProjectFile, ide_project_file, IDE, PROJECT_FILE, IdeProjectItem)
struct _IdeProjectFileClass
{
IdeProjectItemClass parent;
};
IDE_AVAILABLE_IN_ALL
GFile *ide_project_file_get_file (IdeProjectFile *self);
IDE_AVAILABLE_IN_ALL
GFileInfo *ide_project_file_get_file_info (IdeProjectFile *self);
IDE_AVAILABLE_IN_ALL
const gchar *ide_project_file_get_name (IdeProjectFile *self);
IDE_AVAILABLE_IN_ALL
const gchar *ide_project_file_get_path (IdeProjectFile *self);
IDE_AVAILABLE_IN_ALL
gboolean ide_project_file_get_is_directory (IdeProjectFile *self);
G_END_DECLS
/* ide-project-files.c
*
* Copyright © 2015 Christian Hergert <christian@hergert.me>
*
* 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/>.
*/
#define G_LOG_DOMAIN "ide-project-files"
#include "ide-context.h"
#include "projects/ide-project-file.h"
#include "projects/ide-project-files.h"
#include "vcs/ide-vcs.h"
typedef struct
{
GHashTable *files_by_path;
} IdeProjectFilesPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeProjectFiles, ide_project_files,
IDE_TYPE_PROJECT_ITEM)
static void
ide_project_files_dispose (GObject *object)
{
IdeProjectFiles *self = (IdeProjectFiles *)object;
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
g_clear_pointer (&priv->files_by_path, g_hash_table_unref);
G_OBJECT_CLASS (ide_project_files_parent_class)->dispose (object);
}
static void
ide_project_files_class_init (IdeProjectFilesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = ide_project_files_dispose;
}
static void
ide_project_files_init (IdeProjectFiles *self)
{
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
priv->files_by_path = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
}
static IdeProjectItem *
ide_project_files_find_child (IdeProjectItem *item,
const gchar *child)
{
GSequence *children;
GSequenceIter *iter;
g_assert (IDE_IS_PROJECT_ITEM (item));
g_assert (child);
children = ide_project_item_get_children (item);
if (!children)
return NULL;
for (iter = g_sequence_get_begin_iter (children);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
IdeProjectItem *current_item = g_sequence_get (iter);
if (IDE_IS_PROJECT_FILE (current_item))
{
IdeProjectFile *file;
const gchar *name;
file = IDE_PROJECT_FILE (current_item);
name = ide_project_file_get_name (file);
if (g_strcmp0 (name, child) == 0)
return current_item;
}
}
return NULL;
}
/**
* ide_project_files_find_file:
* @self: (in): an #IdeProjectFiles.
* @file: a #GFile.
*
* Tries to locate an #IdeProjectFile matching the given file.
* If @file is the working directory, @self is returned.
*
* Returns: (transfer none) (nullable): An #IdeProjectItem or %NULL.
*/
IdeProjectItem *
ide_project_files_find_file (IdeProjectFiles *self,
GFile *file)
{
IdeProjectItem *item;
IdeContext *context;
IdeVcs *vcs;
GFile *workdir;
gchar **parts;
gchar *path;
gsize i;
g_return_val_if_fail (IDE_IS_PROJECT_FILES (self), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
item = IDE_PROJECT_ITEM (self);
context = ide_object_get_context (IDE_OBJECT (self));
vcs = ide_context_get_vcs (context);
workdir = ide_vcs_get_working_directory (vcs);
if (g_file_equal (workdir, file))
return IDE_PROJECT_ITEM (self);
path = g_file_get_relative_path (workdir, file);
if (path == NULL)
return NULL;
parts = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
for (i = 0; parts [i]; i++)
{
if (!(item = ide_project_files_find_child (item, parts [i])))
break;
}
g_strfreev (parts);
g_free (path);
return item;
}
/**
* ide_project_files_get_file_for_path:
*
* Retrieves an #IdeFile for the path. If no such path exists within the
* project, %NULL is returned.
*
* Returns: (transfer full) (nullable): An #IdeFile or %NULL.
*/
IdeFile *
ide_project_files_get_file_for_path (IdeProjectFiles *self,
const gchar *path)
{
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
IdeProjectItem *item = (IdeProjectItem *)self;
IdeFile *file = NULL;
gchar **parts;
gsize i;
g_return_val_if_fail (IDE_IS_PROJECT_FILES (self), NULL);
if ((file = g_hash_table_lookup (priv->files_by_path, path)))
return g_object_ref (file);
parts = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
for (i = 0; item && parts [i]; i++)
item = ide_project_files_find_child (item, parts [i]);
if (item)
{
IdeContext *context;
const gchar *file_path;
GFile *gfile;