Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Includes] Some improvements #131

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void ExecuteCommand(OpenFileCommandArgs args, Action nextHandler)

var currentFile = ((SyntaxTree) syntaxTree).File;

var include = includeFileResolver.OpenInclude(includeDirectiveTrivia.TrimmedFilename, currentFile);
var include = includeFileResolver.OpenInclude(includeDirectiveTrivia.TrimmedFilename, includeDirectiveTrivia.IsLocal ? IncludeType.Local : IncludeType.System, currentFile);

if (include == null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using ShaderTools.CodeAnalysis.Hlsl.Syntax;
using ShaderTools.CodeAnalysis.Hlsl.Text;
using ShaderTools.CodeAnalysis.Text;
using Xunit;

namespace ShaderTools.CodeAnalysis.Hlsl.Tests.Parser
{
public class CustomFileResolverTests
{
private class MyCustomResolver : IIncludeFileResolver
{
public string Path { get; private set; }

public IncludeType IncludeType { get; private set; }

public bool HasBeenCalled { get; private set; }

public ImmutableArray<string> GetSearchDirectories(string includeFilename, SourceFile currentFile)
{
return new ImmutableArray<string>();
}

public SourceFile OpenInclude(string includeFilename, IncludeType includeType, SourceFile currentFile)
{
this.Path = includeFilename;
this.IncludeType = includeType;
this.HasBeenCalled = true;

return new SourceFile(SourceText.From(""), currentFile);
}

}


[Theory]
[InlineData("#include\"foo.fxh\"", IncludeType.Local, "foo.fxh")]
[InlineData("#include<foo.fxh>", IncludeType.System, "foo.fxh")]
public void TestName(string text, IncludeType includeType, string trimmedName)
{
MyCustomResolver resolver = new MyCustomResolver();

var expression = SyntaxFactory.ParseSyntaxTree(SourceText.From(text), null, null, resolver);

Assert.True(resolver.HasBeenCalled);
Assert.Equal(includeType, resolver.IncludeType);
Assert.Equal(trimmedName, resolver.Path);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Diagnostics;
using System.Linq;
using ShaderTools.CodeAnalysis.Hlsl.Syntax;
using ShaderTools.CodeAnalysis.Text;
using Xunit;

namespace ShaderTools.CodeAnalysis.Hlsl.Tests.Parser
{
public class IncludeDirectiveTests
{
[Theory]
[InlineData("#include\"foo.fxh\"", true, "foo.fxh")]
[InlineData("#include<foo.fxh>", false, "foo.fxh")]
public void TestName(string text, bool isLocal, string trimmedName)
{
var expression = SyntaxFactory.ParseSyntaxTree(SourceText.From(text));
var trivia = ((SyntaxToken)expression.Root.ChildNodes[0]).LeadingTrivia;

Assert.Equal(1, trivia.Length);

var includeTrivia = (IncludeDirectiveTriviaSyntax)trivia[0];

Assert.NotNull(expression);
Assert.Equal(SyntaxKind.IncludeDirectiveTrivia, includeTrivia.Kind);

IncludeDirectiveTriviaSyntax directive = (IncludeDirectiveTriviaSyntax)includeTrivia;

Assert.Equal(isLocal, directive.IsLocal);
Assert.Equal(trimmedName, directive.TrimmedFilename);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public InMemoryFileSystem(Dictionary<string, string> includes)
_includes = includes;
}

public bool TryGetFile(string path, out SourceText text)
public bool TryGetFile(string path, IncludeType includeType, out SourceText text)
{
string include;
if (_includes.TryGetValue(path, out include))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Tests.Support
{
public sealed class TestFileSystem : IIncludeFileSystem
{
public bool TryGetFile(string path, out SourceText text)
public bool TryGetFile(string path, IncludeType includeType, out SourceText text)
{
if (File.Exists(path))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public SyntaxTreeBase ParseSyntaxTree(SourceText text, CancellationToken cancell
text,
options,
_fileSystem,
null,
cancellationToken);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IO;
using System.Linq;
using ShaderTools.CodeAnalysis;
using ShaderTools.CodeAnalysis.Hlsl.Text;
using ShaderTools.CodeAnalysis.Text;

namespace ShaderTools.CodeAnalysis.Hlsl.LanguageServices
Expand All @@ -14,7 +15,7 @@ public WorkspaceFileSystem(Workspace workspace)
_workspace = workspace;
}

public bool TryGetFile(string path, out SourceText text)
public bool TryGetFile(string path, IncludeType includeType, out SourceText text)
{
// Is file open in workspace?
var document = _workspace.CurrentDocuments
Expand Down
6 changes: 3 additions & 3 deletions src/ShaderTools.CodeAnalysis.Hlsl/Parser/HlslLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ public IncludeContext(SourceFile file)
// - {main.hlsl, 101, 200}
internal List<FileSegment> FileSegments { get; }

public HlslLexer(SourceFile file, HlslParseOptions options = null, IIncludeFileSystem includeFileSystem = null)
public HlslLexer(SourceFile file, HlslParseOptions options = null, IIncludeFileSystem includeFileSystem = null, IIncludeFileResolver includeFileResolver = null)
{
_rootFile = file;

_includeFileResolver = new IncludeFileResolver(
_includeFileResolver = includeFileResolver ?? new IncludeFileResolver(
includeFileSystem ?? new DummyFileSystem(),
options ?? new HlslParseOptions());

Expand Down Expand Up @@ -300,7 +300,7 @@ private bool LexDirectiveAndExcludedTrivia(
SourceFile include;
try
{
include = _includeFileResolver.OpenInclude(includeFilename, _includeStack.Peek().File);
include = _includeFileResolver.OpenInclude(includeFilename, includeDirective.IsLocal ? IncludeType.Local : IncludeType.System, _includeStack.Peek().File);
if (include == null)
{
includeDirective = includeDirective.WithDiagnostic(Diagnostic.Create(HlslMessageProvider.Instance, includeDirective.SourceRange, (int) DiagnosticId.IncludeNotFound, includeFilename));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ public sealed class IncludeDirectiveTriviaSyntax : DirectiveTriviaSyntax

public string TrimmedFilename => Filename.Text.TrimStart('<', '"').TrimEnd('>', '"');

public bool IsLocal => !Filename.Text.StartsWith("<");

public IncludeDirectiveTriviaSyntax(SyntaxToken hashToken, SyntaxToken includeKeyword, SyntaxToken filename, SyntaxToken endOfDirectiveToken, bool isActive, IEnumerable<Diagnostic> diagnostics)
: base(SyntaxKind.IncludeDirectiveTrivia, diagnostics)
{
Expand Down
16 changes: 8 additions & 8 deletions src/ShaderTools.CodeAnalysis.Hlsl/Syntax/SyntaxFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Syntax
{
public static class SyntaxFactory
{
public static SyntaxTree ParseSyntaxTree(SourceText sourceText, HlslParseOptions options = null, IIncludeFileSystem fileSystem = null, CancellationToken cancellationToken = default(CancellationToken))
public static SyntaxTree ParseSyntaxTree(SourceText sourceText, HlslParseOptions options = null, IIncludeFileSystem fileSystem = null, IIncludeFileResolver fileResolver = null, CancellationToken cancellationToken = default(CancellationToken))
{
return Parse(sourceText, options, fileSystem ?? new DummyFileSystem(), p => p.ParseCompilationUnit(cancellationToken));
return Parse(sourceText, options, fileSystem ?? new DummyFileSystem(), fileResolver, p => p.ParseCompilationUnit(cancellationToken));
}

public static CompilationUnitSyntax ParseCompilationUnit(SourceText sourceText, IIncludeFileSystem fileSystem = null)
public static CompilationUnitSyntax ParseCompilationUnit(SourceText sourceText, IIncludeFileSystem fileSystem = null, IIncludeFileResolver fileResolver = null)
{
return (CompilationUnitSyntax) Parse(sourceText, null, fileSystem, p => p.ParseCompilationUnit(CancellationToken.None)).Root;
return (CompilationUnitSyntax) Parse(sourceText, null, fileSystem, fileResolver, p => p.ParseCompilationUnit(CancellationToken.None)).Root;
}

public static SyntaxTree ParseExpression(string text)
{
return Parse(SourceText.From(text), null, null, p => p.ParseExpression());
return Parse(SourceText.From(text), null, null, null, p => p.ParseExpression());
}

public static StatementSyntax ParseStatement(string text)
{
return (StatementSyntax) Parse(SourceText.From(text), null, null, p => p.ParseStatement()).Root;
return (StatementSyntax) Parse(SourceText.From(text), null, null, null, p => p.ParseStatement()).Root;
}

private static SyntaxTree Parse(SourceText sourceText, HlslParseOptions options, IIncludeFileSystem fileSystem, Func<HlslParser, SyntaxNode> parseFunc)
private static SyntaxTree Parse(SourceText sourceText, HlslParseOptions options, IIncludeFileSystem fileSystem, IIncludeFileResolver fileResolver, Func <HlslParser, SyntaxNode> parseFunc)
{
var sourceFile = new SourceFile(sourceText, null);

var lexer = new HlslLexer(sourceFile, options, fileSystem);
var lexer = new HlslLexer(sourceFile, options, fileSystem, fileResolver);
var parser = new HlslParser(lexer);

var result = new SyntaxTree(
Expand Down
2 changes: 1 addition & 1 deletion src/ShaderTools.CodeAnalysis.Hlsl/Text/DummyFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Text
{
internal sealed class DummyFileSystem : IIncludeFileSystem
{
public bool TryGetFile(string path, out SourceText text)
public bool TryGetFile(string path, IncludeType includeType, out SourceText text)
{
text = null;
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Text
public interface IIncludeFileResolver
{
ImmutableArray<string> GetSearchDirectories(string includeFilename, SourceFile currentFile);
SourceFile OpenInclude(string includeFilename, SourceFile currentFile);
SourceFile OpenInclude(string includeFilename, IncludeType includeType, SourceFile currentFile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Text
{
public interface IIncludeFileSystem
{
bool TryGetFile(string path, out SourceText text);
bool TryGetFile(string path, IncludeType includeType, out SourceText text);
}
}
8 changes: 4 additions & 4 deletions src/ShaderTools.CodeAnalysis.Hlsl/Text/IncludeFileResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ImmutableArray<string> GetSearchDirectories(string includeFilename, Sourc
return result.ToImmutable();
}

public SourceFile OpenInclude(string includeFilename, SourceFile currentFile)
public SourceFile OpenInclude(string includeFilename, IncludeType includeType, SourceFile currentFile)
{
SourceText text;

Expand All @@ -56,7 +56,7 @@ public SourceFile OpenInclude(string includeFilename, SourceFile currentFile)
// If path is rooted, open it directly.
if (Path.IsPathRooted(includeFilename))
{
if (_fileSystem.TryGetFile(includeFilename, out text))
if (_fileSystem.TryGetFile(includeFilename, includeType, out text))
return new SourceFile(text, currentFile);
return null;
}
Expand All @@ -70,7 +70,7 @@ public SourceFile OpenInclude(string includeFilename, SourceFile currentFile)
{
var rootFileDirectory = Path.GetDirectoryName(fileToCheck.FilePath);
var testFilename = Path.Combine(rootFileDirectory, includeFilename);
if (_fileSystem.TryGetFile(testFilename, out text))
if (_fileSystem.TryGetFile(testFilename, includeType, out text))
return new SourceFile(text, currentFile);
}
fileToCheck = fileToCheck.IncludedBy;
Expand All @@ -80,7 +80,7 @@ public SourceFile OpenInclude(string includeFilename, SourceFile currentFile)
foreach (var includeDirectory in _parserOptions.AdditionalIncludeDirectories)
{
var testFilename = Path.Combine(includeDirectory, includeFilename);
if (_fileSystem.TryGetFile(testFilename, out text))
if (_fileSystem.TryGetFile(testFilename, includeType, out text))
return new SourceFile(text, currentFile);
}

Expand Down
21 changes: 21 additions & 0 deletions src/ShaderTools.CodeAnalysis.Hlsl/Text/IncludeType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace ShaderTools.CodeAnalysis.Hlsl.Text
{
/// <summary>
/// Defines hlsl include type
/// </summary>
public enum IncludeType
{
/// <summary>
/// Local include (we should look in folder relative to the code file)
/// </summary>
Local,
/// <summary>
/// System include generally defined by executable path, or application specified folders
/// </summary>
System
}
}
2 changes: 1 addition & 1 deletion src/ShaderTools.CodeAnalysis/Text/SourceFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public sealed class SourceFile

public bool IsRootFile => IncludedBy == null;

internal SourceFile(SourceText text, SourceFile includedBy)
public SourceFile(SourceText text, SourceFile includedBy)
{
Text = text ?? throw new ArgumentNullException(nameof(text));
IncludedBy = includedBy;
Expand Down