mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
166 lines
6.3 KiB
C++
166 lines
6.3 KiB
C++
#include "UsedExtensionsFinder.h"
|
|
|
|
#include "GDCore/Events/Instruction.h"
|
|
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
|
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
|
#include "GDCore/Extensions/PlatformExtension.h"
|
|
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
|
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
|
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
|
#include "GDCore/Project/Behavior.h"
|
|
#include "GDCore/Project/Object.h"
|
|
#include "GDCore/Project/Project.h"
|
|
|
|
namespace gd {
|
|
|
|
const UsedExtensionsResult UsedExtensionsFinder::ScanProject(gd::Project& project) {
|
|
UsedExtensionsFinder worker(project);
|
|
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
|
|
gd::ProjectBrowserHelper::ExposeProjectEvents(project, worker);
|
|
return worker.result;
|
|
};
|
|
|
|
// Objects scanner
|
|
|
|
void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
|
|
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
|
project.GetCurrentPlatform(), object.GetType());
|
|
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
|
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
|
result.GetUsedIncludeFiles().insert(includeFile);
|
|
}
|
|
};
|
|
|
|
// Behaviors scanner
|
|
|
|
void UsedExtensionsFinder::DoVisitBehavior(gd::Behavior &behavior) {
|
|
auto metadata = gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
|
|
project.GetCurrentPlatform(), behavior.GetTypeName());
|
|
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
|
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
|
result.GetUsedIncludeFiles().insert(includeFile);
|
|
}
|
|
for (auto &&includeFile : metadata.GetMetadata().requiredFiles) {
|
|
result.GetUsedRequiredFiles().insert(includeFile);
|
|
}
|
|
};
|
|
|
|
// Instructions scanner
|
|
|
|
bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
|
bool isCondition) {
|
|
auto metadata =
|
|
isCondition ? gd::MetadataProvider::GetExtensionAndConditionMetadata(
|
|
project.GetCurrentPlatform(), instruction.GetType())
|
|
: gd::MetadataProvider::GetExtensionAndActionMetadata(
|
|
project.GetCurrentPlatform(), instruction.GetType());
|
|
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
|
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
|
result.GetUsedIncludeFiles().insert(includeFile);
|
|
}
|
|
|
|
gd::ParameterMetadataTools::IterateOverParameters(
|
|
instruction.GetParameters(),
|
|
metadata.GetMetadata().GetParameters(),
|
|
[this](const gd::ParameterMetadata& parameterMetadata,
|
|
const gd::Expression& parameterValue,
|
|
const gd::String& lastObjectName) {
|
|
const gd::String& parameterType = parameterMetadata.GetType();
|
|
|
|
if (gd::ParameterMetadata::IsExpression("string", parameterType)) {
|
|
rootType = "string";
|
|
parameterValue.GetRootNode()->Visit(*this);
|
|
} else if (gd::ParameterMetadata::IsExpression("number", parameterType)) {
|
|
rootType = "number";
|
|
parameterValue.GetRootNode()->Visit(*this);
|
|
} else if (gd::ParameterMetadata::IsExpression("variable", parameterType))
|
|
result.GetUsedExtensions().insert("BuiltinVariables");
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
// Expressions scanner
|
|
|
|
// Ignore litterals nodes
|
|
void UsedExtensionsFinder::OnVisitNumberNode(NumberNode& node){};
|
|
void UsedExtensionsFinder::OnVisitTextNode(TextNode& node){};
|
|
|
|
// Ignore nodes without valid extensions
|
|
void UsedExtensionsFinder::OnVisitEmptyNode(EmptyNode& node){};
|
|
void UsedExtensionsFinder::OnVisitObjectFunctionNameNode(
|
|
ObjectFunctionNameNode& node){};
|
|
|
|
// Visit sub-expressions
|
|
void UsedExtensionsFinder::OnVisitSubExpressionNode(SubExpressionNode& node) {
|
|
node.expression->Visit(*this);
|
|
};
|
|
|
|
void UsedExtensionsFinder::OnVisitOperatorNode(OperatorNode& node) {
|
|
node.leftHandSide->Visit(*this);
|
|
node.rightHandSide->Visit(*this);
|
|
};
|
|
|
|
void UsedExtensionsFinder::OnVisitUnaryOperatorNode(UnaryOperatorNode& node) {
|
|
node.factor->Visit(*this);
|
|
};
|
|
|
|
// Add variable extension and visit sub-expressions on variable nodes
|
|
void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
|
|
result.GetUsedExtensions().insert("BuiltinVariables");
|
|
if (node.child) node.child->Visit(*this);
|
|
};
|
|
|
|
void UsedExtensionsFinder::OnVisitVariableAccessorNode(
|
|
VariableAccessorNode& node) {
|
|
result.GetUsedExtensions().insert("BuiltinVariables");
|
|
if (node.child) node.child->Visit(*this);
|
|
};
|
|
|
|
void UsedExtensionsFinder::OnVisitVariableBracketAccessorNode(
|
|
VariableBracketAccessorNode& node) {
|
|
result.GetUsedExtensions().insert("BuiltinVariables");
|
|
node.expression->Visit(*this);
|
|
if (node.child) node.child->Visit(*this);
|
|
};
|
|
|
|
// Add extensions bound to Objects/Behaviors/Functions
|
|
void UsedExtensionsFinder::OnVisitIdentifierNode(IdentifierNode &node) {
|
|
auto type = gd::ExpressionTypeFinder::GetType(
|
|
project.GetCurrentPlatform(), GetGlobalObjectsContainer(),
|
|
GetObjectsContainer(), rootType, node);
|
|
if (gd::ParameterMetadata::IsObject(type)) {
|
|
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
|
project.GetCurrentPlatform(), node.identifierName);
|
|
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
|
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
|
result.GetUsedIncludeFiles().insert(includeFile);
|
|
}
|
|
}
|
|
};
|
|
|
|
void UsedExtensionsFinder::OnVisitFunctionCallNode(FunctionCallNode& node) {
|
|
// Extensions of non-free functions are already found when scanning objects.
|
|
if (!(node.objectName.empty() && node.behaviorName.empty())) return;
|
|
gd::ExtensionAndMetadata<gd::ExpressionMetadata> metadata;
|
|
|
|
// Try to find a free number expression
|
|
metadata = gd::MetadataProvider::GetExtensionAndExpressionMetadata(
|
|
project.GetCurrentPlatform(), node.functionName);
|
|
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata())) {
|
|
// Try to find a free str expression
|
|
metadata = gd::MetadataProvider::GetExtensionAndStrExpressionMetadata(
|
|
project.GetCurrentPlatform(), node.functionName);
|
|
// No valid expression found, return.
|
|
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata()))
|
|
return;
|
|
}
|
|
|
|
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
|
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
|
result.GetUsedIncludeFiles().insert(includeFile);
|
|
}
|
|
};
|
|
|
|
} // namespace gd
|