Files
GDevelop/Core/GDCore/IDE/WholeProjectRefactorer.h

815 lines
30 KiB
C++

/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include <memory>
#include "GDCore/String.h"
#include "GDCore/Project/Variable.h"
namespace gd {
class Platform;
class Project;
class Layout;
class Layer;
class Object;
class ObjectGroup;
class String;
class EventsFunctionsExtension;
class EventsFunction;
class ObjectsContainer;
class VariablesContainer;
class EventsBasedBehavior;
class EventsBasedObject;
class Behavior;
class UnfilledRequiredBehaviorPropertyProblem;
class ProjectBrowser;
class SerializerElement;
class ProjectScopedContainers;
class InitialInstancesContainer;
struct VariablesRenamingChangesetNode;
} // namespace gd
namespace gd {
struct VariablesRenamingChangesetNode {
std::unordered_map<gd::String, gd::String> oldToNewVariableNames;
std::unordered_map<gd::String, std::shared_ptr<gd::VariablesRenamingChangesetNode>>
modifiedVariables;
};
struct VariablesChangeset : VariablesRenamingChangesetNode {
std::unordered_set<gd::String> removedVariableNames;
/**
* No distinction is done between a change of the variable itself or its
* children. Ensuring that a child is actually the one with a type change
* would take more time than checking the instruction type is rightly set.
*/
std::unordered_set<gd::String> typeChangedVariableNames;
std::unordered_set<gd::String> valueChangedVariableNames;
std::unordered_set<gd::String> addedVariableNames;
bool HasRemovedVariables() { return !removedVariableNames.empty(); }
VariablesChangeset& ClearRemovedVariables() { removedVariableNames.clear(); return *this; }
};
/**
* \brief Tool functions to do refactoring on the whole project after
* changes like deletion or renaming of an object.
*
* \TODO Ideally ObjectOrGroupRenamedInScene, ObjectRemovedInScene,
* GlobalObjectOrGroupRenamed, GlobalObjectRemoved would be implemented
* using ExposeProjectEvents.
*/
class GD_CORE_API WholeProjectRefactorer {
public:
/**
* \brief Compute the changes made on the variables of a variable container.
*/
static VariablesChangeset ComputeChangesetForVariablesContainer(
const gd::SerializerElement &oldSerializedVariablesContainer,
const gd::VariablesContainer &newVariablesContainer);
/**
* \brief Refactor the project according to the changes (renaming or deletion)
* made to global or scene variables.
*/
static void ApplyRefactoringForVariablesContainer(
gd::Project &project, gd::VariablesContainer &variablesContainer,
const gd::VariablesChangeset &changeset,
const gd::SerializerElement &originalSerializedVariables);
/**
* \brief Refactor the project according to the changes (renaming or deletion)
* made to object variables.
*/
static void ApplyRefactoringForObjectVariablesContainer(
gd::Project &project, gd::VariablesContainer &objectVariablesContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::String &objectName, const gd::VariablesChangeset &changeset,
const gd::SerializerElement &originalSerializedVariables);
/**
* \brief Refactor the project according to the changes (renaming or deletion)
* made to variables of a group.
*/
static void ApplyRefactoringForGroupVariablesContainer(
gd::Project &project, gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::VariablesContainer &groupVariablesContainer,
const gd::ObjectGroup &objectGroup,
const gd::VariablesChangeset &changeset,
const gd::SerializerElement &originalSerializedVariables);
/**
* \brief Refactor the project **before** an events function extension is
* renamed.
*
* \warning Do the renaming of the specified extension after calling this.
* This is because the extension is expected to have its old name for the
* refactoring.
*/
static void RenameEventsFunctionsExtension(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& oldName,
const gd::String& newName);
/**
* \brief Refactor behavior events after the behavior has been placed in a new
* extension.
*/
static void UpdateExtensionNameInEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceExtensionName);
/**
* \brief Refactor object events after the object has been placed in a new
* extension.
*/
static void UpdateExtensionNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceExtensionName);
/**
* \brief Refactor the project **before** an events function is renamed.
*
* \warning Do the renaming of the specified function after calling this.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void RenameEventsFunction(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& oldFunctionName,
const gd::String& newFunctionName);
/**
* \brief Refactor the project **before** an events function of a behavior is
* renamed.
*
* \warning Do the renaming of the specified function after calling this.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void RenameBehaviorEventsFunction(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::String& oldFunctionName,
const gd::String& newFunctionName);
/**
* \brief Refactor the project **before** an events function of an object is
* renamed.
*
* \warning Do the renaming of the specified function after calling this.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void RenameObjectEventsFunction(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedObject& eventsBasedObject,
const gd::String& oldFunctionName,
const gd::String& newFunctionName);
/**
* \brief Refactor the function **before** a parameter is renamed.
*
* \warning Do the renaming of the specified parameter after calling this.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void
RenameParameter(gd::Project &project,
gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction &eventsFunction,
const gd::ObjectsContainer &parameterObjectsContainer,
const gd::String &oldParameterName,
const gd::String &newParameterName);
/**
* \brief Refactor the function **after** a parameter has changed of type.
*/
static void
ChangeParameterType(gd::Project &project,
gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction &eventsFunction,
const gd::ObjectsContainer &parameterObjectsContainer,
const gd::String &parameterName);
/**
* \brief Refactor the project **before** an events function parameter
* is moved.
*
* \warning Do the move of the specified function parameters after calling
* this. This is because the function is expected to be in its old state for
* the refactoring.
*/
static void MoveEventsFunctionParameter(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& functionName,
std::size_t oldIndex,
std::size_t newIndex);
/**
* \brief Refactor the project **before** the parameter of an events function
* of a behavior is moved.
*
* \warning Do the move of the specified function parameters after calling
* this. This is because the function is expected to be in its old state for
* the refactoring.
*/
static void MoveBehaviorEventsFunctionParameter(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::String& functionName,
std::size_t oldIndex,
std::size_t newIndex);
/**
* \brief Refactor the project **before** the parameter of an events function
* of an object is moved.
*
* \warning Do the move of the specified function parameters after calling
* this. This is because the function is expected to be in its old state for
* the refactoring.
*/
static void MoveObjectEventsFunctionParameter(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedObject& eventsBasedObject,
const gd::String& functionName,
std::size_t oldIndex,
std::size_t newIndex);
/**
* \brief Refactor the project **before** a property of a behavior is
* renamed.
*
* \warning Do the renaming of the specified property after calling this.
* This is because the property is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedBehaviorProperty(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::String& oldPropertyName,
const gd::String& newPropertyName);
/**
* \brief Refactor the project **before** a shared property of a behavior is
* renamed.
*
* \warning Do the renaming of the specified shared property after calling
* this. This is because the shared property is expected to have its old name
* for the refactoring.
*/
static void RenameEventsBasedBehaviorSharedProperty(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::String& oldPropertyName,
const gd::String& newPropertyName);
/**
* \brief Refactor the project **before** a property of an object is
* renamed.
*
* \warning Do the renaming of the specified property after calling this.
* This is because the property is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedObjectProperty(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedObject& eventsBasedObject,
const gd::String& oldPropertyName,
const gd::String& newPropertyName);
/**
* \brief Refactor the project **after** a property of a behavior has
* changed of type.
*/
static void ChangeEventsBasedBehaviorPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &propertyName);
/**
* \brief Refactor the project **after** a property of an object has
* changed of type.
*/
static void ChangeEventsBasedObjectPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &propertyName);
/**
* \brief Add a behavior to an object and add required behaviors if necessary
* to fill every behavior properties of the added behaviors.
*/
static void AddBehaviorAndRequiredBehaviors(gd::Project& project,
gd::Object& object,
const gd::String& behaviorType,
const gd::String& behaviorName);
/**
* \brief Add required behaviors if necessary to fill every behavior
* properties of the given behaviors.
*/
static void AddRequiredBehaviorsFor(gd::Project& project,
gd::Object& object,
const gd::String& behaviorName);
/**
* \brief Find every behavior of the object that needs the given behaviors
* directly or indirectly (because of "required behavior" properties).
*/
static std::vector<gd::String> FindDependentBehaviorNames(
const gd::Project& project,
const gd::Object& object,
const gd::String& behaviorName);
/**
* \brief Find the names of the behaviors with the specified type on the object.
*/
static std::vector<gd::String> GetBehaviorsWithType(const gd::Object& object,
const gd::String& type);
/**
* \brief Find in the project objects having behaviors with "behavior" properties that
* don't have a valid value (i.e: pointing to a non existing behavior, or of a wrong type).
*/
static std::vector<gd::UnfilledRequiredBehaviorPropertyProblem>
FindInvalidRequiredBehaviorProperties(const gd::Project& project);
/**
* \brief Fix in the project objects having behaviors with "behavior" properties that
* don't have a valid value (i.e: pointing to a non existing behavior, or of a wrong type),
* by setting a proper behavior, or adding missing behaviors to these objects.
*/
static bool
FixInvalidRequiredBehaviorProperties(gd::Project& project);
/**
* \brief Refactor the project **before** a behavior is renamed.
*
* \warning Do the renaming of the specified behavior after calling this.
* This is because the behavior is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedBehavior(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& oldBehaviorName,
const gd::String& newBehaviorName);
/**
* \brief Refactor events-based behavior events after the events-based
* behavior has been duplicated.
*/
static void UpdateBehaviorNameInEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceBehaviorName);
/**
* \brief Refactor the project **before** an object is renamed.
*
* \warning Do the renaming of the specified object after calling this.
* This is because the object is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedObject(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& oldObjectName,
const gd::String& newObjectName);
/**
* \brief Refactor events-based object events after the events-based object
* has been duplicated.
*/
static void UpdateObjectNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceObjectName);
/**
* \brief Refactor the project after a layout is renamed.
*/
static void RenameLayout(gd::Project &project, const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after an external layout is renamed.
*/
static void RenameExternalLayout(gd::Project &project,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after external events are renamed.
*/
static void RenameExternalEvents(gd::Project &project,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after a layer is renamed.
*/
static void RenameLayerInScene(gd::Project &project, gd::Layout &scene,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after a layer is renamed.
*/
static void RenameLayerInEventsBasedObject(
gd::Project &project,
gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject, const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after a layer effect is renamed.
*/
static void RenameLayerEffectInScene(gd::Project &project, gd::Layout &scene,
gd::Layer &layer,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after a layer effect is renamed.
*/
static void RenameLayerEffectInEventsBasedObject(
gd::Project &project,
gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject, gd::Layer &layer,
const gd::String &oldName, const gd::String &newName);
/**
* \brief Refactor the project after an object animation is renamed.
*/
static void RenameObjectAnimationInScene(gd::Project &project,
gd::Layout &scene,
gd::Object &object,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after an object animation is renamed.
*/
static void RenameObjectAnimationInEventsBasedObject(
gd::Project &project,
gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
const gd::String &oldName, const gd::String &newName);
/**
* \brief Refactor the project after an object point is renamed.
*/
static void RenameObjectPointInScene(gd::Project &project, gd::Layout &scene,
gd::Object &object,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after an object point is renamed.
*/
static void RenameObjectPointInEventsBasedObject(
gd::Project &project,
gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
const gd::String &oldName, const gd::String &newName);
/**
* \brief Refactor the project after an object effect is renamed.
*/
static void RenameObjectEffectInScene(gd::Project &project, gd::Layout &scene,
gd::Object &object,
const gd::String &oldName,
const gd::String &newName);
/**
* \brief Refactor the project after an object effect is renamed.
*/
static void RenameObjectEffectInEventsBasedObject(
gd::Project &project,
gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
const gd::String &oldName, const gd::String &newName);
/**
* \brief Refactor the project after an object is renamed in a layout
*
* This will update the layout, all external layouts associated with it
* and all external events associated with it.
*/
static void ObjectOrGroupRenamedInScene(gd::Project &project,
gd::Layout &scene,
const gd::String &oldName,
const gd::String &newName,
bool isObjectGroup);
/**
* \brief Refactor the project after an object is removed in a layout
*
* This will update the layout, all external layouts associated with it
* and all external events associated with it.
*/
static void ObjectRemovedInScene(gd::Project &project, gd::Layout &scene,
const gd::String &objectName);
/**
* \brief Refactor the project after behaviors are added to an object in a
* layout.
*
* This will update the layout, all external events associated with it.
* The refactor is actually applied to all objects because it allow to handle
* groups.
*/
static void BehaviorsAddedToObjectInScene(gd::Project &project,
gd::Layout &layout,
const gd::String &objectName);
/**
* \brief Refactor the project after an object is removed in an events-based
* object.
*
* This will update the events of the function and groups.
*/
static void ObjectRemovedInEventsBasedObject(
gd::Project& project,
gd::EventsBasedObject& eventsBasedObject,
const gd::String& objectName);
/**
* \brief Refactor the events function after an object or group is renamed
*
* This will update the events of the function and groups.
*/
static void ObjectOrGroupRenamedInEventsBasedObject(
gd::Project& project,
const gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsBasedObject& eventsBasedObject,
const gd::String& oldName,
const gd::String& newName,
bool isObjectGroup);
/**
* \brief Refactor the events function after an object or group is renamed
*
* This will update the events of the function and groups.
*/
static void ObjectOrGroupRenamedInEventsFunction(
gd::Project& project,
const gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction& eventsFunction,
const gd::ObjectsContainer &targetedObjectsContainer,
const gd::String& oldName,
const gd::String& newName,
bool isObjectGroup);
/**
* \brief Refactor the events function after an object or group is removed
*
* This will update the events of the function and groups.
*/
static void ObjectRemovedInEventsFunction(
gd::Project& project,
gd::EventsFunction& eventsFunction,
const gd::String& objectName);
/**
* \brief Refactor the project after a global object is renamed.
*
* This will update all the layouts, all external layouts associated with them
* and all external events used by the layouts.
*/
static void GlobalObjectOrGroupRenamed(gd::Project& project,
const gd::String& oldName,
const gd::String& newName,
bool isObjectGroup);
/**
* \brief Refactor the project after a global object is removed.
*
* This will update all the layouts, all external layouts associated with them
* and all external events used by the layouts.
*/
static void GlobalObjectRemoved(gd::Project& project,
const gd::String& objectName);
/**
* \brief Refactor the project after behaviors are added a global object.
*
* This will update all the layouts, all external events associated with them.
* The refactor is actually applied to all objects because it allow to handle
* groups.
*/
void BehaviorsAddedToGlobalObject(gd::Project &project,
const gd::String &objectName);
/**
* \brief Return the set of all the types of the objects that are using the
* given behavior.
*/
static std::set<gd::String> GetAllObjectTypesUsingEventsBasedBehavior(
const gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior);
/**
* \brief Ensure (adding if necessary) that the functions of the given
* behavior have the proper mandatory parameters (the "Object" and
* "Behavior").
*/
static void EnsureBehaviorEventsFunctionsProperParameters(
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior);
/**
* \brief Ensure (adding if necessary) that the functions of the given
* object have the proper mandatory parameters (the "Object").
*/
static void EnsureObjectEventsFunctionsProperParameters(
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::EventsBasedObject& eventsBasedObject);
/**
* \brief Remove all the instances from one layer.
*/
static void RemoveLayerInScene(gd::Project &project, gd::Layout &scene,
const gd::String &layerName);
/**
* \brief Move all the instances from one layer into another.
*/
static void MergeLayersInScene(gd::Project &project, gd::Layout &scene,
const gd::String &originLayerName,
const gd::String &targetLayerName);
/**
* \brief Remove all the instances from one layer.
*/
static void
RemoveLayerInEventsBasedObject(gd::EventsBasedObject &eventsBasedObject,
const gd::String &layerName);
/**
* \brief Move all the instances from one layer into another.
*/
static void
MergeLayersInEventsBasedObject(gd::EventsBasedObject &eventsBasedObject,
const gd::String &originLayerName,
const gd::String &targetLayerName);
/**
* \brief Replace the leaderboard ids in the whole project.
*/
static void
RenameLeaderboards(gd::Project &project,
const std::map<gd::String, gd::String> &leaderboardIdMap);
/**
* \brief Find all the leaderboard identifiers in the whole project.
*/
static std::set<gd::String> FindAllLeaderboardIds(gd::Project &project);
/**
* \brief Return the number of instances on the layer named \a layerName and
* all its associated layouts.
*/
static size_t GetLayoutAndExternalLayoutLayerInstancesCount(
gd::Project &project, gd::Layout &layout, const gd::String &layerName);
/**
* This ensures that the scenes had an instance of shared data for
* every behavior of every object that can be used on the scene
* (i.e. the objects of the scene and the global objects)
*
* Must be called when a behavior have been added/deleted
* from a global object or an object has been made global.
*/
static void UpdateBehaviorsSharedData(gd::Project &project);
virtual ~WholeProjectRefactorer(){};
private:
static void ObjectOrGroupRenamedInScene(gd::Project &project,
gd::Layout &scene,
const gd::ObjectsContainer &targetedObjectsContainer,
const gd::String &oldName,
const gd::String &newName,
bool isObjectGroup);
static std::vector<gd::String> GetAssociatedExternalLayouts(
gd::Project& project, gd::Layout& layout);
static std::vector<gd::String>
GetAssociatedExternalLayouts(gd::Project &project,
const gd::String &layoutName);
static std::vector<gd::String>
GetAssociatedExternalEvents(gd::Project &project,
const gd::String &layoutName);
static void DoRenameEventsFunction(gd::Project& project,
const gd::EventsFunction& eventsFunction,
const gd::String& oldFullType,
const gd::String& newFullType,
const gd::ProjectBrowser& projectBrowser);
static void DoRenameBehavior(gd::Project& project,
const gd::String& oldBehaviorType,
const gd::String& newBehaviorType,
const gd::ProjectBrowser& projectBrowser);
static void DoRenameObject(gd::Project& project,
const gd::String& oldObjectType,
const gd::String& newObjectType,
const gd::ProjectBrowser& projectBrowser);
/**
* \brief Refactor the project **before** an events function extension is
* renamed.
*
* \warning Do the renaming of the specified extension after calling this.
* This is because the extension is expected to have its old name for the
* refactoring.
*/
static void RenameEventsFunctionsExtension(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
const gd::String& oldName,
const gd::String& newName,
const gd::ProjectBrowser& projectBrowser);
/**
* \brief Refactor the project **before** a behavior is renamed.
*
* \warning Do the renaming of the specified behavior after calling this.
* This is because the behavior is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &oldBehaviorName,
const gd::String &newBehaviorName,
const gd::ProjectBrowser &projectBrowser);
/**
* \brief Refactor the project **before** an object is renamed.
*
* \warning Do the renaming of the specified object after calling this.
* This is because the object is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &oldObjectName, const gd::String &newObjectName,
const gd::ProjectBrowser &projectBrowser);
static void FindDependentBehaviorNames(
const gd::Project& project,
const gd::Object& object,
const gd::String& behaviorName,
std::unordered_set<gd::String>& dependentBehaviorNames);
static std::shared_ptr<VariablesRenamingChangesetNode>
ComputeChangesetForVariable(const gd::Variable &oldVariable,
const gd::Variable &newVariable);
static bool HasAnyVariableTypeChanged(const gd::Variable &oldVariable,
const gd::Variable &newVariable);
static const gd::String behaviorObjectParameterName;
static const gd::String parentObjectParameterName;
WholeProjectRefactorer(){};
};
} // namespace gd