public void TestIntrinsicFunctionOverloading(string function, string type1, string type2, string expectedMatchTypes)
        {
            var expressionCode   = $"{function}(({type1}) 0, ({type2}) 0)";
            var syntaxTree       = SyntaxFactory.ParseExpression(expressionCode);
            var syntaxTreeSource = syntaxTree.Root.ToFullString();

            Assert.Equal(expressionCode, syntaxTreeSource);

            var expression = (ExpressionSyntax)syntaxTree.Root;

            var compilation         = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel       = compilation.GetSemanticModel();
            var combinedDiagnostics = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToList();

            foreach (var d in combinedDiagnostics)
            {
                Debug.WriteLine(d);
            }

            var invokedFunctionSymbol = (FunctionSymbol)semanticModel.GetSymbol(expression);

            var diagnostic = combinedDiagnostics.SingleOrDefault(x => x.Severity == DiagnosticSeverity.Error);
            var result     = diagnostic == null
                ? $"{invokedFunctionSymbol.Parameters[0].ValueType.ToMarkup()}, {invokedFunctionSymbol.Parameters[1].ValueType.ToMarkup()}"
                : ExpressionTestUtility.GetErrorString((DiagnosticId)diagnostic.Descriptor.Code);

            Assert.Equal(expectedMatchTypes, result);
        }
        public void TestFunctionOverloadResolutionMultipleFunctionDeclarations()
        {
            var code             = $@"
void foo();
void foo();

void main()
{{
    foo();
}}";
            var syntaxTree       = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var syntaxTreeSource = syntaxTree.Root.ToFullString();

            Assert.Equal(code, syntaxTreeSource);

            var expression = (FunctionInvocationExpressionSyntax)syntaxTree.Root.ChildNodes
                             .OfType <FunctionDefinitionSyntax>()
                             .Where(x => x.Name.GetUnqualifiedName().Name.Text == "main")
                             .Select(x => ((ExpressionStatementSyntax)x.Body.Statements[0]).Expression)
                             .First();

            var compilation         = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel       = compilation.GetSemanticModel();
            var combinedDiagnostics = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToList();

            foreach (var d in combinedDiagnostics)
            {
                Debug.WriteLine(d);
            }

            var invokedFunctionSymbol = (FunctionSymbol)semanticModel.GetSymbol(expression);

            Assert.Equal("foo", invokedFunctionSymbol.Name);
        }
        public void SemanticModelForTypedef()
        {
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(@"
typedef float2 Point;

void main() {
    Point p;
    p.x = 1;
}"));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            foreach (var diagnostic in semanticModel.GetDiagnostics())
            {
                _output.WriteLine(diagnostic.ToString());
            }

            Assert.Equal(0, semanticModel.GetDiagnostics().Count(x => x.Severity == DiagnosticSeverity.Error));

            var typedefStatement   = (TypedefStatementSyntax)syntaxTree.Root.ChildNodes[0];
            var functionDefinition = (FunctionDefinitionSyntax)syntaxTree.Root.ChildNodes[1];

            var typeAliasSymbol = semanticModel.GetDeclaredSymbol(typedefStatement.Declarators[0]);

            Assert.NotNull(typeAliasSymbol);
            Assert.Equal("Point", typeAliasSymbol.Name);

            var variableDeclaration = (VariableDeclarationStatementSyntax)functionDefinition.Body.Statements[0];
            var variableSymbol      = semanticModel.GetDeclaredSymbol(variableDeclaration.Declaration.Variables[0]);

            Assert.NotNull(variableSymbol);
            Assert.Equal("p", variableSymbol.Name);
            Assert.NotNull(variableSymbol.ValueType);
            Assert.Equal(typeAliasSymbol, variableSymbol.ValueType);
        }
        public void TestBinaryOperatorTypeConversions(string opText, string leftText, string rightText, string expectedResult)
        {
            var left             = ExpressionTestUtility.GetValue(leftText);
            var right            = ExpressionTestUtility.GetValue(rightText);
            var source           = $"{left} {opText} {right}";
            var syntaxTree       = SyntaxFactory.ParseExpression(source);
            var syntaxTreeSource = syntaxTree.Root.ToString();

            Assert.Equal(source, syntaxTreeSource);

            var expression    = (BinaryExpressionSyntax)syntaxTree.Root;
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            var leftType = ExpressionTestUtility.GetExpressionTypeString(semanticModel.GetExpressionType(expression.Left));

            Assert.Equal(leftText, leftType);

            var rightType = ExpressionTestUtility.GetExpressionTypeString(semanticModel.GetExpressionType(expression.Right));

            Assert.Equal(rightText, rightType);

            var diagnostic     = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).SingleOrDefault();
            var expressionType = semanticModel.GetExpressionType(expression);
            var result         = diagnostic == null
                ? ExpressionTestUtility.GetExpressionTypeString(expressionType)
                : ExpressionTestUtility.GetErrorString((DiagnosticId)diagnostic.Descriptor.Code);

            Assert.Equal(expectedResult, result);
        }
        protected void AssertNoDiagnostics(string code)
        {
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();
            var diagnostics   = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToImmutableArray();

            Assert.Empty(diagnostics);
        }
        protected void AssertDiagnostics(string code, params DiagnosticId[] expectedDiagnosticIds)
        {
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();
            var diagnostics   = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToImmutableArray();

            Assert.Equal(expectedDiagnosticIds.Length, diagnostics.Length);
            for (var i = 0; i < expectedDiagnosticIds.Length; i++)
            {
                Assert.Equal(expectedDiagnosticIds[i], (DiagnosticId)diagnostics[i].Descriptor.Code);
            }
        }
Esempio n. 7
0
        public void DetectsRedefinitionAsFunction()
        {
            var code          = @"
struct foo {};
void foo();";
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();
            var diagnostics   = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToImmutableArray();

            Assert.Equal(1, diagnostics.Length);
            Assert.Equal(DiagnosticId.SymbolRedefined, (DiagnosticId)diagnostics[0].Descriptor.Code);
        }
Esempio n. 8
0
        public void DetectsUndeclaredVariable()
        {
            var code          = @"
void main()
{
    int foo = a;
}";
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();
            var diagnostics   = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToImmutableArray();

            Assert.Equal(1, diagnostics.Length);
            Assert.Equal(DiagnosticId.UndeclaredVariable, (DiagnosticId)diagnostics[0].Descriptor.Code);
        }
Esempio n. 9
0
        public void SemanticModelForScalarSwizzle()
        {
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(@"
float4 main() {
    return 1.xxxx + 2.0f.xxxx + 2.5.xxxx;
}"));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            foreach (var diagnostic in semanticModel.GetDiagnostics())
            {
                _output.WriteLine(diagnostic.ToString());
            }

            Assert.Equal(0, semanticModel.GetDiagnostics().Count(x => x.Severity == DiagnosticSeverity.Error));
        }
        public void TestFunctionOverloadResolution2Args(string type1, string type2, string expectedMatchTypes)
        {
            var code             = $@"
int foo(int x, float y)       {{ return 1; }}
int foo(float x, float y)     {{ return 2; }}
int foo(double x, float y)    {{ return 3; }}
int foo(float x, int y)       {{ return 4; }}
int foo(float x, double y)    {{ return 5; }}
int foo(double x, int y)      {{ return 6; }}
int foo(int2 x, float y)      {{ return 7; }}
int foo(float2 x, float y)    {{ return 8; }}
int foo(double2 x, float y)   {{ return 9; }}
int foo(float3x3 x, float y)  {{ return 10; }}

void main()
{{
    foo({ExpressionTestUtility.GetValue(type1)}, {ExpressionTestUtility.GetValue(type2)});
}}";
            var syntaxTree       = SyntaxFactory.ParseSyntaxTree(SourceText.From(code));
            var syntaxTreeSource = syntaxTree.Root.ToFullString();

            Assert.Equal(code, syntaxTreeSource);

            var expression = (FunctionInvocationExpressionSyntax)syntaxTree.Root.ChildNodes
                             .OfType <FunctionDefinitionSyntax>()
                             .Where(x => x.Name.GetUnqualifiedName().Name.Text == "main")
                             .Select(x => ((ExpressionStatementSyntax)x.Body.Statements[0]).Expression)
                             .First();

            var compilation         = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel       = compilation.GetSemanticModel();
            var combinedDiagnostics = syntaxTree.GetDiagnostics().Concat(semanticModel.GetDiagnostics()).ToList();

            foreach (var d in combinedDiagnostics)
            {
                Debug.WriteLine(d);
            }

            var invokedFunctionSymbol = (FunctionSymbol)semanticModel.GetSymbol(expression);

            var diagnostic = combinedDiagnostics.SingleOrDefault(x => x.Severity == DiagnosticSeverity.Error);
            var result     = diagnostic == null
                ? $"{invokedFunctionSymbol.Parameters[0].ValueType.ToMarkup()}, {invokedFunctionSymbol.Parameters[1].ValueType.ToMarkup()}"
                : ExpressionTestUtility.GetErrorString((DiagnosticId)diagnostic.Descriptor.Code);

            Assert.Equal(expectedMatchTypes, result);
        }
        public void SemanticModelForStructAndFunction()
        {
            var syntaxTree    = SyntaxFactory.ParseSyntaxTree(SourceText.From(@"
struct MyStruct
{
    float a;
    int b;
};

void MyFunc()
{
    MyStruct s;
    s.a = 1.0;
}"));
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            var structDefinition    = (TypeDeclarationStatementSyntax)syntaxTree.Root.ChildNodes[0];
            var functionDefinition  = (FunctionDefinitionSyntax)syntaxTree.Root.ChildNodes[1];
            var variableDeclaration = (VariableDeclarationStatementSyntax)functionDefinition.Body.Statements[0];
            var assignmentStatement = (ExpressionStatementSyntax)functionDefinition.Body.Statements[1];

            var structSymbol = semanticModel.GetDeclaredSymbol((StructTypeSyntax)structDefinition.Type);

            Assert.NotNull(structSymbol);
            Assert.Equal("MyStruct", structSymbol.Name);
            Assert.Equal(2, structSymbol.Members.Length);

            var functionSymbol = semanticModel.GetDeclaredSymbol(functionDefinition);

            Assert.NotNull(functionSymbol);
            Assert.Equal("MyFunc", functionSymbol.Name);
            Assert.Equal(IntrinsicTypes.Void, functionSymbol.ReturnType);

            var variableSymbol = semanticModel.GetDeclaredSymbol(variableDeclaration.Declaration.Variables[0]);

            Assert.NotNull(variableSymbol);
            Assert.Equal("s", variableSymbol.Name);
            Assert.NotNull(variableSymbol.ValueType);
            Assert.Equal(structSymbol, variableSymbol.ValueType);

            var assignmentExpressionType = semanticModel.GetExpressionType(assignmentStatement.Expression);

            Assert.NotNull(assignmentExpressionType);
            Assert.Equal(IntrinsicTypes.Float, assignmentExpressionType);
        }
        public void CanGetSemanticModel(string testFile)
        {
            var sourceCode = File.ReadAllText(testFile);

            // Build syntax tree.
            var syntaxTree = SyntaxFactory.ParseSyntaxTree(new SourceFile(SourceText.From(sourceCode), testFile), fileSystem: new TestFileSystem());

            SyntaxTreeUtility.CheckForParseErrors(syntaxTree);

            // Get semantic model.
            var compilation   = new CodeAnalysis.Hlsl.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            Assert.NotNull(semanticModel);

            foreach (var diagnostic in semanticModel.GetDiagnostics())
            {
                _output.WriteLine(diagnostic.ToString());
            }

            Assert.Equal(0, semanticModel.GetDiagnostics().Count(x => x.Severity == DiagnosticSeverity.Error));
        }