diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2023-04-04 17:20:05 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-04 17:20:05 -0400 |
| commit | 7bb2de1bc40e535fae93940113db97b5ea44a6f2 (patch) | |
| tree | a70dcd1c4f97387ba7df482fefcd576c04543606 | |
| parent | 34a2fd593dd5a5d7b597b9d2fe20e39cc24b8e6c (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.cpp | 32 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-representation-impl.h | 8 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-representation.h | 3 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 3 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 122 |
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); } |
