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); } }
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); }
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); }
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)); }