mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Fix missing export files for extensions (#4773)
This commit is contained in:
@@ -11,30 +11,36 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
std::set<gd::String> UsedExtensionsFinder::ScanProject(gd::Project& project) {
|
||||
const UsedExtensionsResult UsedExtensionsFinder::ScanProject(gd::Project& project) {
|
||||
UsedExtensionsFinder worker(project);
|
||||
gd::WholeProjectRefactorer::ExposeProjectObjects(project, worker);
|
||||
gd::WholeProjectRefactorer::ExposeProjectEvents(project, worker);
|
||||
return worker.usedExtensions;
|
||||
return worker.result;
|
||||
};
|
||||
|
||||
// Objects scanner
|
||||
|
||||
void UsedExtensionsFinder::DoVisitObject(gd::Object& object) {
|
||||
usedExtensions.insert(gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
||||
project.GetCurrentPlatform(), object.GetType())
|
||||
.GetExtension()
|
||||
.GetName());
|
||||
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) {
|
||||
usedExtensions.insert(
|
||||
gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
|
||||
project.GetCurrentPlatform(), behavior.GetTypeName())
|
||||
.GetExtension()
|
||||
.GetName());
|
||||
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
|
||||
@@ -46,7 +52,10 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
||||
project.GetCurrentPlatform(), instruction.GetType())
|
||||
: gd::MetadataProvider::GetExtensionAndActionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType());
|
||||
usedExtensions.insert(metadata.GetExtension().GetName());
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (auto expression : instruction.GetParameters()) {
|
||||
@@ -61,7 +70,7 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
||||
rootType = "number";
|
||||
expression.GetRootNode()->Visit(*this);
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", parameterType))
|
||||
usedExtensions.insert("BuiltinVariables");
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -93,31 +102,35 @@ void UsedExtensionsFinder::OnVisitUnaryOperatorNode(UnaryOperatorNode& node) {
|
||||
|
||||
// Add variable extension and visit sub-expressions on variable nodes
|
||||
void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
|
||||
usedExtensions.insert("BuiltinVariables");
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
if (node.child) node.child->Visit(*this);
|
||||
};
|
||||
|
||||
void UsedExtensionsFinder::OnVisitVariableAccessorNode(
|
||||
VariableAccessorNode& node) {
|
||||
usedExtensions.insert("BuiltinVariables");
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
if (node.child) node.child->Visit(*this);
|
||||
};
|
||||
|
||||
void UsedExtensionsFinder::OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) {
|
||||
usedExtensions.insert("BuiltinVariables");
|
||||
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);
|
||||
void UsedExtensionsFinder::OnVisitIdentifierNode(IdentifierNode &node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(
|
||||
project.GetCurrentPlatform(), GetGlobalObjectsContainer(),
|
||||
GetObjectsContainer(), rootType, node);
|
||||
if (gd::ParameterMetadata::IsObject(type)) {
|
||||
usedExtensions.insert(gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
||||
project.GetCurrentPlatform(), node.identifierName)
|
||||
.GetExtension()
|
||||
.GetName());
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -138,7 +151,10 @@ void UsedExtensionsFinder::OnVisitFunctionCallNode(FunctionCallNode& node) {
|
||||
return;
|
||||
}
|
||||
|
||||
usedExtensions.insert(metadata.GetExtension().GetName());
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -21,18 +21,62 @@ class Behavior;
|
||||
|
||||
namespace gd {
|
||||
|
||||
class GD_CORE_API UsedExtensionsResult {
|
||||
public:
|
||||
/**
|
||||
* The extensions used by the project (or part of it).
|
||||
*/
|
||||
const std::set<gd::String> &GetUsedExtensions() const {
|
||||
return usedExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The include files used at runtime by the project (or part of it).
|
||||
*/
|
||||
const std::set<gd::String> &GetUsedIncludeFiles() const {
|
||||
return usedIncludeFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The additional files required at runtime by the project (or part of it).
|
||||
*/
|
||||
const std::set<gd::String> &GetUsedRequiredFiles() const {
|
||||
return usedRequiredFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extensions used by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedExtensions() { return usedExtensions; }
|
||||
|
||||
/**
|
||||
* The include files used at runtime by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedIncludeFiles() { return usedIncludeFiles; }
|
||||
|
||||
/**
|
||||
* The additional files required at runtime by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedRequiredFiles() { return usedRequiredFiles; }
|
||||
|
||||
private:
|
||||
std::set<gd::String> usedExtensions;
|
||||
std::set<gd::String> usedIncludeFiles;
|
||||
std::set<gd::String> usedRequiredFiles;
|
||||
};
|
||||
|
||||
class GD_CORE_API UsedExtensionsFinder
|
||||
: public ArbitraryObjectsWorker,
|
||||
public ArbitraryEventsWorkerWithContext,
|
||||
public ExpressionParser2NodeWorker {
|
||||
public:
|
||||
static std::set<gd::String> ScanProject(gd::Project& project);
|
||||
static const UsedExtensionsResult ScanProject(gd::Project& project);
|
||||
|
||||
private:
|
||||
UsedExtensionsFinder(gd::Project& project_) : project(project_){};
|
||||
gd::Project& project;
|
||||
gd::String rootType;
|
||||
std::set<gd::String> usedExtensions;
|
||||
UsedExtensionsResult result;
|
||||
|
||||
// Object Visitor
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
|
@@ -32,6 +32,11 @@
|
||||
|
||||
namespace gdjs {
|
||||
|
||||
static void InsertUnique(std::vector<gd::String> &container, gd::String str) {
|
||||
if (std::find(container.begin(), container.end(), str) == container.end())
|
||||
container.push_back(str);
|
||||
}
|
||||
|
||||
Exporter::Exporter(gd::AbstractFileSystem &fileSystem, gd::String gdjsRoot_)
|
||||
: fs(fileSystem), gdjsRoot(gdjsRoot_) {
|
||||
SetCodeOutputDirectory(fs.GetTempDir() + "/GDTemporaries/JSCodeTemp");
|
||||
@@ -52,10 +57,11 @@ bool Exporter::ExportWholePixiProject(
|
||||
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
|
||||
gd::Project exportedProject = project;
|
||||
|
||||
auto usedExtensions = gd::UsedExtensionsFinder::ScanProject(project);
|
||||
auto usedExtensionsResult = gd::UsedExtensionsFinder::ScanProject(project);
|
||||
auto& usedExtensions = usedExtensionsResult.GetUsedExtensions();
|
||||
|
||||
auto exportProject = [this, &exportedProject, &exportOptions, &helper](
|
||||
gd::String exportDir) {
|
||||
auto exportProject = [this, &exportedProject, &exportOptions, &helper,
|
||||
&usedExtensionsResult](gd::String exportDir) {
|
||||
bool exportForCordova = exportOptions["exportForCordova"];
|
||||
bool exportForFacebookInstantGames =
|
||||
exportOptions["exportForFacebookInstantGames"];
|
||||
@@ -88,9 +94,14 @@ bool Exporter::ExportWholePixiProject(
|
||||
exportedProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for object and behaviors
|
||||
helper.ExportObjectAndBehaviorsIncludes(exportedProject, includesFiles);
|
||||
helper.ExportObjectAndBehaviorsRequiredFiles(exportedProject, resourcesFiles);
|
||||
// Export files for free function, object and behaviors
|
||||
for (const auto &includeFile : usedExtensionsResult.GetUsedIncludeFiles()) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
for (const auto &requiredFile :
|
||||
usedExtensionsResult.GetUsedRequiredFiles()) {
|
||||
InsertUnique(resourcesFiles, requiredFile);
|
||||
}
|
||||
|
||||
// Export effects (after engine libraries as they auto-register themselves
|
||||
// to the engine)
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDJS/Events/CodeGeneration/LayoutCodeGenerator.h"
|
||||
#include "GDJS/Extensions/JsPlatform.h"
|
||||
#include "GDCore/IDE/Events/UsedExtensionsFinder.h"
|
||||
#undef CopyFile // Disable an annoying macro
|
||||
|
||||
namespace {
|
||||
@@ -115,9 +116,15 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
immutableProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for object and behaviors
|
||||
ExportObjectAndBehaviorsIncludes(immutableProject, includesFiles);
|
||||
ExportObjectAndBehaviorsRequiredFiles(immutableProject, resourcesFiles);
|
||||
// Export files for free function, object and behaviors
|
||||
auto usedExtensionsResult =
|
||||
gd::UsedExtensionsFinder::ScanProject(exportedProject);
|
||||
for (const auto &includeFile : usedExtensionsResult.GetUsedIncludeFiles()) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
for (const auto &requiredFile : usedExtensionsResult.GetUsedRequiredFiles()) {
|
||||
InsertUnique(resourcesFiles, requiredFile);
|
||||
}
|
||||
|
||||
// Export effects (after engine libraries as they auto-register themselves to
|
||||
// the engine)
|
||||
@@ -797,98 +804,6 @@ bool ExporterHelper::ExportIncludesAndLibs(
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExporterHelper::ExportObjectAndBehaviorsIncludes(
|
||||
const gd::Project &project, std::vector<gd::String> &includesFiles) {
|
||||
auto addIncludeFiles = [&](const std::vector<gd::String> &newIncludeFiles) {
|
||||
for (const auto &includeFile : newIncludeFiles) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
};
|
||||
|
||||
auto addObjectIncludeFiles = [&](const gd::Object &object) {
|
||||
// Ensure needed files are included for the object type and its behaviors.
|
||||
const gd::ObjectMetadata &metadata =
|
||||
gd::MetadataProvider::GetObjectMetadata(JsPlatform::Get(),
|
||||
object.GetType());
|
||||
addIncludeFiles(metadata.includeFiles);
|
||||
|
||||
std::vector<gd::String> behaviors = object.GetAllBehaviorNames();
|
||||
for (std::size_t j = 0; j < behaviors.size(); ++j) {
|
||||
const gd::BehaviorMetadata &metadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(
|
||||
JsPlatform::Get(),
|
||||
object.GetBehavior(behaviors[j]).GetTypeName());
|
||||
addIncludeFiles(metadata.includeFiles);
|
||||
}
|
||||
};
|
||||
|
||||
auto addObjectsIncludeFiles =
|
||||
[&](const gd::ObjectsContainer &objectsContainer) {
|
||||
for (std::size_t i = 0; i < objectsContainer.GetObjectsCount(); ++i) {
|
||||
addObjectIncludeFiles(objectsContainer.GetObject(i));
|
||||
}
|
||||
};
|
||||
|
||||
// TODO UsedExtensionsFinder should be used instead to find the file to include.
|
||||
// The Exporter class already use it.
|
||||
addObjectsIncludeFiles(project);
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
const gd::Layout &layout = project.GetLayout(i);
|
||||
addObjectsIncludeFiles(layout);
|
||||
}
|
||||
|
||||
// Event based objects children
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount(); e++) {
|
||||
auto& eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
for (auto&& eventsBasedObjectUniquePtr :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto eventsBasedObject = eventsBasedObjectUniquePtr.get();
|
||||
|
||||
addObjectsIncludeFiles(*eventsBasedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExporterHelper::ExportObjectAndBehaviorsRequiredFiles(
|
||||
const gd::Project &project, std::vector<gd::String> &requiredFiles) {
|
||||
auto addRequiredFiles = [&](const std::vector<gd::String> &newRequiredFiles) {
|
||||
for (const auto &requiredFile : newRequiredFiles) {
|
||||
InsertUnique(requiredFiles, requiredFile);
|
||||
}
|
||||
};
|
||||
|
||||
auto addObjectRequiredFiles = [&](const gd::Object &object) {
|
||||
// Ensure needed files are included for the object type and its behaviors.
|
||||
|
||||
// TODO: Handle required files declared by objects. For now, no objects has
|
||||
// a need for additional required files, so the object metadata do not even
|
||||
// have `requiredFiles`.
|
||||
|
||||
std::vector<gd::String> behaviors = object.GetAllBehaviorNames();
|
||||
for (std::size_t j = 0; j < behaviors.size(); ++j) {
|
||||
const gd::BehaviorMetadata &metadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(
|
||||
JsPlatform::Get(),
|
||||
object.GetBehavior(behaviors[j]).GetTypeName());
|
||||
addRequiredFiles(metadata.requiredFiles);
|
||||
}
|
||||
};
|
||||
|
||||
auto addObjectsRequiredFiles =
|
||||
[&](const gd::ObjectsContainer &objectsContainer) {
|
||||
for (std::size_t i = 0; i < objectsContainer.GetObjectsCount(); ++i) {
|
||||
addObjectRequiredFiles(objectsContainer.GetObject(i));
|
||||
}
|
||||
};
|
||||
|
||||
addObjectsRequiredFiles(project);
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
const gd::Layout &layout = project.GetLayout(i);
|
||||
addObjectsRequiredFiles(layout);
|
||||
}
|
||||
}
|
||||
|
||||
void ExporterHelper::ExportResources(gd::AbstractFileSystem &fs,
|
||||
gd::Project &project,
|
||||
gd::String exportDir) {
|
||||
|
@@ -247,19 +247,6 @@ class ExporterHelper {
|
||||
bool ExportEffectIncludes(const gd::Project &project,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Add the include files for all the objects of the project
|
||||
* and their behaviors.
|
||||
*/
|
||||
void ExportObjectAndBehaviorsIncludes(const gd::Project &project,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
/**
|
||||
* \brief Add the required files for all the objects of the project
|
||||
* and their behaviors.
|
||||
*/
|
||||
void ExportObjectAndBehaviorsRequiredFiles(const gd::Project &project,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Copy the external source files used by the game into the export
|
||||
* directory, and add them into files to be included.
|
||||
|
@@ -2221,8 +2221,12 @@ interface PropertyFunctionGenerator {
|
||||
boolean STATIC_CanGenerateGetterAndSetter([Const, Ref] AbstractEventsBasedEntity eventsBasedBehavior, [Const, Ref] NamedPropertyDescriptor property);
|
||||
};
|
||||
|
||||
interface UsedExtensionsResult {
|
||||
[Const, Ref] SetString GetUsedExtensions();
|
||||
};
|
||||
|
||||
interface UsedExtensionsFinder {
|
||||
[Value] SetString STATIC_ScanProject([Ref] Project project);
|
||||
[Value] UsedExtensionsResult STATIC_ScanProject([Ref] Project project);
|
||||
};
|
||||
|
||||
interface ExtensionAndBehaviorMetadata {
|
||||
|
@@ -108,6 +108,7 @@ describe('libGD.js', function () {
|
||||
it('should have a list of extensions', function () {
|
||||
expect(
|
||||
gd.UsedExtensionsFinder.scanProject(project)
|
||||
.getUsedExtensions()
|
||||
.toNewVectorString()
|
||||
.toJSArray()
|
||||
).toEqual([]);
|
||||
@@ -116,6 +117,7 @@ describe('libGD.js', function () {
|
||||
|
||||
expect(
|
||||
gd.UsedExtensionsFinder.scanProject(project)
|
||||
.getUsedExtensions()
|
||||
.toNewVectorString()
|
||||
.toJSArray()
|
||||
).toEqual(['Sprite']);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdUsedExtensionsFinder {
|
||||
static scanProject(project: gdProject): gdSetString;
|
||||
static scanProject(project: gdProject): gdUsedExtensionsResult;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
6
GDevelop.js/types/gdusedextensionsresult.js
Normal file
6
GDevelop.js/types/gdusedextensionsresult.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdUsedExtensionsResult {
|
||||
getUsedExtensions(): gdSetString;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -152,6 +152,7 @@ declare class libGDevelop {
|
||||
VectorUnfilledRequiredBehaviorPropertyProblem: Class<gdVectorUnfilledRequiredBehaviorPropertyProblem>;
|
||||
WholeProjectRefactorer: Class<gdWholeProjectRefactorer>;
|
||||
PropertyFunctionGenerator: Class<gdPropertyFunctionGenerator>;
|
||||
UsedExtensionsResult: Class<gdUsedExtensionsResult>;
|
||||
UsedExtensionsFinder: Class<gdUsedExtensionsFinder>;
|
||||
ExtensionAndBehaviorMetadata: Class<gdExtensionAndBehaviorMetadata>;
|
||||
ExtensionAndObjectMetadata: Class<gdExtensionAndObjectMetadata>;
|
||||
|
@@ -43,7 +43,6 @@ type Options = {|
|
||||
|
||||
type CodeGenerationContext = {|
|
||||
codeNamespacePrefix: string,
|
||||
extensionIncludeFiles: Array<string>,
|
||||
|};
|
||||
|
||||
const mangleName = (name: string) => {
|
||||
@@ -145,29 +144,6 @@ const loadProjectEventsFunctionsExtension = (
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of mandatory include files when using the
|
||||
* extension.
|
||||
*/
|
||||
const getExtensionIncludeFiles = (
|
||||
project: gdProject,
|
||||
eventsFunctionsExtension: gdEventsFunctionsExtension,
|
||||
options: Options,
|
||||
codeNamespacePrefix: string
|
||||
): Array<string> => {
|
||||
return mapFor(0, eventsFunctionsExtension.getEventsFunctionsCount(), i => {
|
||||
const eventsFunction = eventsFunctionsExtension.getEventsFunctionAt(i);
|
||||
|
||||
const codeNamespace = getFreeFunctionCodeNamespace(
|
||||
eventsFunction,
|
||||
codeNamespacePrefix
|
||||
);
|
||||
const functionName = codeNamespace + '.func'; // TODO
|
||||
|
||||
return options.eventsFunctionCodeWriter.getIncludeFileFor(functionName);
|
||||
}).filter(Boolean);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the code for the events based extension
|
||||
*/
|
||||
@@ -182,15 +158,8 @@ const generateEventsFunctionExtension = (
|
||||
const codeNamespacePrefix =
|
||||
'gdjs.evtsExt__' + mangleName(eventsFunctionsExtension.getName());
|
||||
|
||||
const extensionIncludeFiles = getExtensionIncludeFiles(
|
||||
project,
|
||||
eventsFunctionsExtension,
|
||||
options,
|
||||
codeNamespacePrefix
|
||||
);
|
||||
const codeGenerationContext = {
|
||||
codeNamespacePrefix,
|
||||
extensionIncludeFiles,
|
||||
};
|
||||
|
||||
return Promise.all(
|
||||
@@ -246,9 +215,6 @@ const generateEventsFunctionExtension = (
|
||||
)
|
||||
)
|
||||
.then(functionInfos => {
|
||||
if (!options.skipCodeGeneration) {
|
||||
applyFunctionIncludeFilesDependencyTransitivity(functionInfos);
|
||||
}
|
||||
return extension;
|
||||
});
|
||||
};
|
||||
@@ -301,11 +267,6 @@ const generateFreeFunction = (
|
||||
.setIncludeFile(functionFile)
|
||||
.setFunctionName(functionName);
|
||||
|
||||
// Always include the extension include files when using a free function.
|
||||
codeGenerationContext.extensionIncludeFiles.forEach(includeFile => {
|
||||
instructionOrExpression.addIncludeFile(includeFile);
|
||||
});
|
||||
|
||||
if (!options.skipCodeGeneration) {
|
||||
const includeFiles = new gd.SetString();
|
||||
const eventsFunctionsExtensionCodeGenerator = new gd.EventsFunctionsExtensionCodeGenerator(
|
||||
@@ -353,65 +314,6 @@ const generateFreeFunction = (
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add dependencies between functions according to transitivity.
|
||||
* @param functionInfos free function metadatas
|
||||
*/
|
||||
const applyFunctionIncludeFilesDependencyTransitivity = (
|
||||
functionInfos: Array<{
|
||||
functionFile: string,
|
||||
functionMetadata:
|
||||
| gdInstructionMetadata
|
||||
| gdExpressionMetadata
|
||||
| gdMultipleInstructionMetadata,
|
||||
}>
|
||||
): void => {
|
||||
// Note that the iteration order doesn't matter, for instance for:
|
||||
// a -> b
|
||||
// b -> c
|
||||
// c -> d
|
||||
//
|
||||
// going from a to c:
|
||||
// a -> (b -> c)
|
||||
// b -> c
|
||||
// c -> d
|
||||
//
|
||||
// or from c to a:
|
||||
// a -> b
|
||||
// b -> (c -> d)
|
||||
// c -> d
|
||||
//
|
||||
// give the same result:
|
||||
// a -> (b -> (c -> d))
|
||||
// b -> (c -> d)
|
||||
// c -> d
|
||||
const includeFileSets = functionInfos.map(
|
||||
functionInfo =>
|
||||
new Set(functionInfo.functionMetadata.getIncludeFiles().toJSArray())
|
||||
);
|
||||
// For any function A of the extension...
|
||||
for (let index = 0; index < functionInfos.length; index++) {
|
||||
const includeFiles = includeFileSets[index];
|
||||
const functionIncludeFile = functionInfos[index].functionFile;
|
||||
|
||||
// ...and any function B of the extension...
|
||||
for (let otherIndex = 0; otherIndex < functionInfos.length; otherIndex++) {
|
||||
const otherFunctionMetadata = functionInfos[otherIndex].functionMetadata;
|
||||
const otherIncludeFileSet = includeFileSets[otherIndex];
|
||||
// ...where function B depends on function A...
|
||||
if (otherIncludeFileSet.has(functionIncludeFile)) {
|
||||
// ...add function A dependencies to the function B ones.
|
||||
includeFiles.forEach(includeFile => {
|
||||
if (!otherIncludeFileSet.has(includeFile)) {
|
||||
otherIncludeFileSet.add(includeFile);
|
||||
otherFunctionMetadata.addIncludeFile(includeFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function generateBehavior(
|
||||
project: gdProject,
|
||||
extension: gdPlatformExtension,
|
||||
@@ -436,11 +338,6 @@ function generateBehavior(
|
||||
|
||||
behaviorMetadata.setIncludeFile(includeFile);
|
||||
|
||||
// Always include the extension include files when using a behavior.
|
||||
codeGenerationContext.extensionIncludeFiles.forEach(includeFile => {
|
||||
behaviorMetadata.addIncludeFile(includeFile);
|
||||
});
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
const behaviorMethodMangledNames = new gd.MapStringString();
|
||||
|
||||
@@ -557,11 +454,6 @@ function generateObject(
|
||||
|
||||
objectMetadata.setIncludeFile(includeFile);
|
||||
|
||||
// Always include the extension include files when using an object.
|
||||
codeGenerationContext.extensionIncludeFiles.forEach(includeFile => {
|
||||
objectMetadata.addIncludeFile(includeFile);
|
||||
});
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
const objectMethodMangledNames = new gd.MapStringString();
|
||||
|
||||
|
Reference in New Issue
Block a user