summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-09-01 10:06:19 -0400
committerGitHub <noreply@github.com>2022-09-01 10:06:19 -0400
commit3c0177134d126956336865623ea3d6861be59cfa (patch)
tree920ba158afe75edde6f5254617dfa22ffeb98403 /source
parentcd8715a7760189c54b36c0c250efbe1db5b8635c (diff)
Make FileSystem files and OS files distinct (#2383)
* #include an absolute path didn't work - because paths were taken to always be relative. * Make DownstreamCompileOptions use POD types. * CharSliceAllocator -> SliceAllocator Added SliceConverter CharSliceCaster -> SliceCaster * First attempt at zero terminating around blobs. * Fix clang warning. * Add SlangTerminatedChars Make Blob implementations support it. Make most blobs 'terminated'. * Fix bug setting up sourceFiles for CommandLineDownstreamCompiler. * Traffic in TerminatedCharSlice for sourceFiles. Use ArtifactDesc to generate temporary file names for source. * Fix typo in testing for shared library/C++. * Working with source being passed as artifacts to DownstreamCompiler. * Use artifacts in SourceManager/SourceFile. * Support infering extension from the original file extension. * * Infer extension if can't determine from the artifact type * Split IOSFile/IExtFile representations * Move responsibility for creating OS file to the handler. * Disable the check memory path.
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp29
-rw-r--r--source/compiler-core/slang-artifact-desc-util.h12
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.cpp87
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.h6
-rw-r--r--source/compiler-core/slang-artifact-helper.cpp38
-rw-r--r--source/compiler-core/slang-artifact-helper.h20
-rw-r--r--source/compiler-core/slang-artifact-impl.cpp14
-rw-r--r--source/compiler-core/slang-artifact-impl.h2
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.cpp77
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.h69
-rw-r--r--source/compiler-core/slang-artifact-representation.h39
-rw-r--r--source/compiler-core/slang-artifact-util.cpp119
-rw-r--r--source/compiler-core/slang-artifact-util.h22
-rw-r--r--source/compiler-core/slang-artifact.h8
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp32
-rw-r--r--source/compiler-core/slang-downstream-compiler.h2
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp2
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp18
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.h4
-rw-r--r--source/compiler-core/slang-include-system.cpp4
-rw-r--r--source/compiler-core/slang-source-loc.cpp76
-rw-r--r--source/compiler-core/slang-source-loc.h5
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.cpp19
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.h4
-rw-r--r--source/slang/slang-compiler.cpp9
-rwxr-xr-xsource/slang/slang-compiler.h2
-rw-r--r--source/slang/slang-options.cpp6
-rw-r--r--source/slang/slang-preprocessor.cpp2
-rw-r--r--source/slang/slang.cpp43
29 files changed, 425 insertions, 345 deletions
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index 7534e1265..7e274794f 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -704,7 +704,13 @@ SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, S
/* static */String ArtifactDescUtil::getBaseNameFromPath(const ArtifactDesc& desc, const UnownedStringSlice& path)
{
- String name = Path::getFileName(path);
+ const String name = Path::getFileName(path);
+ return getBaseNameFromName(desc, name.getUnownedSlice());
+}
+
+/* static */String ArtifactDescUtil::getBaseNameFromName(const ArtifactDesc& desc, const UnownedStringSlice& inName)
+{
+ String name(inName);
const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY;
if (isSharedLibraryPrefixPlatform)
@@ -723,16 +729,19 @@ SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, S
}
}
- // Strip any extension
+ // Strip any extension
{
StringBuilder descExt;
-
- appendDefaultExtension(desc, descExt);
-
- // Strip the extension if it's a match
- if (descExt.getLength() &&
- Path::getPathExt(name) == descExt)
+ if (SLANG_SUCCEEDED(appendDefaultExtension(desc, descExt)) &&
+ descExt.getLength())
{
+ // TODO(JS):
+ // It has an extension. We could check if they are the same
+ // but if they are not that might be fine, because of case insensitivity
+ // or perhaps there are multiple valid extensions. So for now we just strip
+ // and don't bother confirming with something like..
+ // if (Path::getPathExt(name) == descExt))
+
name = Path::getFileNameWithoutExt(name);
}
}
@@ -740,9 +749,9 @@ SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, S
return name;
}
-/* static */String ArtifactDescUtil::getBaseName(const ArtifactDesc& desc, IFileArtifactRepresentation* fileRep)
+/* static */String ArtifactDescUtil::getBaseName(const ArtifactDesc& desc, IPathArtifactRepresentation* pathRep)
{
- UnownedStringSlice path(fileRep->getPath());
+ UnownedStringSlice path(pathRep->getPath());
return getBaseNameFromPath(desc, path);
}
diff --git a/source/compiler-core/slang-artifact-desc-util.h b/source/compiler-core/slang-artifact-desc-util.h
index b700fa465..6aa5c321e 100644
--- a/source/compiler-core/slang-artifact-desc-util.h
+++ b/source/compiler-core/slang-artifact-desc-util.h
@@ -68,12 +68,12 @@ struct ArtifactDescUtil
/// Given a desc and a path returns the base name (stripped of prefix and extension)
static String getBaseNameFromPath(const ArtifactDesc& desc, const UnownedStringSlice& path);
- /// Get the base name of this artifact.
- /// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
- /// Else if there is an explicit name set, this is returned.
- /// Else returns the empty string
-
- static String getBaseName(const ArtifactDesc& desc, IFileArtifactRepresentation* fileRep);
+ /// Given a desc and a name returns the base name (stripped of prefix and extension)
+ static String getBaseNameFromName(const ArtifactDesc& desc, const UnownedStringSlice& path);
+
+ /// Get the base name of the fileRep
+ /// If no base name is found will return an empty slice
+ static String getBaseName(const ArtifactDesc& desc, IPathArtifactRepresentation* fileRep);
/// Given a desc and a basePath returns a suitable path for a entity of specified desc
static SlangResult calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath);
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp
index 94e6fb6f7..d7c3f02b6 100644
--- a/source/compiler-core/slang-artifact-handler-impl.cpp
+++ b/source/compiler-core/slang-artifact-handler-impl.cpp
@@ -7,9 +7,12 @@
#include "slang-artifact-desc-util.h"
#include "slang-artifact-helper.h"
+#include "slang-artifact-util.h"
#include "../core/slang-castable-util.h"
+#include "slang-slice-allocator.h"
+
#include "../core/slang-file-system.h"
#include "../core/slang-io.h"
#include "../core/slang-shared-library.h"
@@ -148,42 +151,72 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac
SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, sharedLib.writeRef()));
return _addRepresentation(artifact, keep, sharedLib, outCastable);
}
+ else if (guid == IOSFileArtifactRepresentation::getTypeGuid())
+ {
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
+ SLANG_RETURN_ON_FAIL(_createOSFile(artifact, getIntermediateKeep(keep), fileRep.writeRef()));
+ return _addRepresentation(artifact, keep, fileRep, outCastable);
+ }
return SLANG_E_NOT_AVAILABLE;
}
-static bool _isFileSystemFile(ICastable* castable, void* data)
+SlangResult DefaultArtifactHandler::_createOSFile(IArtifact* artifact, ArtifactKeep keep, IOSFileArtifactRepresentation** outFileRep)
{
- if (auto fileRep = as<IFileArtifactRepresentation>(castable))
+ // Look if we have an IExtFile representation, as we might already have a OS file associated with that
+ if (auto extRep = findRepresentation<IExtFileArtifactRepresentation>(artifact))
{
- ISlangMutableFileSystem* fileSystem = (ISlangMutableFileSystem*)data;
- if (fileRep->getFileSystem() == fileSystem)
+ auto system = extRep->getFileSystem();
+
+ String path;
+ switch (system->getOSPathKind())
{
- return true;
+ case OSPathKind::Direct:
+ {
+ path = UnownedStringSlice(extRep->getPath());
+ break;
+ }
+ case OSPathKind::Canonical:
+ {
+ ComPtr<ISlangBlob> canonicalPathBlob;
+ if (SLANG_SUCCEEDED(system->getCanonicalPath(extRep->getPath(), canonicalPathBlob.writeRef())))
+ {
+ path = StringUtil::getString(canonicalPathBlob);
+ }
+ break;
+ }
+ default: break;
}
- }
- return false;
-}
-SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
-{
- // See if we already have it
- if (auto fileRep = as<IFileArtifactRepresentation>(artifact->findRepresentationWithPredicate(&_isFileSystemFile, fileSystem)))
- {
- fileRep->addRef();
- *outFileRep = fileRep;
- return SLANG_OK;
+ if (path.getLength())
+ {
+ auto fileRep = OSFileArtifactRepresentation::create(IOSFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice() , nullptr);
+ // As a sanity check make sure it exists!
+ if (fileRep->exists())
+ {
+ *outFileRep = fileRep.detach();
+ return SLANG_OK;
+ }
+ }
}
+ // Okay looks like we will need to generate a temporary file
auto helper = DefaultArtifactHelper::getSingleton();
// If we are going to access as a file we need to be able to write it, and to do that we need a blob
ComPtr<ISlangBlob> blob;
SLANG_RETURN_ON_FAIL(artifact->loadBlob(getIntermediateKeep(keep), blob.writeRef()));
+ // Find some name associated
+ auto name = ArtifactUtil::findName(artifact);
+ if (name.getLength() == 0)
+ {
+ name = toSlice("unknown");
+ }
+
// Okay we need to store as a temporary. Get a lock file.
- ComPtr<IFileArtifactRepresentation> lockFile;
- SLANG_RETURN_ON_FAIL(helper->createLockFile(artifact->getName(), fileSystem, lockFile.writeRef()));
+ ComPtr<IOSFileArtifactRepresentation> lockFile;
+ SLANG_RETURN_ON_FAIL(helper->createLockFile(asCharSlice(name), lockFile.writeRef()));
// Now we need the appropriate name for this item
ComPtr<ISlangBlob> pathBlob;
@@ -194,7 +227,7 @@ SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* art
// Write the contents
SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
// TODO(JS): This path comparison is perhaps not perfect, in that it assumes the path is not changed
// in any way. For example an impl of calcArtifactPath that changed slashes or used a canonical path
@@ -209,13 +242,7 @@ SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* art
else
{
// Create a new rep that references the lock file
- fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, lockFile->getFileSystem());
- }
-
- // Create the rep
- if (canKeep(keep))
- {
- artifact->addRepresentation(fileRep);
+ fileRep = new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::Owned, path, lockFile);
}
// Return the file
@@ -232,14 +259,11 @@ SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ISla
isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
{
// Get as a file represenation on the OS file system
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
// We want to keep the file representation, otherwise every request, could produce a new file
// and that seems like a bad idea.
- SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
-
- // We requested on the OS file system, just check that's what we got...
- SLANG_ASSERT(fileRep->getFileSystem() == nullptr);
+ SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, fileRep.writeRef()));
// Try loading the shared library
SharedLibrary::Handle handle;
@@ -247,6 +271,7 @@ SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ISla
{
return SLANG_FAIL;
}
+
// Output
*outSharedLibrary = ScopeSharedLibrary::create(handle, fileRep).detach();
return SLANG_OK;
diff --git a/source/compiler-core/slang-artifact-handler-impl.h b/source/compiler-core/slang-artifact-handler-impl.h
index 88be93f55..a46005a33 100644
--- a/source/compiler-core/slang-artifact-handler-impl.h
+++ b/source/compiler-core/slang-artifact-handler-impl.h
@@ -23,13 +23,13 @@ public:
// IArtifactHandler
SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) SLANG_OVERRIDE;
SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
-
+
static IArtifactHandler* getSingleton() { return &g_singleton; }
protected:
SlangResult _loadSharedLibrary(IArtifact* artifact, ISlangSharedLibrary** outSharedLibrary);
-
+ SlangResult _createOSFile(IArtifact* artifact, ArtifactKeep intermediateKeep, IOSFileArtifactRepresentation** outFileRep);
+
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
diff --git a/source/compiler-core/slang-artifact-helper.cpp b/source/compiler-core/slang-artifact-helper.cpp
index 27965b0cc..c3b007d28 100644
--- a/source/compiler-core/slang-artifact-helper.cpp
+++ b/source/compiler-core/slang-artifact-helper.cpp
@@ -87,26 +87,12 @@ ArtifactStyle DefaultArtifactHelper::getStyleParent(ArtifactStyle style) { retur
UnownedStringSlice DefaultArtifactHelper::getStyleName(ArtifactStyle style) { return getName(style); }
bool DefaultArtifactHelper::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
-SlangResult DefaultArtifactHelper::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile)
+SlangResult DefaultArtifactHelper::createLockFile(const CharSlice& inNameBase, IOSFileArtifactRepresentation** outLockFile)
{
- if (fileSystem)
- {
- if (fileSystem != OSFileSystem::getMutableSingleton())
- {
- // We can only create lock files, on the global OS file system
- return SLANG_E_NOT_AVAILABLE;
- }
- fileSystem = nullptr;
- }
-
- const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
-
+ const UnownedStringSlice nameBase = inNameBase.count ? asStringSlice(inNameBase) : UnownedStringSlice("unknown");
String lockPath;
SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
-
- ComPtr<IFileArtifactRepresentation> lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath.getUnownedSlice(), nullptr, fileSystem));
-
- *outLockFile = lockFile.detach();
+ *outLockFile = OSFileArtifactRepresentation::create(IOSFileArtifactRepresentation::Kind::Lock, lockPath.getUnownedSlice(), nullptr).detach();
return SLANG_OK;
}
@@ -151,22 +137,26 @@ SlangResult DefaultArtifactHelper::createCastableList(const Guid& guid, ICastabl
return SLANG_E_NO_INTERFACE;
}
-SlangResult DefaultArtifactHelper::createFileArtifactRepresentation(
- IFileArtifactRepresentation::Kind kind, const CharSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outRep)
+SlangResult DefaultArtifactHelper::createOSFileArtifactRepresentation(
+ IOSFileArtifactRepresentation::Kind kind, const CharSlice& path, IOSFileArtifactRepresentation* lockFile, IOSFileArtifactRepresentation** outRep)
{
- *outRep = FileArtifactRepresentation::create(kind, asStringSlice(path), lockFile, fileSystem).detach();
+ *outRep = OSFileArtifactRepresentation::create(kind, asStringSlice(path), lockFile).detach();
return SLANG_OK;
}
+SlangResult DefaultArtifactHelper::createExtFileArtifactRepresentation(const CharSlice& path, ISlangFileSystemExt* system, IExtFileArtifactRepresentation** outRep)
+{
+ *outRep = ExtFileArtifactRepresentation::create(asStringSlice(path), system).detach();
+ return SLANG_OK;
+}
-SlangResult DefaultArtifactHelper::createFileArtifact(const ArtifactDesc& desc, const CharSlice& path, IArtifact** outArtifact)
+SlangResult DefaultArtifactHelper::createOSFileArtifact(const ArtifactDesc& desc, const CharSlice& path, IArtifact** outArtifact)
{
auto artifact = Artifact::create(desc);
- auto fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Reference, asStringSlice(path), nullptr, nullptr);
-
+ auto fileRep = new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::Reference, asStringSlice(path), nullptr);
artifact->addRepresentation(fileRep);
-
+
*outArtifact = artifact.detach();
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-artifact-helper.h b/source/compiler-core/slang-artifact-helper.h
index 208c80bd5..e14a67d7c 100644
--- a/source/compiler-core/slang-artifact-helper.h
+++ b/source/compiler-core/slang-artifact-helper.h
@@ -41,7 +41,7 @@ class IArtifactHelper : public ICastable
virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
/// Create a lock file, the path of which can be used to generate other temporary files
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const CharSlice& nameBase, IOSFileArtifactRepresentation** outLockFile) = 0;
/// Given a desc and a basePath returns a suitable name
virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactDescPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0;
@@ -56,14 +56,16 @@ class IArtifactHelper : public ICastable
virtual SLANG_NO_THROW void SLANG_MCALL getCastable(ISlangUnknown* unk, ICastable** outCastable) = 0;
/// Create a file rep
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createFileArtifactRepresentation(
- IFileArtifactRepresentation::Kind kind, const CharSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outRep) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createOSFileArtifactRepresentation(
+ IOSFileArtifactRepresentation::Kind kind, const CharSlice& path, IOSFileArtifactRepresentation* lockFile, IOSFileArtifactRepresentation** outRep) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createExtFileArtifactRepresentation(const CharSlice& path, ISlangFileSystemExt* system, IExtFileArtifactRepresentation** outRep) = 0;
/// Create an empty ICastableList
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createCastableList(const Guid& guid, ICastableList** outList) = 0;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createFileArtifact(const ArtifactDesc& desc, const CharSlice& slice, IArtifact** outArtifact) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createOSFileArtifact(const ArtifactDesc& desc, const CharSlice& slice, IArtifact** outArtifact) = 0;
};
class DefaultArtifactHelper : public IArtifactHelper
@@ -93,7 +95,7 @@ public:
virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const CharSlice& nameBase, IOSFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactDescPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) SLANG_OVERRIDE;
@@ -105,10 +107,12 @@ public:
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createCastableList(const Guid& guid, ICastableList** outList) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createFileArtifactRepresentation(
- IFileArtifactRepresentation::Kind kind, const CharSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outRep) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createOSFileArtifactRepresentation(
+ IOSFileArtifactRepresentation::Kind kind, const CharSlice& path, IOSFileArtifactRepresentation* lockFile, IOSFileArtifactRepresentation** outRep) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createExtFileArtifactRepresentation(const CharSlice& path, ISlangFileSystemExt* system, IExtFileArtifactRepresentation** outRep) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createFileArtifact(const ArtifactDesc& desc, const CharSlice& slice, IArtifact** outArtifact) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createOSFileArtifact(const ArtifactDesc& desc, const CharSlice& slice, IArtifact** outArtifact) SLANG_OVERRIDE;
static IArtifactHelper* getSingleton() { return &g_singleton; }
diff --git a/source/compiler-core/slang-artifact-impl.cpp b/source/compiler-core/slang-artifact-impl.cpp
index 056d89a4b..bec28f3eb 100644
--- a/source/compiler-core/slang-artifact-impl.cpp
+++ b/source/compiler-core/slang-artifact-impl.cpp
@@ -77,10 +77,18 @@ bool Artifact::exists()
return false;
}
-SlangResult Artifact::requireFile(Keep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
+SlangResult Artifact::requireFile(Keep keep, IOSFileArtifactRepresentation** outFileRep)
{
auto handler = _getHandler();
- return handler->getOrCreateFileRepresentation(this, keep, fileSystem, outFileRep);
+
+ ComPtr<ICastable> castable;
+ SLANG_RETURN_ON_FAIL(handler->getOrCreateRepresentation(this, IOSFileArtifactRepresentation::getTypeGuid(), keep, castable.writeRef()));
+
+ auto fileRep = as<IOSFileArtifactRepresentation>(castable);
+ fileRep->addRef();
+
+ *outFileRep = fileRep;
+ return SLANG_OK;
}
SlangResult Artifact::loadSharedLibrary(ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary)
@@ -90,7 +98,7 @@ SlangResult Artifact::loadSharedLibrary(ArtifactKeep keep, ISlangSharedLibrary**
ComPtr<ICastable> castable;
SLANG_RETURN_ON_FAIL(handler->getOrCreateRepresentation(this, ISlangSharedLibrary::getTypeGuid(), keep, castable.writeRef()));
- ISlangSharedLibrary* lib = as<ISlangSharedLibrary>(castable);
+ auto lib = as<ISlangSharedLibrary>(castable);
lib->addRef();
*outSharedLibrary = lib;
diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h
index 9901b9d63..b59c700d8 100644
--- a/source/compiler-core/slang-artifact-impl.h
+++ b/source/compiler-core/slang-artifact-impl.h
@@ -43,7 +43,7 @@ public:
virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadBlob(Keep keep, ISlangBlob** outBlob) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, IOSFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE;
virtual SLANG_NO_THROW const char* SLANG_MCALL getName() SLANG_OVERRIDE { return m_name.getBuffer(); }
diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp
index 4e33f2f0c..9a5c13311 100644
--- a/source/compiler-core/slang-artifact-representation-impl.cpp
+++ b/source/compiler-core/slang-artifact-representation-impl.cpp
@@ -13,32 +13,87 @@
namespace Slang {
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ExtFileArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ExtFileArtifactRepresentation::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IArtifactRepresentation::getTypeGuid() ||
+ guid == IPathArtifactRepresentation::getTypeGuid() ||
+ guid == IExtFileArtifactRepresentation::getTypeGuid())
+ {
+ return static_cast<IPathArtifactRepresentation*>(this);
+ }
+ return nullptr;
+}
+
+void* ExtFileArtifactRepresentation::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+void* ExtFileArtifactRepresentation::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+SlangResult ExtFileArtifactRepresentation::createRepresentation(const Guid& typeGuid, ICastable** outCastable)
+{
+ // We can convert into a blob only, and only if we have a path
+ // If it's referenced by a name only, it's a file that *can't* be loaded as a blob in general.
+ if (typeGuid != ISlangBlob::getTypeGuid())
+ {
+ return SLANG_E_NOT_AVAILABLE;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(m_fileSystem->loadFile(m_path.getBuffer(), blob.writeRef()));
+
+ *outCastable = CastableUtil::getCastable(blob).detach();
+ return SLANG_OK;
+}
+
+bool ExtFileArtifactRepresentation::exists()
+{
+ SlangPathType pathType;
+ const auto res = m_fileSystem->getPathType(m_path.getBuffer(), &pathType);
+ // It exists if it is a file
+ return SLANG_SUCCEEDED(res) && pathType == getPathType();
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FileArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */
-void* FileArtifactRepresentation::getInterface(const Guid& guid)
+void* OSFileArtifactRepresentation::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ICastable::getTypeGuid() ||
guid == IArtifactRepresentation::getTypeGuid() ||
- guid == IFileArtifactRepresentation::getTypeGuid())
+ guid == IPathArtifactRepresentation::getTypeGuid() ||
+ guid == IOSFileArtifactRepresentation::getTypeGuid())
{
- return static_cast<IFileArtifactRepresentation*>(this);
+ return static_cast<IOSFileArtifactRepresentation*>(this);
}
return nullptr;
}
-void* FileArtifactRepresentation::getObject(const Guid& guid)
+void* OSFileArtifactRepresentation::getObject(const Guid& guid)
{
SLANG_UNUSED(guid);
return nullptr;
}
-ISlangMutableFileSystem* FileArtifactRepresentation::_getFileSystem()
+/* static */ISlangMutableFileSystem* OSFileArtifactRepresentation::_getFileSystem()
{
- return m_fileSystem ? m_fileSystem : OSFileSystem::getMutableSingleton();
+ return OSFileSystem::getMutableSingleton();
}
-void* FileArtifactRepresentation::castAs(const Guid& guid)
+void* OSFileArtifactRepresentation::castAs(const Guid& guid)
{
if (auto intf = getInterface(guid))
{
@@ -47,7 +102,7 @@ void* FileArtifactRepresentation::castAs(const Guid& guid)
return getObject(guid);
}
-SlangResult FileArtifactRepresentation::createRepresentation(const Guid& typeGuid, ICastable** outCastable)
+SlangResult OSFileArtifactRepresentation::createRepresentation(const Guid& typeGuid, ICastable** outCastable)
{
// We can convert into a blob only, and only if we have a path
// If it's referenced by a name only, it's a file that *can't* be loaded as a blob in general.
@@ -66,7 +121,7 @@ SlangResult FileArtifactRepresentation::createRepresentation(const Guid& typeGui
return SLANG_OK;
}
-bool FileArtifactRepresentation::exists()
+bool OSFileArtifactRepresentation::exists()
{
// TODO(JS):
// If it's a name only it's hard to know what exists should do. It can't *check* because it relies on the 'system' doing
@@ -86,7 +141,7 @@ bool FileArtifactRepresentation::exists()
return SLANG_SUCCEEDED(res) && pathType == SLANG_PATH_TYPE_FILE;
}
-void FileArtifactRepresentation::disown()
+void OSFileArtifactRepresentation::disown()
{
if (_isOwned())
{
@@ -94,7 +149,7 @@ void FileArtifactRepresentation::disown()
}
}
-FileArtifactRepresentation::~FileArtifactRepresentation()
+OSFileArtifactRepresentation::~OSFileArtifactRepresentation()
{
if (_isOwned())
{
diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h
index 4ccd9062c..da21e30bc 100644
--- a/source/compiler-core/slang-artifact-representation-impl.h
+++ b/source/compiler-core/slang-artifact-representation-impl.h
@@ -14,10 +14,10 @@ namespace Slang
{
/* A representation of an artifact that is held in a file */
-class FileArtifactRepresentation : public ComBaseObject, public IFileArtifactRepresentation
+class OSFileArtifactRepresentation : public ComBaseObject, public IOSFileArtifactRepresentation
{
public:
- typedef FileArtifactRepresentation ThisType;
+ typedef OSFileArtifactRepresentation ThisType;
SLANG_COM_BASE_IUNKNOWN_ALL
@@ -28,26 +28,27 @@ public:
SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE;
SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
- // IFileArtifactRepresentation
- virtual SLANG_NO_THROW Kind SLANG_MCALL getKind() SLANG_OVERRIDE { return m_kind; }
+ // IPathArtifactRepresentation
virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() SLANG_OVERRIDE { return m_path.getBuffer(); }
- virtual SLANG_NO_THROW ISlangMutableFileSystem* SLANG_MCALL getFileSystem() SLANG_OVERRIDE { return m_fileSystem; }
+ virtual SLANG_NO_THROW SlangPathType SLANG_MCALL getPathType() SLANG_OVERRIDE { return SLANG_PATH_TYPE_FILE; }
+
+ // IOSFileArtifactRepresentation
+ virtual SLANG_NO_THROW Kind SLANG_MCALL getKind() SLANG_OVERRIDE { return m_kind; }
virtual SLANG_NO_THROW void SLANG_MCALL disown() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IFileArtifactRepresentation* SLANG_MCALL getLockFile() SLANG_OVERRIDE { return m_lockFile; }
+ virtual SLANG_NO_THROW IOSFileArtifactRepresentation* SLANG_MCALL getLockFile() SLANG_OVERRIDE { return m_lockFile; }
- FileArtifactRepresentation(Kind kind, const UnownedStringSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem):
+ OSFileArtifactRepresentation(Kind kind, const UnownedStringSlice& path, IOSFileArtifactRepresentation* lockFile):
m_kind(kind),
m_lockFile(lockFile),
- m_path(path),
- m_fileSystem(fileSystem)
+ m_path(path)
{
}
- ~FileArtifactRepresentation();
+ ~OSFileArtifactRepresentation();
- static ComPtr<IFileArtifactRepresentation> create(Kind kind, const UnownedStringSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem)
+ static ComPtr<IOSFileArtifactRepresentation> create(Kind kind, const UnownedStringSlice& path, IOSFileArtifactRepresentation* lockFile)
{
- return ComPtr<IFileArtifactRepresentation>(new ThisType(kind, path, lockFile, fileSystem));
+ return ComPtr<IOSFileArtifactRepresentation>(new ThisType(kind, path, lockFile));
}
protected:
@@ -57,14 +58,54 @@ protected:
/// True if the file is owned
bool _isOwned() const { return Index(m_kind) >= Index(Kind::Owned); }
- ISlangMutableFileSystem* _getFileSystem();
+ static ISlangMutableFileSystem* _getFileSystem();
Kind m_kind;
String m_path;
- ComPtr<IFileArtifactRepresentation> m_lockFile;
+ ComPtr<IOSFileArtifactRepresentation> m_lockFile;
ComPtr<ISlangMutableFileSystem> m_fileSystem;
};
+class ExtFileArtifactRepresentation : public ComBaseObject, public IExtFileArtifactRepresentation
+{
+public:
+ typedef ExtFileArtifactRepresentation ThisType;
+
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactRepresentation
+ SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE;
+ SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
+
+ // IPathArtifactRepresentation
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() SLANG_OVERRIDE { return m_path.getBuffer(); }
+ virtual SLANG_NO_THROW SlangPathType SLANG_MCALL getPathType() SLANG_OVERRIDE { return SLANG_PATH_TYPE_FILE; }
+
+ // IExtFileArtifactRepresentation
+ virtual SLANG_NO_THROW ISlangFileSystemExt* SLANG_MCALL getFileSystem() SLANG_OVERRIDE { return m_fileSystem; }
+
+ ExtFileArtifactRepresentation(const UnownedStringSlice& path, ISlangFileSystemExt* fileSystem) :
+ m_path(path),
+ m_fileSystem(fileSystem)
+ {
+ }
+
+ static ComPtr<IExtFileArtifactRepresentation> create(const UnownedStringSlice& path, ISlangFileSystemExt* fileSystem)
+ {
+ return ComPtr<IExtFileArtifactRepresentation>(new ThisType(path, fileSystem));
+ }
+
+protected:
+ void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
+
+ String m_path;
+ ComPtr<ISlangFileSystemExt> m_fileSystem;
+};
+
/* This allows wrapping any object to be an artifact representation.
NOTE! Only allows casting from a single guid. Passing a RefObject across an ABI bounday remains risky!
diff --git a/source/compiler-core/slang-artifact-representation.h b/source/compiler-core/slang-artifact-representation.h
index 32945b0be..a345d762b 100644
--- a/source/compiler-core/slang-artifact-representation.h
+++ b/source/compiler-core/slang-artifact-representation.h
@@ -7,23 +7,34 @@
namespace Slang
{
-/*
-A representation as a file.
+/* Base interface for types that have a path. */
+class IPathArtifactRepresentation : public IArtifactRepresentation
+{
+ SLANG_COM_INTERFACE(0xcb1c188c, 0x7e48, 0x43eb, { 0xb0, 0x9a, 0xa1, 0x6e, 0xef, 0xd4, 0x9b, 0xef });
+
+ /// The path
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() = 0;
+ /// Get type
+ virtual SLANG_NO_THROW SlangPathType SLANG_MCALL getPathType() = 0;
+};
-A file representation does not have to be a file on the OS file system, and might specify a file
-contained in a virtual file system represented by ISlangMutableFileSystem.
+/* Represents a path to a file held on an ISlangFileSystem. */
+class IExtFileArtifactRepresentation : public IPathArtifactRepresentation
+{
+ SLANG_COM_INTERFACE(0xacd65576, 0xb09d, 0x4ac9, { 0xa5, 0x93, 0xeb, 0xf8, 0x9b, 0xd7, 0x11, 0xfd });
-If `getFileSystem()` returns nullptr, then the path does specify a file on the regular OS file system otherwise
-the path specifies the file contained in the virtual file system.
+ /// File system that holds the item along the path.
+ virtual SLANG_NO_THROW ISlangFileSystemExt* SLANG_MCALL getFileSystem() = 0;
+};
-This distinction is important as it is sometimes necessary to have an artifact stored on the OS file system
-to be usable. */
-class IFileArtifactRepresentation : public IArtifactRepresentation
+/*
+A representation as a file on the OS file system. */
+class IOSFileArtifactRepresentation : public IPathArtifactRepresentation
{
public:
SLANG_COM_INTERFACE(0xc7d7d3a4, 0x8683, 0x44b5, { 0x87, 0x96, 0xdf, 0xba, 0x9b, 0xc3, 0xf1, 0x7b });
- /* Determines ownership and other characteristics of the 'file' */
+ /* Determines ownership and other characteristics of the OS 'file' */
enum class Kind
{
Reference, ///< References a file on the file system
@@ -32,18 +43,14 @@ public:
Lock, ///< An owned type, indicates potentially in part may only exist to 'lock' a path for a temporary file. Other files might exists based on the 'lock' path.
CountOf,
};
-
+
/// The the kind of file.
virtual SLANG_NO_THROW Kind SLANG_MCALL getKind() = 0;
- /// The path (on the file system)
- virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() = 0;
- /// Optional, the file system it's on. If nullptr its on the 'regular' OS file system.
- virtual SLANG_NO_THROW ISlangMutableFileSystem* SLANG_MCALL getFileSystem() = 0;
/// Makes the file no longer owned. Only applicable for Owned/Lock and they will become 'Reference'
virtual SLANG_NO_THROW void SLANG_MCALL disown() = 0;
/// Gets the 'lock file' if any associated with this file. Returns nullptr if there isn't one.
/// If this file is based on a 'lock file', the lock file must stay in scope at least as long as this does.
- virtual SLANG_NO_THROW IFileArtifactRepresentation* SLANG_MCALL getLockFile() = 0;
+ virtual SLANG_NO_THROW IOSFileArtifactRepresentation* SLANG_MCALL getLockFile() = 0;
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index 047e87db0..413bd5efe 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -95,124 +95,55 @@ namespace Slang {
return artifact->findArtifactByPredicate(IArtifact::FindStyle::SelfOrChildren, &ArtifactUtil::isSignificant, nullptr);
}
-/* static */String ArtifactUtil::getBaseName(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep);
- }
- // Else use the name
- return artifact->getName();
-}
-
-/* static */String ArtifactUtil::getParentPath(IFileArtifactRepresentation* fileRep)
-{
- UnownedStringSlice path(fileRep->getPath());
- return Path::getParentDirectory(path);
-}
-
-/* static */String ArtifactUtil::getParentPath(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return getParentPath(fileRep);
- }
- return String();
-}
-
-/* static */IFileArtifactRepresentation* ArtifactUtil::findFileSystemTemporaryFile(IArtifact* artifact)
-{
- if (auto fileRep = findFileSystemFile(artifact))
- {
- return fileRep->getLockFile() ? fileRep : nullptr;
- }
- return nullptr;
-}
-
-/* static */IFileArtifactRepresentation* ArtifactUtil::findFileSystemFile(IArtifact* artifact)
+UnownedStringSlice ArtifactUtil::findPath(IArtifact* artifact)
{
- for (auto rep : artifact->getRepresentations())
+ // If a name is set we'll just use that
{
- if (auto fileSystemRep = as<IFileArtifactRepresentation>(rep))
+ const UnownedStringSlice name(artifact->getName());
+ if (name.getLength())
{
- if (fileSystemRep->getFileSystem() == nullptr)
- {
- return fileSystemRep;
- }
+ return name;
}
}
- return nullptr;
-}
-/* static */IFileArtifactRepresentation* ArtifactUtil::findFileSystemPrimaryFile(IArtifact* artifact)
-{
+ IPathArtifactRepresentation* bestRep = nullptr;
+
+ // Look for a rep with a path. Prefer IExtFile because a IOSFile might be a temporary file
for (auto rep : artifact->getRepresentations())
{
- if (auto fileRep = as<IFileArtifactRepresentation>(rep))
+ if (auto pathRep = as<IPathArtifactRepresentation>(rep))
{
- // If it has a file system it's not on OS
- // If it has a lock file it can be assumed to be temporary
- if (fileRep->getFileSystem() != nullptr ||
- fileRep->getLockFile())
- {
- continue;
- }
-
- // If it's a file that is persistant it will just be a reference to a pre-existing file
- const auto kind = fileRep->getKind();
- if (kind != IFileArtifactRepresentation::Kind::Reference)
+ if (pathRep->getPathType() == SLANG_PATH_TYPE_FILE &&
+ (bestRep == nullptr || as<IExtFileArtifactRepresentation>(rep)))
{
- continue;
+ bestRep = pathRep;
}
-
- return fileRep;
}
}
- return nullptr;
+
+ const UnownedStringSlice name = bestRep ? UnownedStringSlice(bestRep->getPath()) : UnownedStringSlice();
+ return name.getLength() ? name : UnownedStringSlice();
}
-UnownedStringSlice ArtifactUtil::findPath(IArtifact* artifact)
+/* static */UnownedStringSlice ArtifactUtil::inferExtension(IArtifact* artifact)
{
- // If a name is set we'll just use that
- {
- const char* name = artifact->getName();
- if (name && name[0] != 0)
- {
- return UnownedStringSlice(name);
- }
- }
-
- // Find the *first* file rep and use it's path.
- // This may not be the file on the file system - but is probably the path/name the user most associated with the artifact
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ const UnownedStringSlice path = findPath(artifact);
+ if (path.getLength())
{
- // If there isn't a lock file it is
- if (fileRep->getLockFile() == nullptr)
+ auto ext = Path::getPathExt(UnownedStringSlice(path));
+ if (ext.getLength())
{
- return UnownedStringSlice(fileRep->getPath());
+ return ext;
}
}
-
return UnownedStringSlice();
}
-/* static */UnownedStringSlice ArtifactUtil::inferExtension(IArtifact* artifact)
+/* static */UnownedStringSlice ArtifactUtil::findName(IArtifact* artifact)
{
- for (auto rep :artifact->getRepresentations())
- {
- if (auto fileRep = as<IFileArtifactRepresentation>(rep))
- {
- const char* path = fileRep->getPath();
- auto ext = Path::getPathExt(UnownedStringSlice(path));
- if (ext.getLength())
- {
- return ext;
- }
- }
- }
-
- // Okay lets see if the name has an extension
- return Path::getPathExt(UnownedStringSlice(artifact->getName()));
+ const UnownedStringSlice path = findPath(artifact);
+ const Index pos = Path::findLastSeparatorIndex(path);
+ return (pos >= 0) ? path.tail(pos + 1) : path;
}
static SlangResult _calcInferred(IArtifact* artifact, const UnownedStringSlice& basePath, StringBuilder& outPath)
diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h
index 16687d6a9..70b736828 100644
--- a/source/compiler-core/slang-artifact-util.h
+++ b/source/compiler-core/slang-artifact-util.h
@@ -10,16 +10,6 @@ namespace Slang
struct ArtifactUtil
{
- /// Get the base name of this artifact.
- /// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
- /// Else if there is an explicit name set, this is returned.
- /// Else returns the empty string
- static String getBaseName(IArtifact* artifact);
-
- /// Get the parent path (empty if there isn't one)
- static String getParentPath(IArtifact* artifact);
- static String getParentPath(IFileArtifactRepresentation* fileRep);
-
/// Create an empty container which is compatible with the desc
static ComPtr<IArtifactContainer> createContainer(const ArtifactDesc& desc);
@@ -38,20 +28,14 @@ struct ArtifactUtil
/// Find a significant artifact
static IArtifact* findSignificant(IArtifact* artifact);
- /// Returns the rep of the artifact that contains a temporary (identified by having a lock) on
- /// the OS file system
- static IFileArtifactRepresentation* findFileSystemTemporaryFile(IArtifact* artifact);
- /// Returns true if the artifact contains a file on the OS file system
- static IFileArtifactRepresentation* findFileSystemFile(IArtifact* artifact);
- /// Returns the rep of a file system file which *isn't* temporary
- static IFileArtifactRepresentation* findFileSystemPrimaryFile(IArtifact* artifact);
-
/// Find the path/name associated with the artifact.
/// The path is *not* necessarily the path on the file system. The order of search is
/// * If the artifact has a name return that
- /// * If the artifact has a IFileArtifactRepresentation (that isn't temporary) return it's path
+ /// * If the artifact has a IPathFileArtifactRepresentation (that isn't temporary) return it's path
/// * If not found return an empty slice
static UnownedStringSlice findPath(IArtifact* artifact);
+ /// Find a name
+ static UnownedStringSlice findName(IArtifact* artifact);
/// Sometimes we have artifacts that don't specify a payload type - perhaps because they can be interpretted in different ways
/// This function uses the associated name and file representations to infer a extension. If none is found returns an empty slice.
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index 672e8d8d4..222b902a5 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -275,7 +275,9 @@ inline /* static */ArtifactDesc ArtifactDesc::make(Packed inPacked)
}
// Forward declare
-class IFileArtifactRepresentation;
+class IOSFileArtifactRepresentation;
+class IPathArtifactRepresentation;
+
class IArtifactRepresentation;
// Controls what items can be kept.
@@ -376,7 +378,7 @@ public:
/// Require artifact is available as a file.
/// NOTE! May need to serialize and write as a temporary file.
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, IOSFileArtifactRepresentation** outFileRep) = 0;
/// Load the artifact as a shared library
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary) = 0;
@@ -500,8 +502,6 @@ class IArtifactHandler : public ICastable
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) = 0;
/// Given an artifact gets or creates a representation.
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) = 0;
- /// Given an artifact gets a represenation of it on the file system.
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) = 0;
};
} // namespace Slang
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp
index f665757bb..104f1e631 100644
--- a/source/compiler-core/slang-downstream-compiler.cpp
+++ b/source/compiler-core/slang-downstream-compiler.cpp
@@ -82,7 +82,7 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
auto artifactList = CastableList::create();
// It may be necessary to produce a temporary file 'lock file'.
- ComPtr<IFileArtifactRepresentation> lockFile;
+ ComPtr<IOSFileArtifactRepresentation> lockFile;
// The allocator can be used for items that are not kept in scope by the options
String modulePath;
@@ -92,7 +92,7 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
{
// We could use the path to the source, or use the source name/paths as defined on the artifact
// For now we just go with a lock file based on "slang-generated".
- SLANG_RETURN_ON_FAIL(helper->createLockFile("slang-generated", nullptr, lockFile.writeRef()));
+ SLANG_RETURN_ON_FAIL(helper->createLockFile(asCharSlice(toSlice("slang-generated")), lockFile.writeRef()));
auto lockArtifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::Lock, ArtifactStyle::None));
lockArtifact->addRepresentation(lockFile);
@@ -108,8 +108,8 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
// Append command line args to the end of cmdLine using the target specific function for the specified options
SLANG_RETURN_ON_FAIL(calcArgs(options, cmdLine));
- // The 'mainArtifact' is the main product produced from the compilation - the executable/sharedlibrary/object etc
- ComPtr<IArtifact> mainArtifact;
+ // The 'productArtifact' is the main product produced from the compilation - the executable/sharedlibrary/object etc
+ ComPtr<IArtifact> productArtifact;
{
List<ComPtr<IArtifact>> artifacts;
SLANG_RETURN_ON_FAIL(calcCompileProducts(options, DownstreamProductFlag::All, lockFile, artifacts));
@@ -119,17 +119,17 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
// The main artifact must be in the list, so add it if we find it
if (artifact->getDesc() == targetDesc)
{
- SLANG_ASSERT(mainArtifact == nullptr);
- mainArtifact = artifact;
+ SLANG_ASSERT(productArtifact == nullptr);
+ productArtifact = artifact;
}
artifactList->add(artifact);
}
}
- SLANG_ASSERT(mainArtifact);
+ SLANG_ASSERT(productArtifact);
// Somethings gone wrong if we don't find the main artifact
- if (!mainArtifact)
+ if (!productArtifact)
{
return SLANG_FAIL;
}
@@ -166,15 +166,15 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
{
// We should find a file rep and if we do we can disown it. Disowning will mean
// when scope is lost the rep won't try and delete the (apparently non existing) backing file.
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ if (auto fileRep = findRepresentation<IOSFileArtifactRepresentation>(artifact))
{
fileRep->disown();
}
// If the main artifact doesn't exist, we don't have a main artifact
- if (artifact == mainArtifact)
+ if (artifact == productArtifact)
{
- mainArtifact.setNull();
+ productArtifact.setNull();
}
// Remove from the list
@@ -188,9 +188,13 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
// Add all of the source artifacts, that are temporary on the file system, such that they can stay in scope for debugging
for (auto sourceArtifact : options.sourceArtifacts)
{
- if (ArtifactUtil::findFileSystemTemporaryFile(sourceArtifact) && sourceArtifact->exists())
+ if (auto fileRep = findRepresentation<IOSFileArtifactRepresentation>(sourceArtifact))
{
- artifactList->add(sourceArtifact);
+ // If it has a lock file we can assume it's a temporary
+ if (fileRep->getLockFile())
+ {
+ artifactList->add(sourceArtifact);
+ }
}
}
@@ -207,7 +211,7 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
// Find the rep from the 'main' artifact, we'll just use the same representation on the output
// artifact. Sharing is desirable, because the rep owns the file.
- if (auto fileRep = mainArtifact ? findRepresentation<IFileArtifactRepresentation>(mainArtifact) : nullptr)
+ if (auto fileRep = productArtifact ? findRepresentation<IOSFileArtifactRepresentation>(productArtifact) : nullptr)
{
artifact->addRepresentation(fileRep);
}
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index a9ef56221..a543f8e46 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -235,7 +235,7 @@ public:
/// Given options determines the paths to products produced (including the 'moduleFilePath').
/// Note that does *not* guarentee all products were or should be produced. Just aims to include all that could
/// be produced, such that can be removed on completion.
- virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) = 0;
+ virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) = 0;
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) = 0;
virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) = 0;
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 03ad868a8..c92eea47b 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -86,7 +86,7 @@ static UnownedStringSlice _addName(const UnownedStringSlice& inSlice, StringSlic
static UnownedStringSlice _addName(IArtifact* artifact, StringSlicePool& pool)
{
- return _addName(ArtifactUtil::getBaseName(artifact).getUnownedSlice(), pool);
+ return _addName(ArtifactUtil::findName(artifact), pool);
}
class DxcIncludeHandler : public IDxcIncludeHandler
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 8851477d7..f003ffb0f 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -432,7 +432,7 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
return SLANG_OK;
}
-/* static */SlangResult GCCDownstreamCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
+/* static */SlangResult GCCDownstreamCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
{
SLANG_ASSERT(options.modulePath.count);
@@ -444,7 +444,7 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
const auto desc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType);
SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, asStringSlice(options.modulePath), builder));
- auto fileRep = FileArtifactRepresentation::create(IFileArtifactRepresentation::Kind::Owned, builder.getUnownedSlice(), lockFile, nullptr);
+ auto fileRep = OSFileArtifactRepresentation::create(IOSFileArtifactRepresentation::Kind::Owned, builder.getUnownedSlice(), lockFile);
auto artifact = ArtifactUtil::createArtifact(desc);
artifact->addRepresentation(fileRep);
@@ -615,11 +615,11 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
// Files to compile, need to be on the file system.
for (IArtifact* sourceArtifact : options.sourceArtifacts)
{
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
// TODO(JS):
// Do we want to keep the file on the file system? It's probably reasonable to do so.
- SLANG_RETURN_ON_FAIL(sourceArtifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
+ SLANG_RETURN_ON_FAIL(sourceArtifact->requireFile(ArtifactKeep::Yes, fileRep.writeRef()));
cmdLine.addArg(fileRep->getPath());
}
@@ -644,13 +644,15 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
// If it's a library for CPU types, try and use it
if (ArtifactDescUtil::isCpuBinary(artifactDesc) && artifactDesc.kind == ArtifactKind::Library)
{
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
// Get the name and path (can be empty) to the library
- SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
+ SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, fileRep.writeRef()));
- libPathPool.add(ArtifactUtil::getParentPath(fileRep));
- cmdLine.addPrefixPathArg("-l", ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep));
+ const UnownedStringSlice path(fileRep->getPath());
+ libPathPool.add(Path::getParentDirectory(path));
+
+ cmdLine.addPrefixPathArg("-l", ArtifactDescUtil::getBaseNameFromPath(artifact->getDesc(), path));
}
}
diff --git a/source/compiler-core/slang-gcc-compiler-util.h b/source/compiler-core/slang-gcc-compiler-util.h
index 8791930bb..6afb39ec6 100644
--- a/source/compiler-core/slang-gcc-compiler-util.h
+++ b/source/compiler-core/slang-gcc-compiler-util.h
@@ -22,7 +22,7 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerUtilBase
static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics);
/// Given options, calculate paths to products/files produced for a compilation
- static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts);
+ static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts);
/// Given the exe location, creates a DownstreamCompiler.
/// Note! Invoke/s the compiler to determine the compiler version number.
@@ -44,7 +44,7 @@ public:
// CommandLineCPPCompiler impl - just forwards to the Util
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); }
virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); }
- virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, flags, lockFile, outArtifacts); }
+ virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, flags, lockFile, outArtifacts); }
GCCDownstreamCompiler(const Desc& desc):Super(desc) {}
};
diff --git a/source/compiler-core/slang-include-system.cpp b/source/compiler-core/slang-include-system.cpp
index 455ecde2b..9cd193ec6 100644
--- a/source/compiler-core/slang-include-system.cpp
+++ b/source/compiler-core/slang-include-system.cpp
@@ -132,7 +132,7 @@ SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>
sourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, sourceFile);
- sourceFile->maybeAddArtifact(m_fileSystemExt);
+ sourceFile->maybeAddArtifact(nullptr, m_fileSystemExt);
outBlob = foundSourceBlob;
return SLANG_OK;
@@ -152,7 +152,7 @@ SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>
}
sourceFile->setContents(foundSourceBlob);
- sourceFile->maybeAddArtifact(m_fileSystemExt);
+ sourceFile->maybeAddArtifact(nullptr, m_fileSystemExt);
outBlob = foundSourceBlob;
return SLANG_OK;
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp
index c82636248..6b4c5654d 100644
--- a/source/compiler-core/slang-source-loc.cpp
+++ b/source/compiler-core/slang-source-loc.cpp
@@ -6,6 +6,8 @@
#include "slang-artifact-representation-impl.h"
#include "slang-artifact-impl.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-desc-util.h"
namespace Slang {
@@ -432,69 +434,61 @@ String SourceFile::calcVerbosePath() const
return m_pathInfo.foundPath;
}
-void SourceFile::maybeAddArtifact(ISlangFileSystemExt* ext)
+void SourceFile::maybeAddArtifact(const ArtifactDesc* inArtifactDesc, ISlangFileSystemExt* ext)
{
if (!m_contentBlob)
{
return;
}
- // If there already is an artifact, or we are not using OSFile system then
+ // If there already is an artifact, we don't need to create one
if (m_artifact)
{
- // TODO(JS):
- // Check if it has the blob or not
+ // Check it has a blob and the blob is the same as the content blob
SLANG_ASSERT(m_contentBlob == findRepresentation<ISlangBlob>(m_artifact));
return;
}
- // We don't know how the source will be used
- m_artifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Unknown, ArtifactStyle::Unknown));
+ ArtifactDesc artifactDesc;
- // Add the blob as a representation.
- m_artifact->addRepresentationUnknown(m_contentBlob);
-
- // If we have the file system see if we can set up a path too
- if (ext)
+ if (inArtifactDesc)
{
- const auto osPathKind = ext->getOSPathKind();
+ artifactDesc = *inArtifactDesc;
+ }
+ else
+ {
+ // Set the default
+ artifactDesc = ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Unknown, ArtifactStyle::Unknown);
- if (osPathKind != OSPathKind::None)
+ // Let's work out from the
+ // We could try and work it out
+ if (getPathInfo().foundPath.getLength())
{
- String path;
- switch (osPathKind)
- {
- case OSPathKind::Canonical:
- {
- // Get the canonical path
- ComPtr<ISlangBlob> canonicalPath;
- if (SLANG_SUCCEEDED(ext->getCanonicalPath(getPathInfo().foundPath.getBuffer(), canonicalPath.writeRef())))
- {
- path = StringUtil::getString(canonicalPath);
- }
- break;
- }
- case OSPathKind::Direct:
- {
- path = getPathInfo().foundPath;
- break;
- }
- }
+ // Let's work out what kind of source it is from the this
+ auto desc = ArtifactDescUtil::getDescFromPath(getPathInfo().foundPath.getUnownedSlice());
- if (path.getLength())
+ // If found something just use that
+ if (desc.kind == ArtifactKind::Source)
{
- // We can sanity check that this works
- SlangPathType pathType;
- if (SLANG_SUCCEEDED(ext->getPathType(path.getBuffer(), &pathType)))
- {
- // We can add a file representation
- FileArtifactRepresentation* fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice(), nullptr, nullptr);
- m_artifact->addRepresentation(fileRep);
- }
+ artifactDesc = desc;
}
}
}
+ // We don't know how the source will be used
+ m_artifact = Artifact::create(artifactDesc);
+
+ // Add the blob as a representation.
+ m_artifact->addRepresentationUnknown(m_contentBlob);
+
+ // If we have the file system, set up the rep to that
+ if (ext)
+ {
+ // Add the representation on the file system
+ auto extRep = new ExtFileArtifactRepresentation(getPathInfo().foundPath.getUnownedSlice(), ext);
+ m_artifact->addRepresentation(extRep);
+ }
+
// Get the name
auto name = getPathInfo().getName();
if (name.getLength())
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h
index 461f09e96..29ed9dfbb 100644
--- a/source/compiler-core/slang-source-loc.h
+++ b/source/compiler-core/slang-source-loc.h
@@ -246,8 +246,9 @@ public:
/// Set the content as a string
void setContents(const String& content);
- /// If artifact isn't defined will try and associate one. The pathInfo must be the one associated with the PathInfo
- void maybeAddArtifact(ISlangFileSystemExt* ext);
+ /// If the desc isn't set, will use Unknown source type
+ /// If artifact isn't defined will try and associate one.
+ void maybeAddArtifact(const ArtifactDesc* desc, ISlangFileSystemExt* ext);
/// Calculate a display path -> can canonicalize if necessary
String calcVerbosePath() const;
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp
index 17fb96ee8..2d5b37c50 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.cpp
+++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp
@@ -21,16 +21,16 @@
namespace Slang
{
-static void _addFile(const String& path, const ArtifactDesc& desc, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
+static void _addFile(const String& path, const ArtifactDesc& desc, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
{
- auto fileRep = FileArtifactRepresentation::create(IFileArtifactRepresentation::Kind::Owned, path.getUnownedSlice(), lockFile, nullptr);
+ auto fileRep = OSFileArtifactRepresentation::create(IOSFileArtifactRepresentation::Kind::Owned, path.getUnownedSlice(), lockFile);
auto artifact = ArtifactUtil::createArtifact(desc);
artifact->addRepresentation(fileRep);
outArtifacts.add(artifact);
}
-/* static */SlangResult VisualStudioCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
+/* static */SlangResult VisualStudioCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts)
{
SLANG_ASSERT(options.modulePath.count);
@@ -238,11 +238,11 @@ static void _addFile(const String& path, const ArtifactDesc& desc, IFileArtifact
// Files to compile, need to be on the file system.
for (IArtifact* sourceArtifact : options.sourceArtifacts)
{
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
// TODO(JS):
// Do we want to keep the file on the file system? It's probably reasonable to do so.
- SLANG_RETURN_ON_FAIL(sourceArtifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
+ SLANG_RETURN_ON_FAIL(sourceArtifact->requireFile(ArtifactKeep::Yes, fileRep.writeRef()));
cmdLine.addArg(fileRep->getPath());
}
@@ -264,12 +264,13 @@ static void _addFile(const String& path, const ArtifactDesc& desc, IFileArtifact
if (ArtifactDescUtil::isCpuBinary(desc) && desc.kind == ArtifactKind::Library)
{
// Get the libray name and path
- ComPtr<IFileArtifactRepresentation> fileRep;
- SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
+ SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, fileRep.writeRef()));
- libPathPool.add(ArtifactUtil::getParentPath(fileRep));
+ const UnownedStringSlice path(fileRep->getPath());
+ libPathPool.add(Path::getParentDirectory(path));
// We need the extension for windows
- cmdLine.addArg(ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep) + ".lib");
+ cmdLine.addArg(ArtifactDescUtil::getBaseNameFromPath(desc, path) + ".lib");
}
}
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.h b/source/compiler-core/slang-visual-studio-compiler-util.h
index db9f9b7ac..fa1fb7c69 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.h
+++ b/source/compiler-core/slang-visual-studio-compiler-util.h
@@ -14,7 +14,7 @@ struct VisualStudioCompilerUtil : public DownstreamCompilerUtilBase
/// Parse Visual Studio exeRes into CPPCompiler::Output
static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* outOutput);
- static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts);
+ static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts);
static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
};
@@ -28,7 +28,7 @@ public:
// CommandLineDownstreamCompiler impl - just forwards to the Util
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); }
virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); }
- virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags productFlags, IFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, productFlags, lockFile, outArtifacts); }
+ virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags productFlags, IOSFileArtifactRepresentation* lockFile, List<ComPtr<IArtifact>>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, productFlags, lockFile, outArtifacts); }
VisualStudioDownstreamCompiler(const Desc& desc):Super(desc) {}
};
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 15a1ceb4b..ce380681e 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -1071,13 +1071,6 @@ namespace Slang
SourceFile* sourceFile = sourceFiles[0];
- // Make it have an artifact if doesn't have one already
- // This is useful because it will mean any reps will be kept in scope
- //
- // For example if file backing is needed, the file rep will last the lifetime of the
- // SourceFile
- sourceFile->maybeAddArtifact(nullptr);
-
sourceArtifact = sourceFile->getArtifact();
SLANG_ASSERT(sourceArtifact);
}
@@ -1258,7 +1251,7 @@ namespace Slang
// Set up the library artifact
auto artifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), toSlice("slang-rt"));
- ComPtr<IFileArtifactRepresentation> fileRep(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, toSlice("slang-rt"), nullptr, nullptr));
+ ComPtr<IOSFileArtifactRepresentation> fileRep(new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::NameOnly, toSlice("slang-rt"), nullptr));
artifact->addRepresentation(fileRep);
libraries.add(artifact);
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 3c17d1c09..4c6b0a6b1 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -3025,6 +3025,8 @@ SLANG_FORCE_INLINE EndToEndCompileRequest* asInternal(SlangCompileRequest* reque
SLANG_FORCE_INLINE SlangCompileTarget asExternal(CodeGenTarget target) { return (SlangCompileTarget)target; }
+SLANG_FORCE_INLINE SlangSourceLanguage asExternal(SourceLanguage sourceLanguage) { return (SlangSourceLanguage)sourceLanguage; }
+
}
#endif
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index f88f02221..a86cd5e6b 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -1491,15 +1491,15 @@ struct OptionsParser
// Seeing as on all targets the baseName doesn't have an extension, and all library types do
// if the name doesn't have an extension we can assume there is no path to it.
- ComPtr<IFileArtifactRepresentation> fileRep;
+ ComPtr<IOSFileArtifactRepresentation> fileRep;
if (Path::getPathExt(path).getLength() <= 0)
{
// If there is no extension *assume* it is the name of a system level library
- fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, path.getUnownedSlice(), nullptr, nullptr);
+ fileRep = new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::NameOnly, path.getUnownedSlice(), nullptr);
}
else
{
- fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice(), nullptr, nullptr);
+ fileRep = new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice(), nullptr);
if (!fileRep->exists())
{
sink->diagnose(referenceModuleName.loc, Diagnostics::libraryDoesNotExist, path);
diff --git a/source/slang/slang-preprocessor.cpp b/source/slang/slang-preprocessor.cpp
index f1f7cffa4..739860915 100644
--- a/source/slang/slang-preprocessor.cpp
+++ b/source/slang/slang-preprocessor.cpp
@@ -3058,7 +3058,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob);
auto fileSystemExt = context->m_preprocessor->fileSystem;
- sourceFile->maybeAddArtifact(fileSystemExt);
+ sourceFile->maybeAddArtifact(nullptr, fileSystemExt);
sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile);
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index a9868898e..a7a4fc8dc 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -2564,7 +2564,42 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile(
int translationUnitIndex,
SourceFile* sourceFile)
{
- translationUnits[translationUnitIndex]->addSourceFile(sourceFile);
+ auto translationUnit = translationUnits[translationUnitIndex];
+
+ // TODO(JS):
+ // The larger problem here is that a file on a file system *could* be interpretted in different ways.
+ // When the user supplies the source as a string, we use the source type specified for the translation unit.
+ //
+ // If it's on the file system it could be (say) compiled as HLSL or some other way. A *downstream* compiler
+ // that used the file system may care.
+ //
+ // We will assume here, that if it's loaded from the file system, it's path extension defines how it should be interpretted
+ // If that wasn't the case we'd have to either *copy*, or do some command line fiddling to tell it for the downstream compiler
+ // what the file is.
+
+ const auto& pathInfo = sourceFile->getPathInfo();
+ const auto pathType = pathInfo.type;
+
+ switch (pathType)
+ {
+ case PathInfo::Type::FromString:
+ {
+ // Set the artifact type from the the source language type
+ auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(translationUnit->sourceLanguage));
+ sourceFile->maybeAddArtifact(&sourceDesc, nullptr);
+ break;
+ }
+ case PathInfo::Type::FoundPath:
+ case PathInfo::Type::Normal:
+ {
+ // We'll *not* use the source for the artifact type. Doing so will lead to the type being determined via extension
+ sourceFile->maybeAddArtifact(nullptr, getLinkage()->getFileSystemExt());
+ break;
+ }
+ }
+
+ // Add the source file
+ translationUnit->addSourceFile(sourceFile);
}
void FrontEndCompileRequest::addTranslationUnitSourceBlob(
@@ -2575,8 +2610,6 @@ void FrontEndCompileRequest::addTranslationUnitSourceBlob(
// The path specified may or may not be a file path - mark as being constructed 'FromString'.
SourceFile* sourceFile = getSourceManager()->createSourceFileWithBlob(PathInfo::makeFromString(path), sourceBlob);
- sourceFile->maybeAddArtifact(nullptr);
-
addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
}
@@ -2588,8 +2621,6 @@ void FrontEndCompileRequest::addTranslationUnitSourceString(
// The path specified may or may not be a file path - mark as being constructed 'FromString'.
SourceFile* sourceFile = getSourceManager()->createSourceFileWithString(PathInfo::makeFromString(path), source);
- sourceFile->maybeAddArtifact(nullptr);
-
addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
}
@@ -2622,8 +2653,6 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile(
// Was loaded from the specified path
SourceFile* sourceFile = getSourceManager()->createSourceFileWithBlob(pathInfo, sourceBlob);
- sourceFile->maybeAddArtifact(getLinkage()->getFileSystemExt());
-
addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
}