summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-02-04 17:30:51 -0500
committerGitHub <noreply@github.com>2019-02-04 17:30:51 -0500
commit9b80537bc0272a9caf93f146d8964d9bdd4a407e (patch)
tree13c2e92adca1b78b632bd8dd6cc1fecb5a12ded9 /source
parent0d206996cd68b9f08ae1b4d9da6f16293984302c (diff)
Feature/view path (#824)
* Use 'is' over 'as' where appropriate. * dynamic_cast -> dynamicCast * Replace 'dynamicCast' with 'as' where has no change in behavior/ambiguity. * Replace dynamicCast with as where doesn't change behavior/non ambiguous. * Keep a per view path to the file loaded - such that diagnostic messages always display the path to the requested file. * Add simplifyPath to ISlangFileSystemExt Simplify (if possible) paths that are set on SourceFile and SourcView - doing so makes reading paths simpler. * Fix small typo. * Improve documentation in source for getFileUniqueIdentity * Fix override warning.
Diffstat (limited to 'source')
-rw-r--r--source/slang/ir-serialize.cpp2
-rw-r--r--source/slang/preprocessor.cpp14
-rw-r--r--source/slang/preprocessor.h2
-rw-r--r--source/slang/slang-file-system.cpp48
-rw-r--r--source/slang/slang-file-system.h20
-rw-r--r--source/slang/slang.cpp11
-rw-r--r--source/slang/source-loc.cpp39
-rw-r--r--source/slang/source-loc.h20
8 files changed, 134 insertions, 22 deletions
diff --git a/source/slang/ir-serialize.cpp b/source/slang/ir-serialize.cpp
index 730f13ca7..a50ed6bd5 100644
--- a/source/slang/ir-serialize.cpp
+++ b/source/slang/ir-serialize.cpp
@@ -1801,7 +1801,7 @@ static int _calcFixSourceLoc(const IRSerialData::DebugSourceInfo& info, SourceVi
pathInfo.foundPath = debugStringSlices[UInt(srcSourceInfo.m_pathIndex)];
SourceFile* sourceFile = sourceManager->createSourceFileWithSize(pathInfo, srcSourceInfo.m_endSourceLoc - srcSourceInfo.m_startSourceLoc);
- SourceView* sourceView = sourceManager->createSourceView(sourceFile);
+ SourceView* sourceView = sourceManager->createSourceView(sourceFile, nullptr);
// We need to accumulate all line numbers, for this source file, both adjusted and unadjusted
List<IRSerialData::DebugLineInfo> lineInfos;
diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp
index 4ccb5d50e..91043bcf9 100644
--- a/source/slang/preprocessor.cpp
+++ b/source/slang/preprocessor.cpp
@@ -842,7 +842,7 @@ top:
PathInfo pathInfo = PathInfo::makeTokenPaste();
SourceFile* sourceFile = sourceManager->createSourceFileWithString(pathInfo, sb.ProduceString());
- SourceView* sourceView = sourceManager->createSourceView(sourceFile);
+ SourceView* sourceView = sourceManager->createSourceView(sourceFile, nullptr);
Lexer lexer;
lexer.initialize(sourceView, GetSink(preprocessor), getNamePool(preprocessor), sourceManager->getMemoryArena());
@@ -1627,6 +1627,9 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
return;
}
+ // Simplify the path
+ filePathInfo.foundPath = includeHandler->simplifyPath(filePathInfo.foundPath);
+
// Push the new file onto our stack of input streams
// TODO(tfoley): check if we have made our include stack too deep
auto sourceManager = context->preprocessor->getCompileRequest()->getSourceManager();
@@ -1643,12 +1646,13 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
return;
}
+
sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob);
sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile);
}
// This is a new parse (even if it's a pre-existing source file), so create a new SourceUnit
- SourceView* sourceView = sourceManager->createSourceView(sourceFile);
+ SourceView* sourceView = sourceManager->createSourceView(sourceFile, &filePathInfo);
PreprocessorInputStream* inputStream = CreateInputStreamForSource(context->preprocessor, sourceView);
inputStream->parent = context->preprocessor->inputStream;
@@ -2259,8 +2263,8 @@ static void DefineMacro(
SourceFile* keyFile = sourceManager->createSourceFileWithString(pathInfo, key);
SourceFile* valueFile = sourceManager->createSourceFileWithString(pathInfo, value);
- SourceView* keyView = sourceManager->createSourceView(keyFile);
- SourceView* valueView = sourceManager->createSourceView(valueFile);
+ SourceView* keyView = sourceManager->createSourceView(keyFile, nullptr);
+ SourceView* valueView = sourceManager->createSourceView(valueFile, nullptr);
// Use existing `Lexer` to generate a token stream.
Lexer lexer;
@@ -2319,7 +2323,7 @@ TokenList preprocessSource(
SourceManager* sourceManager = translationUnit->compileRequest->getSourceManager();
- SourceView* sourceView = sourceManager->createSourceView(file);
+ SourceView* sourceView = sourceManager->createSourceView(file, nullptr);
// create an initial input stream based on the provided buffer
preprocessor.inputStream = CreateInputStreamForSource(&preprocessor, sourceView);
diff --git a/source/slang/preprocessor.h b/source/slang/preprocessor.h
index 42a3b25f4..4d02cb50b 100644
--- a/source/slang/preprocessor.h
+++ b/source/slang/preprocessor.h
@@ -22,6 +22,8 @@ struct IncludeHandler
virtual SlangResult readFile(const String& path,
ISlangBlob** blobOut) = 0;
+
+ virtual String simplifyPath(const String& path) = 0;
};
// Take a string of source code and preprocess it into a list of tokens.
diff --git a/source/slang/slang-file-system.cpp b/source/slang/slang-file-system.cpp
index b3ba692bd..d52ea1157 100644
--- a/source/slang/slang-file-system.cpp
+++ b/source/slang/slang-file-system.cpp
@@ -76,6 +76,13 @@ SlangResult OSFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCan
return SLANG_OK;
}
+SlangResult OSFileSystem::getSimplifiedPath(const char* pathIn, ISlangBlob** outSimplifiedPath)
+{
+ String simplifiedPath = Path::Simplify(_fixPathDelimiters(pathIn));
+ *outSimplifiedPath = StringUtil::createStringBlob(simplifiedPath).detach();
+ return SLANG_OK;
+}
+
SlangResult OSFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
{
// Don't need to fix delimiters - because combine path handles both path delimiter types
@@ -143,9 +150,10 @@ ISlangUnknown* CacheFileSystem::getInterface(const Guid& guid)
return _getInterface(this, guid);
}
-CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode) :
+CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode, PathStyle pathStyle) :
m_fileSystem(fileSystem),
- m_uniqueIdentityMode(uniqueIdentityMode)
+ m_uniqueIdentityMode(uniqueIdentityMode),
+ m_pathStyle(pathStyle)
{
// Try to get the more sophisticated interface
fileSystem->queryInterface(IID_ISlangFileSystemExt, (void**)m_fileSystemExt.writeRef());
@@ -162,6 +170,17 @@ CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMod
default: break;
}
+ if (m_fileSystemExt)
+ {
+ // We just defer to the m_fileSystem, so we mark as unknown
+ m_pathStyle = PathStyle::Unknown;
+ }
+ else if (m_pathStyle == PathStyle::Default)
+ {
+ // We'll assume it's simplify-able
+ m_pathStyle = PathStyle::Simplifiable;
+ }
+
// It can't be default
SLANG_ASSERT(m_uniqueIdentityMode != UniqueIdentityMode::Default);
}
@@ -286,7 +305,7 @@ CacheFileSystem::PathInfo* CacheFileSystem::_resolveUniqueIdentityCacheInfo(cons
// At this point they must have same uniqueIdentity
SLANG_ASSERT(pathInfo->getUniqueIdentity() == uniqueIdentity);
- // If we have the file contents (because of calcing uniqueIdentity), and there isn't a read fileblob already
+ // If we have the file contents (because of calc-ing uniqueIdentity), and there isn't a read file blob already
// store the data as if read, so doesn't get read again
if (fileContents && !pathInfo->m_fileBlob)
{
@@ -414,6 +433,29 @@ SlangResult CacheFileSystem::getPathType(const char* pathIn, SlangPathType* path
return toResult(info->m_getPathTypeResult);
}
+SlangResult CacheFileSystem::getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath)
+{
+ // If we have a ISlangFileSystemExt we can just pass on the request to it
+ if (m_fileSystemExt)
+ {
+ return m_fileSystemExt->getSimplifiedPath(path, outSimplifiedPath);
+ }
+ else
+ {
+ // Use the path style to see what we can do with it
+ switch (m_pathStyle)
+ {
+ case PathStyle::Simplifiable:
+ {
+ String simplifiedPath = Path::Simplify(_fixPathDelimiters(path));
+ *outSimplifiedPath = StringUtil::createStringBlob(simplifiedPath).detach();
+ return SLANG_OK;
+ }
+ default: return SLANG_E_NOT_IMPLEMENTED;
+ }
+ }
+}
+
SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath)
{
// If we don't have a backing full file system, we can't produce a canonical path with just ISlangFileSystem::loadFile
diff --git a/source/slang/slang-file-system.h b/source/slang/slang-file-system.h
index e341bf649..a9e92dc1e 100644
--- a/source/slang/slang-file-system.h
+++ b/source/slang/slang-file-system.h
@@ -40,9 +40,13 @@ public:
const char* path,
SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getSimplifiedPath(
+ const char* path,
+ ISlangBlob** outSimplifiedPath) SLANG_OVERRIDE;
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanonicalPath(
const char* path,
- ISlangBlob** outCanonicalPath);
+ ISlangBlob** outCanonicalPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() {}
@@ -71,6 +75,13 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
{
public:
+ enum class PathStyle
+ {
+ Default, ///< Pass to say use the default
+ Unknown, ///< It's an unknown type of path
+ Simplifiable, ///< It can be simplified by Path::Simplify
+ };
+
enum UniqueIdentityMode
{
Default, ///< If passed, will default to the others depending on what kind of ISlangFileSystem is passed in
@@ -115,6 +126,10 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
const char* path,
SlangPathType* outPathType) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getSimplifiedPath(
+ const char* path,
+ ISlangBlob** outSimplifiedPath) SLANG_OVERRIDE;
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getCanonicalPath(
const char* path,
ISlangBlob** outCanonicalPath);
@@ -122,7 +137,7 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
virtual SLANG_NO_THROW void SLANG_MCALL clearCache();
/// Ctor
- CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default);
+ CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
/// Dtor
virtual ~CacheFileSystem();
@@ -178,6 +193,7 @@ protected:
Dictionary<String, PathInfo*> m_uniqueIdentityMap; ///< Maps a unique identity for a file to its contents. This OWNs the PathInfo.
UniqueIdentityMode m_uniqueIdentityMode; ///< Determines how the 'uniqueIdentity' is produced. Cannot be Default in usage.
+ PathStyle m_pathStyle; ///< Style of paths
ComPtr<ISlangFileSystem> m_fileSystem; ///< Must always be set
ComPtr<ISlangFileSystemExt> m_fileSystemExt; ///< Optionally set -> if nullptr will fall back on the m_fileSystem and emulate all the other methods of ISlangFileSystemExt
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index e332ef588..16dfe8618 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -176,6 +176,17 @@ struct IncludeHandlerImpl : IncludeHandler
return SLANG_OK;
}
+ virtual String simplifyPath(const String& path) override
+ {
+ ISlangFileSystemExt* fileSystemExt = _getFileSystemExt();
+ ComPtr<ISlangBlob> simplifiedPath;
+ if (SLANG_FAILED(fileSystemExt->getSimplifiedPath(path.Buffer(), simplifiedPath.writeRef())))
+ {
+ return path;
+ }
+ return StringUtil::getString(simplifiedPath);
+ }
+
};
//
diff --git a/source/slang/source-loc.cpp b/source/slang/source-loc.cpp
index 6507ea4b7..00b6d3be4 100644
--- a/source/slang/source-loc.cpp
+++ b/source/slang/source-loc.cpp
@@ -150,16 +150,30 @@ HumaneSourceLoc SourceView::getHumaneLoc(SourceLoc loc, SourceLocType type)
pathHandle = entry.m_pathHandle;
}
- humaneLoc.pathInfo = _getPathInfo(pathHandle);
+ humaneLoc.pathInfo = _getPathInfoFromHandle(pathHandle);
return humaneLoc;
}
-PathInfo SourceView::_getPathInfo(StringSlicePool::Handle pathHandle) const
+PathInfo SourceView::_getPathInfo() const
+{
+ if (m_viewPath.Length())
+ {
+ PathInfo pathInfo(m_sourceFile->getPathInfo());
+ pathInfo.foundPath = m_viewPath;
+ return pathInfo;
+ }
+ else
+ {
+ return m_sourceFile->getPathInfo();
+ }
+}
+
+PathInfo SourceView::_getPathInfoFromHandle(StringSlicePool::Handle pathHandle) const
{
// If there is no override path, then just the source files path
if (pathHandle == StringSlicePool::Handle(0))
{
- return m_sourceFile->getPathInfo();
+ return _getPathInfo();
}
else
{
@@ -171,11 +185,11 @@ PathInfo SourceView::getPathInfo(SourceLoc loc, SourceLocType type)
{
if (type == SourceLocType::Actual)
{
- return m_sourceFile->getPathInfo();
+ return _getPathInfo();
}
const int entryIndex = findEntryIndex(loc);
- return _getPathInfo((entryIndex >= 0) ? m_entries[entryIndex].m_pathHandle : StringSlicePool::Handle(0));
+ return _getPathInfoFromHandle((entryIndex >= 0) ? m_entries[entryIndex].m_pathHandle : StringSlicePool::Handle(0));
}
/* !!!!!!!!!!!!!!!!!!!!!!! SourceFile !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -418,10 +432,21 @@ SourceFile* SourceManager::createSourceFileWithBlob(const PathInfo& pathInfo, IS
return sourceFile;
}
-SourceView* SourceManager::createSourceView(SourceFile* sourceFile)
+SourceView* SourceManager::createSourceView(SourceFile* sourceFile, const PathInfo* pathInfo)
{
SourceRange range = allocateSourceRange(sourceFile->getContentSize());
- SourceView* sourceView = new SourceView(sourceFile, range);
+
+ SourceView* sourceView = nullptr;
+ if (pathInfo &&
+ (pathInfo->foundPath.Length() && sourceFile->getPathInfo().foundPath != pathInfo->foundPath))
+ {
+ sourceView = new SourceView(sourceFile, range, &pathInfo->foundPath);
+ }
+ else
+ {
+ sourceView = new SourceView(sourceFile, range, nullptr);
+ }
+
m_sourceViews.Add(sourceView);
return sourceView;
diff --git a/source/slang/source-loc.h b/source/slang/source-loc.h
index aa0623e3d..ad0453d0e 100644
--- a/source/slang/source-loc.h
+++ b/source/slang/source-loc.h
@@ -194,7 +194,7 @@ public:
protected:
- SourceManager * m_sourceManager; ///< The source manager this belongs to
+ SourceManager* m_sourceManager; ///< The source manager this belongs to
PathInfo m_pathInfo; ///< The path The logical file path to report for locations inside this span.
ComPtr<ISlangBlob> m_contentBlob; ///< A blob that owns the storage for the file contents. If nullptr, there is no contents
UnownedStringSlice m_content; ///< The actual contents of the file.
@@ -281,14 +281,24 @@ class SourceView
PathInfo getPathInfo(SourceLoc loc, SourceLocType type = SourceLocType::Nominal);
/// Ctor
- SourceView(SourceFile* sourceFile, SourceRange range):
+ SourceView(SourceFile* sourceFile, SourceRange range, const String* viewPath):
m_range(range),
m_sourceFile(sourceFile)
{
+ if (viewPath)
+ {
+ m_viewPath = *viewPath;
+ }
}
protected:
- PathInfo _getPathInfo(StringSlicePool::Handle pathHandle) const;
+ /// Get the pathInfo from a string handle. If it's 0, it will return the _getPathInfo
+ PathInfo _getPathInfoFromHandle(StringSlicePool::Handle pathHandle) const;
+ /// Gets the pathInfo for this view. It may be different from the m_sourceFile's if the path has been
+ /// overridden by m_viewPath
+ PathInfo _getPathInfo() const;
+
+ String m_viewPath; ///< Path to this view. If empty the path is the path to the SourceView
SourceRange m_range; ///< The range that this SourceView applies to
SourceFile* m_sourceFile; ///< The source file. Can hold the line breaks
@@ -315,7 +325,9 @@ struct SourceManager
PathInfo getPathInfo(SourceLoc loc, SourceLocType type = SourceLocType::Nominal);
/// Create a new source view from a file
- SourceView* createSourceView(SourceFile* sourceFile);
+ /// @param sourceFile is the source file that contains the source
+ /// @param pathInfo is path used to read the file from
+ SourceView* createSourceView(SourceFile* sourceFile, const PathInfo* pathInfo);
/// Find a view by a source file location.
/// If not found in this manager will look in the parent SourceManager