summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-04-04 17:20:05 -0400
committerGitHub <noreply@github.com>2023-04-04 17:20:05 -0400
commit7bb2de1bc40e535fae93940113db97b5ea44a6f2 (patch)
treea70dcd1c4f97387ba7df482fefcd576c04543606
parent34a2fd593dd5a5d7b597b9d2fe20e39cc24b8e6c (diff)
Simplification around ArtifactRepresentation and unique identity (#2771)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP in handling artifacts/SourceFiles. * Add getUniqueIdentity to IPathArtifactRepresentation * Simplification because around using the representation to provide the uniqueIdentity.
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.cpp32
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.h8
-rw-r--r--source/compiler-core/slang-artifact-representation.h3
-rwxr-xr-xsource/slang/slang-compiler.h3
-rw-r--r--source/slang/slang.cpp122
5 files changed, 107 insertions, 61 deletions
diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp
index 3fae154bb..105402e6e 100644
--- a/source/compiler-core/slang-artifact-representation-impl.cpp
+++ b/source/compiler-core/slang-artifact-representation-impl.cpp
@@ -67,6 +67,21 @@ bool ExtFileArtifactRepresentation::exists()
return SLANG_SUCCEEDED(res) && pathType == getPathType();
}
+const char* ExtFileArtifactRepresentation::getUniqueIdentity()
+{
+ if (m_uniqueIdentity.getLength() == 0)
+ {
+ ComPtr<ISlangBlob> uniqueIdentityBlob;
+ if (SLANG_FAILED(m_fileSystem->getFileUniqueIdentity(m_path.getBuffer(), uniqueIdentityBlob.writeRef())))
+ {
+ return nullptr;
+ }
+ m_uniqueIdentity = StringUtil::getString(uniqueIdentityBlob);
+ }
+
+ return m_uniqueIdentity.getLength() ? m_uniqueIdentity.getBuffer() : nullptr;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SourceBlobWithPathArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* SourceBlobWithPathInfoArtifactRepresentation::getInterface(const Guid& guid)
@@ -187,6 +202,23 @@ bool OSFileArtifactRepresentation::exists()
return SLANG_SUCCEEDED(res) && pathType == SLANG_PATH_TYPE_FILE;
}
+const char* OSFileArtifactRepresentation::getUniqueIdentity()
+{
+ if (m_uniqueIdentity.getLength() == 0)
+ {
+ auto fileSystem = _getFileSystem();
+
+ ComPtr<ISlangBlob> uniqueIdentityBlob;
+ if (SLANG_FAILED(fileSystem->getFileUniqueIdentity(m_path.getBuffer(), uniqueIdentityBlob.writeRef())))
+ {
+ return nullptr;
+ }
+ m_uniqueIdentity = StringUtil::getString(uniqueIdentityBlob);
+ }
+
+ return m_uniqueIdentity.getLength() ? m_uniqueIdentity.getBuffer() : nullptr;
+}
+
void OSFileArtifactRepresentation::disown()
{
if (_isOwned())
diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h
index 4b6d49e06..5c76b9e7c 100644
--- a/source/compiler-core/slang-artifact-representation-impl.h
+++ b/source/compiler-core/slang-artifact-representation-impl.h
@@ -33,6 +33,7 @@ public:
// 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; }
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getUniqueIdentity() SLANG_OVERRIDE;
// IOSFileArtifactRepresentation
virtual SLANG_NO_THROW Kind SLANG_MCALL getKind() SLANG_OVERRIDE { return m_kind; }
@@ -64,6 +65,8 @@ protected:
Kind m_kind;
String m_path;
+ String m_uniqueIdentity;
+
ComPtr<IOSFileArtifactRepresentation> m_lockFile;
ComPtr<ISlangMutableFileSystem> m_fileSystem;
};
@@ -85,7 +88,8 @@ public:
// 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; }
-
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getUniqueIdentity() SLANG_OVERRIDE;
+
// IExtFileArtifactRepresentation
virtual SLANG_NO_THROW ISlangFileSystemExt* SLANG_MCALL getFileSystem() SLANG_OVERRIDE { return m_fileSystem; }
@@ -104,6 +108,7 @@ protected:
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
+ String m_uniqueIdentity;
String m_path;
ComPtr<ISlangFileSystemExt> m_fileSystem;
};
@@ -125,6 +130,7 @@ public:
// IPathArtifactRepresentation
virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() SLANG_OVERRIDE { return m_pathInfo.getName().getBuffer(); }
virtual SLANG_NO_THROW SlangPathType SLANG_MCALL getPathType() SLANG_OVERRIDE { return SLANG_PATH_TYPE_FILE; }
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getUniqueIdentity() SLANG_OVERRIDE { return m_pathInfo.hasUniqueIdentity() ? m_pathInfo.uniqueIdentity.getBuffer() : nullptr; }
SourceBlobWithPathInfoArtifactRepresentation(const PathInfo& pathInfo, ISlangBlob* sourceBlob) :
m_pathInfo(pathInfo),
diff --git a/source/compiler-core/slang-artifact-representation.h b/source/compiler-core/slang-artifact-representation.h
index a345d762b..3e7659058 100644
--- a/source/compiler-core/slang-artifact-representation.h
+++ b/source/compiler-core/slang-artifact-representation.h
@@ -16,6 +16,9 @@ class IPathArtifactRepresentation : public IArtifactRepresentation
virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() = 0;
/// Get type
virtual SLANG_NO_THROW SlangPathType SLANG_MCALL getPathType() = 0;
+ /// Returns the unique identity. If a unique identity is not supported
+ /// or available will return nullptr.
+ virtual SLANG_NO_THROW const char* SLANG_MCALL getUniqueIdentity() = 0;
};
/* Represents a path to a file held on an ISlangFileSystem. */
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index b49ce4fc3..895834312 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1495,6 +1495,9 @@ namespace Slang
protected:
void _addSourceFile(SourceFile* sourceFile);
+ /* Given an artifact, find a PathInfo.
+ If no PathInfo can be found will return an unknown PathInfo */
+ PathInfo _findSourcePathInfo(IArtifact* artifact);
List<ComPtr<IArtifact>> m_sourceArtifacts;
// The source file(s) that will be compiled to form this translation unit
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index b831859a5..283e7c16e 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1583,6 +1583,32 @@ void TranslationUnitRequest::addSource(IArtifact* sourceArtifact, SourceFile* so
_addSourceFile(sourceFile);
}
+PathInfo TranslationUnitRequest::_findSourcePathInfo(IArtifact* artifact)
+{
+ auto pathRep = findRepresentation<IPathArtifactRepresentation>(artifact);
+
+ if (pathRep && pathRep->getPathType() == SLANG_PATH_TYPE_FILE)
+ {
+ // See if we have a unique identity set with the path
+ if (const auto uniqueIdentity = pathRep->getUniqueIdentity())
+ {
+ return PathInfo::makeNormal(pathRep->getPath(), uniqueIdentity);
+ }
+
+ // If we couldn't get a unique identity, just use the path
+ return PathInfo::makePath(pathRep->getPath());
+ }
+
+ // If there isn't a path, we can try with the name
+ const char* name = artifact->getName();
+ if (name && name[0] != 0)
+ {
+ return PathInfo::makeFromString(name);
+ }
+
+ return PathInfo::makeUnknown();
+}
+
SlangResult TranslationUnitRequest::requireSourceFiles()
{
SLANG_ASSERT(m_sourceFiles.getCount() <= m_sourceArtifacts.getCount());
@@ -1595,84 +1621,60 @@ SlangResult TranslationUnitRequest::requireSourceFiles()
auto sink = compileRequest->getSink();
SourceManager* sourceManager = compileRequest->getSourceManager();
- // Get he linkage file system
- //ISlangFileSystemExt* linkageFileSystem = compileRequest->getLinkage()->getFileSystemExt();
-
for (Index i = m_sourceFiles.getCount(); i < m_sourceArtifacts.getCount(); ++i)
{
IArtifact* artifact = m_sourceArtifacts[i];
- PathInfo pathInfo = PathInfo::makeUnknown();
+ const PathInfo pathInfo = _findSourcePathInfo(artifact);
+
+ SourceFile* sourceFile = nullptr;
+ ComPtr<ISlangBlob> blob;
- if (auto extRep = findRepresentation<IExtFileArtifactRepresentation>(artifact))
+ // If we have a unique identity see if we have it already
+ if (pathInfo.hasUniqueIdentity())
{
- auto extFileSystem = extRep->getFileSystem();
-
- // TODO(JS):
- // Ideally we'd confirm that the file system was the same, such we could know that the unique
- // identity is appropriate for the current file system.
- //
- // We just assume compatibility for the moment, because repro will be a different file system
- // but we need to use the unique identity that is there.
-
- //if (extFileSystem == linkageFileSystem)
+ // See if this an already loaded source file
+ sourceFile = sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity);
+ // If we have a sourceFile see if it has a blob
+ if (sourceFile)
{
- // Get the unique identity
- ComPtr<ISlangBlob> uniqueIdentityBlob;
- if (SLANG_SUCCEEDED(extFileSystem->getFileUniqueIdentity(extRep->getPath(), uniqueIdentityBlob.writeRef())) && uniqueIdentityBlob)
- {
- auto uniqueIdentity = StringUtil::getString(uniqueIdentityBlob);
-
- // See if this an already loaded source file
- if (auto sourceFile = sourceManager->findSourceFileRecursively(uniqueIdentity))
- {
- // If the source file has a blob, and the artifact doesn't copy over that representation
- if (sourceFile->getContentBlob() && findRepresentation<ISlangBlob>(artifact) == nullptr)
- {
- artifact->addRepresentationUnknown(sourceFile->getContentBlob());
- }
-
- _addSourceFile(sourceFile);
- continue;
- }
-
- pathInfo = PathInfo::makeNormal(extRep->getPath(), uniqueIdentity);
- }
- else
- {
- pathInfo = PathInfo::makePath(extRep->getPath());
- }
+ blob = sourceFile->getContentBlob();
}
}
- if (pathInfo.type == PathInfo::Type::Unknown)
+ // If we *don't* have a blob try and get a blob from the artifact
+ if (!blob)
{
- const auto path = ArtifactUtil::findPath(artifact);
-
- // If has a path representation we'll make it a FoundPath
- if (findRepresentation<IPathArtifactRepresentation>(artifact))
- {
- pathInfo = PathInfo::makePath(path);
- }
- else
+ const SlangResult res = artifact->loadBlob(ArtifactKeep::Yes, blob.writeRef());
+ if (SLANG_FAILED(res))
{
- // Otherwise we'll assume it's created from a 'String' even if that's not quite the case
- pathInfo = PathInfo::makeFromString(path);
+ // Report couldn't load
+ sink->diagnose(SourceLoc(), Diagnostics::cannotOpenFile, pathInfo.getName());
+ return res;
}
}
- ComPtr<ISlangBlob> blob;
- const SlangResult blobRes = artifact->loadBlob(ArtifactKeep::Yes, blob.writeRef());
- if (SLANG_FAILED(blobRes))
+ // If we don't have a blob on the artifact we can now add the one we have
+ if (!findRepresentation<ISlangBlob>(artifact))
{
- // Report couldn't load
- sink->diagnose(SourceLoc(),
- Diagnostics::cannotOpenFile,
- pathInfo.getName());
- return blobRes;
+ artifact->addRepresentationUnknown(blob);
}
- auto sourceFile = sourceManager->createSourceFileWithBlob(pathInfo, blob);
+ // If we have a sourceFile check if it has contents, and set the blob if doesn't
+ if (sourceFile)
+ {
+ if (!sourceFile->getContentBlob())
+ {
+ sourceFile->setContents(blob);
+ }
+ }
+ else
+ {
+ // Create a new source file, using the pathInfo and blob
+ sourceFile = sourceManager->createSourceFileWithBlob(pathInfo, blob);
+ }
+
+ // Finally add the source file
_addSourceFile(sourceFile);
}