From cd8715a7760189c54b36c0c250efbe1db5b8635c Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 1 Sep 2022 09:35:18 -0400 Subject: Passing source to Downstream compilation as artifacts (#2382) * #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. --- source/compiler-core/slang-artifact-util.cpp | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to 'source/compiler-core/slang-artifact-util.cpp') diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp index 20a729cfa..047e87db0 100644 --- a/source/compiler-core/slang-artifact-util.cpp +++ b/source/compiler-core/slang-artifact-util.cpp @@ -120,4 +120,143 @@ namespace Slang { 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) +{ + for (auto rep : artifact->getRepresentations()) + { + if (auto fileSystemRep = as(rep)) + { + if (fileSystemRep->getFileSystem() == nullptr) + { + return fileSystemRep; + } + } + } + return nullptr; +} + +/* static */IFileArtifactRepresentation* ArtifactUtil::findFileSystemPrimaryFile(IArtifact* artifact) +{ + for (auto rep : artifact->getRepresentations()) + { + if (auto fileRep = as(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) + { + continue; + } + + return fileRep; + } + } + return nullptr; +} + +UnownedStringSlice ArtifactUtil::findPath(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(artifact)) + { + // If there isn't a lock file it is + if (fileRep->getLockFile() == nullptr) + { + return UnownedStringSlice(fileRep->getPath()); + } + } + + return UnownedStringSlice(); +} + +/* static */UnownedStringSlice ArtifactUtil::inferExtension(IArtifact* artifact) +{ + for (auto rep :artifact->getRepresentations()) + { + if (auto fileRep = as(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())); +} + +static SlangResult _calcInferred(IArtifact* artifact, const UnownedStringSlice& basePath, StringBuilder& outPath) +{ + auto ext = ArtifactUtil::inferExtension(artifact); + + // If no extension was determined by inferring, go with unknown + if (ext.begin() == nullptr) + { + ext = toSlice("unknown"); + } + + outPath.Clear(); + outPath.append(basePath); + if (ext.getLength()) + { + outPath.appendChar('.'); + outPath.append(ext); + } + return SLANG_OK; +} + +/* static */SlangResult ArtifactUtil::calcPath(IArtifact* artifact, const UnownedStringSlice& basePath, StringBuilder& outPath) +{ + if (ArtifactDescUtil::hasDefinedNameForDesc(artifact->getDesc())) + { + return ArtifactDescUtil::calcPathForDesc(artifact->getDesc(), basePath, outPath); + } + else + { + return _calcInferred(artifact, basePath, outPath); + } +} + +/* static */SlangResult ArtifactUtil::calcName(IArtifact* artifact, const UnownedStringSlice& baseName, StringBuilder& outName) +{ + if (ArtifactDescUtil::hasDefinedNameForDesc(artifact->getDesc())) + { + return ArtifactDescUtil::calcNameForDesc(artifact->getDesc(), baseName, outName); + } + else + { + return _calcInferred(artifact, baseName, outName); + } +} + } // namespace Slang -- cgit v1.2.3