From 265473b9f0386ca2e5af7f3365c471e40bbb9391 Mon Sep 17 00:00:00 2001
From: AnimatedSwine37 <24914353+AnimatedSwine37@users.noreply.github.com>
Date: Sun, 20 Oct 2024 11:04:31 +1000
Subject: [PATCH 1/4] Add TryGetImports
---
.../Compiler/FlowScriptCompiler.cs | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
index 0d4a3497..9ffecb1a 100644
--- a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
+++ b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
@@ -125,6 +125,37 @@ public void AddListener(LogListener listener)
listener.Subscribe(mLogger);
}
+ ///
+ /// Tries to get a list of all files imported (directly or transitively) by a list of base flow files.
+ ///
+ /// A List of paths to .bf, .flow, and .msg files that will be added on top of the base flow
+ /// A list of all imports found.
+ ///
+ public bool TryGetImports(List files, out string[] resolvedImports)
+ {
+ CompilationUnit compilationUnit = new CompilationUnit();
+ compilationUnit.Imports.AddRange(files.Select(import => new Import(import)));
+ mCurrentBaseDirectory = "";
+ InitializeCompilationState();
+
+ // Resolve imports
+ if (compilationUnit.Imports.Count > 0)
+ {
+ do
+ {
+ if (!TryResolveImports(compilationUnit))
+ {
+ Error(compilationUnit, "Failed to resolve imports");
+ resolvedImports = Array.Empty();
+ return false;
+ }
+ } while (mReresolveImports);
+ }
+
+ resolvedImports = compilationUnit.Imports.Select(import => import.CompilationUnitFileName).ToArray();
+ return true;
+ }
+
///
/// Tries to compile the provided FlowScript source with given imports. Returns a boolean indicating if the operation succeeded.
///
From 551c611a066c9d44385b7d8b866d8f5b4d36cc02 Mon Sep 17 00:00:00 2001
From: AnimatedSwine37 <24914353+AnimatedSwine37@users.noreply.github.com>
Date: Sun, 20 Oct 2024 11:05:05 +1000
Subject: [PATCH 2/4] Add sources output to TryCompileWithImports
---
.../Compiler/FlowScriptCompiler.cs | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
index 9ffecb1a..a11decdc 100644
--- a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
+++ b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
@@ -164,6 +164,20 @@ public bool TryGetImports(List files, out string[] resolvedImports)
/// The compiled FlowScript
/// True if the file successfully compiled, false otherwise
public bool TryCompileWithImports(FileStream baseBfStream, List imports, string baseFlow, out FlowScript flowScript)
+ {
+ return TryCompileWithImports(baseBfStream, imports, baseFlow, out flowScript, out _);
+ }
+
+ ///
+ /// Tries to compile the provided FlowScript source with given imports. Returns a boolean indicating if the operation succeeded.
+ ///
+ /// A FileStream of the base bf file
+ /// A List of paths to .bf, .flow, and .msg files that will be forcibly imported
+ /// A full path to the base .flow file to use for compilation
+ /// The compiled FlowScript or null if compilation failed
+ /// A list of full paths to all source files used to compile this bf or null if compilation failed
+ /// True if the file successfully compiled, false otherwise
+ public bool TryCompileWithImports(FileStream baseBfStream, List imports, string baseFlow, out FlowScript flowScript, out List sources)
{
// Parse base flow file
CompilationUnit compilationUnit;
@@ -191,6 +205,7 @@ public bool TryCompileWithImports(FileStream baseBfStream, List imports,
{
Error("Failed to parse compilation unit");
flowScript = null;
+ sources = null;
return false;
}
}
@@ -209,7 +224,17 @@ public bool TryCompileWithImports(FileStream baseBfStream, List imports,
compilationUnit.Imports.AddRange(imports.Select(import => new Import(import)));
mCurrentBaseDirectory = "";
- return TryCompile(compilationUnit, out flowScript);
+ if (TryCompile(compilationUnit, out flowScript))
+ {
+ sources = compilationUnit.Imports.Select(import => import.CompilationUnitFileName).ToList();
+ sources.Add(baseFlow);
+ return true;
+ }
+ else
+ {
+ sources = null;
+ return false;
+ }
}
///
From 85098f58cd44a556d559c8526239397fbfedf632 Mon Sep 17 00:00:00 2001
From: AnimatedSwine37 <24914353+AnimatedSwine37@users.noreply.github.com>
Date: Sun, 20 Oct 2024 11:17:05 +1000
Subject: [PATCH 3/4] Improve summary comment for TryGetImports
---
.../FlowScriptLanguage/Compiler/FlowScriptCompiler.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
index a11decdc..81aae00b 100644
--- a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
+++ b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
@@ -126,11 +126,11 @@ public void AddListener(LogListener listener)
}
///
- /// Tries to get a list of all files imported (directly or transitively) by a list of base flow files.
+ /// Tries to get a list of all files that would be imported (directly or transitively) when compiling a flowscript file.
///
- /// A List of paths to .bf, .flow, and .msg files that will be added on top of the base flow
- /// A list of all imports found.
- ///
+ /// A List of paths to .bf, .flow, and .msg files to be used as a base when checking for imports.
+ /// A list of all imports found. This includes the passed in .
+ /// True if imports could be resolved, false otherwise
public bool TryGetImports(List files, out string[] resolvedImports)
{
CompilationUnit compilationUnit = new CompilationUnit();
From 805da0feb0662ae7c6d1b712a0c2bfd5c841210b Mon Sep 17 00:00:00 2001
From: AnimatedSwine37 <24914353+AnimatedSwine37@users.noreply.github.com>
Date: Sat, 30 Nov 2024 13:02:06 +1000
Subject: [PATCH 4/4] Only parse Flowscript files in TryGetImports
---
.../Compiler/FlowScriptCompiler.cs | 106 +++++++++++++++++-
1 file changed, 100 insertions(+), 6 deletions(-)
diff --git a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
index 81aae00b..bbee33b6 100644
--- a/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
+++ b/Source/AtlusScriptLibrary/FlowScriptLanguage/Compiler/FlowScriptCompiler.cs
@@ -133,26 +133,25 @@ public void AddListener(LogListener listener)
/// True if imports could be resolved, false otherwise
public bool TryGetImports(List files, out string[] resolvedImports)
{
- CompilationUnit compilationUnit = new CompilationUnit();
- compilationUnit.Imports.AddRange(files.Select(import => new Import(import)));
+ var imports = files.Select(import => new Import(import)).ToList();
mCurrentBaseDirectory = "";
InitializeCompilationState();
// Resolve imports
- if (compilationUnit.Imports.Count > 0)
+ if (imports.Count > 0)
{
do
{
- if (!TryResolveImports(compilationUnit))
+ if (!TryResolveImportsSimple(imports))
{
- Error(compilationUnit, "Failed to resolve imports");
+ Error("Failed to resolve imports");
resolvedImports = Array.Empty();
return false;
}
} while (mReresolveImports);
}
- resolvedImports = compilationUnit.Imports.Select(import => import.CompilationUnitFileName).ToArray();
+ resolvedImports = imports.Select(import => import.CompilationUnitFileName).ToArray();
return true;
}
@@ -161,6 +160,7 @@ public bool TryGetImports(List files, out string[] resolvedImports)
///
/// A FileStream of the base bf file
/// A List of paths to .bf, .flow, and .msg files that will be forcibly imported
+ /// A full path to the base .flow file to use for compilation
/// The compiled FlowScript
/// True if the file successfully compiled, false otherwise
public bool TryCompileWithImports(FileStream baseBfStream, List imports, string baseFlow, out FlowScript flowScript)
@@ -498,7 +498,101 @@ private void ExpandImportStatementsPaths(CompilationUnit compilationUnit, string
import.CompilationUnitFileName = Path.Combine(baseDirectory, import.CompilationUnitFileName);
}
}
+
+ private void ExpandImportStatementsPaths(List imports, string baseDirectory)
+ {
+ foreach (var import in imports)
+ {
+ import.CompilationUnitFileName = Path.Combine(baseDirectory, import.CompilationUnitFileName);
+ }
+ }
+
+ ///
+ /// Tries to resolve a list of imports whilst only parsing flowscript files (since they can contain additional imports).
+ /// Compiled flowscript and message files are not parsed, they are just added to the list of imports.
+ ///
+ /// This can be used to determine a list of all imports starting from some initial ones.
+ /// It is not sufficient to actually compile the flowscript.
+ ///
+ /// is set to true this should be run again to determine additional imports from
+ /// flowscript files.
+ ///
+ /// The imports to resolve. Newly found imports are added to this.
+ /// True if imports could be resolved, false otherwise
+ private bool TryResolveImportsSimple(List imports)
+ {
+ Info("Resolving imports");
+
+ ExpandImportStatementsPaths(imports, mCurrentBaseDirectory);
+
+ var importedFlowScripts = new List();
+ var importedMsgAndBfs = new List();
+
+ foreach (var import in imports)
+ {
+ var ext = Path.GetExtension(import.CompilationUnitFileName).ToLowerInvariant();
+ switch (ext)
+ {
+ case ".msg" or ".bf":
+ {
+ if (!TryGetFullImportPath(import, out var compilationUnitFilePath))
+ {
+ Error($"Failed to resolve import: {import.CompilationUnitFileName}");
+ return false;
+ }
+ importedMsgAndBfs.Add(new Import(compilationUnitFilePath));
+ }
+ break;
+
+ case ".flow":
+ {
+ // FlowScript
+ if (!TryResolveFlowScriptImport(import, out var importedCompilationUnit))
+ {
+ Error(import, $"Failed to resolve FlowScript import: {import.CompilationUnitFileName}");
+ return false;
+ }
+
+ // Will be null if it was already imported before
+ if (importedCompilationUnit != null)
+ importedFlowScripts.Add(importedCompilationUnit);
+ }
+ break;
+
+ default:
+ // Unknown
+ Error(import, $"Unknown import file type: {import.CompilationUnitFileName}");
+ return false;
+ }
+ }
+
+ // Resolve FlowScript imports
+ bool shouldReresolveImports = false;
+ if (importedFlowScripts.Count > 0)
+ {
+ // Merge compilation units
+ foreach (var importedFlowScript in importedFlowScripts)
+ {
+ if (importedFlowScript.Imports.Count > 0)
+ {
+ // If any of the imported FlowScripts have import, we have to re-resolve the imports again
+ shouldReresolveImports = true;
+ imports.AddRange(importedFlowScript.Imports);
+ }
+ }
+ }
+
+ mReresolveImports = shouldReresolveImports;
+
+ if (!mReresolveImports)
+ Info("Done resolving imports");
+
+ imports.AddRange(importedMsgAndBfs);
+
+ return true;
+ }
+
//
// Resolving imports
//