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.AreEqual(expressionCode, syntaxTreeSource, $"Source should have been {expressionCode} but is {syntaxTreeSource}.");

            var expression = (ExpressionSyntax)syntaxTree.Root;

            var compilation         = new HlslTools.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 == Diagnostics.DiagnosticSeverity.Error);
            var result     = diagnostic == null
                ? $"{SymbolMarkup.ForSymbol(invokedFunctionSymbol.Parameters[0].ValueType)}, {SymbolMarkup.ForSymbol(invokedFunctionSymbol.Parameters[1].ValueType)}"
                : ExpressionTestUtility.GetErrorString(diagnostic.DiagnosticId);

            Assert.AreEqual(expectedMatchTypes, result, $"Expression should have matched the function overload '{expectedMatchTypes}' but it actually matched '{result}'.");
        }
Esempio n. 2
0
        public void TestPrefixUnaryOperatorTypeConversions(string opText, string argumentText, string expectedResult)
        {
            var argument         = ExpressionTestUtility.GetValue(argumentText);
            var source           = $"{opText}{argument}";
            var syntaxTree       = SyntaxFactory.ParseExpression(source);
            var syntaxTreeSource = syntaxTree.Root.ToString();

            if (syntaxTreeSource != source)
            {
                Assert.Fail($"Source should have been {syntaxTreeSource} but is {source}");
            }

            var expression    = (PrefixUnaryExpressionSyntax)syntaxTree.Root;
            var compilation   = new HlslTools.Compilation.Compilation(syntaxTree);
            var semanticModel = compilation.GetSemanticModel();

            var operandType = ExpressionTestUtility.GetExpressionTypeString(semanticModel.GetExpressionType(expression.Operand));

            if (argumentText != operandType)
            {
                Assert.Fail($"Operand should be of type '{argumentText}' but has type '{operandType}'");
            }

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

            Assert.AreEqual(expectedResult, result, $"Expression {source} should have evaluated to '{expectedResult}' but was '{result}'");
        }
        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.AreEqual(code, syntaxTreeSource, $"Source should have been {code} but is {syntaxTreeSource}.");

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

            var compilation         = new HlslTools.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 == Diagnostics.DiagnosticSeverity.Error);
            var result     = diagnostic == null
                ? $"{SymbolMarkup.ForSymbol(invokedFunctionSymbol.Parameters[0].ValueType)}, {SymbolMarkup.ForSymbol(invokedFunctionSymbol.Parameters[1].ValueType)}"
                : ExpressionTestUtility.GetErrorString(diagnostic.DiagnosticId);

            Assert.AreEqual(expectedMatchTypes, result, $"Expression should have matched the function overload '{expectedMatchTypes}' but it actually matched '{result}'.");
        }