示例#1
0
        public static QuickInfoModel ForSymbol(SemanticModel semanticModel, TextSpan span, Symbol symbol)
        {
            var glyph        = symbol.GetGlyph();
            var symbolMarkup = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, glyph, symbolMarkup, symbol.Documentation));
        }
示例#2
0
        public static QuickInfoModel ForMacroReference(SemanticModel semanticModel, TextSpan span, MacroReference macroReference)
        {
            var glyph        = Glyph.Macro;
            var symbolMarkup = new SymbolMarkup(new[] { new SymbolMarkupToken(SymbolMarkupKind.PlainText, $"(macro reference) {macroReference.DefineDirective.ToString(true)}") });

            return(new QuickInfoModel(semanticModel, span, glyph, symbolMarkup, string.Empty));
        }
        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}'.");
        }
 private static void AppendMarkup(this StringBuilder sb, SymbolMarkup symbolMarkup, INQueryClassificationTypes classificationTypes, IHighlightingStyleRegistry highlightingStyleRegistry)
 {
     foreach (var node in symbolMarkup.Tokens)
     {
         sb.AppendNode(node, classificationTypes, highlightingStyleRegistry);
     }
 }
示例#5
0
 public QuickInfoModel(SemanticModel semanticModel, TextSpan span, Glyph glyph, SymbolMarkup markup)
 {
     SemanticModel = semanticModel;
     Span          = span;
     Glyph         = glyph;
     Markup        = markup;
 }
示例#6
0
        public IContentProvider GetContentProvider(Glyph glyph, SymbolMarkup symbolMarkup)
        {
            var classificationTypes = ClassificationTypes;
            var registry            = AmbientHighlightingStyleRegistry.Instance;

            return(HtmlContentProviderWithGlyph.Create(glyph, symbolMarkup, classificationTypes, registry));
        }
示例#7
0
        public static QuickInfoModel ForMacroDefinition(SemanticModel semanticModel, TextSpan span, DefineDirectiveTriviaSyntax macroDefinition)
        {
            var glyph        = Glyph.Macro;
            var symbolMarkup = new SymbolMarkup(new[] { new SymbolMarkupToken(SymbolMarkupKind.PlainText, $"(macro definition) {macroDefinition}") });

            return(new QuickInfoModel(semanticModel, span, glyph, symbolMarkup, string.Empty));
        }
        public static string GetHtml(Glyph glyph, SymbolMarkup symbolMarkup, INQueryClassificationTypes classificationTypes, IHighlightingStyleRegistry highlightingStyleRegistry)
        {
            var sb = new StringBuilder();

            sb.AppendGlyph(glyph);
            sb.AppendMarkup(symbolMarkup, classificationTypes, highlightingStyleRegistry);
            return(sb.ToString());
        }
示例#9
0
 private QuickInfoModel(SemanticModel semanticModel, TextSpan span, Glyph glyph, SymbolMarkup markup, string documentation)
 {
     SemanticModel = semanticModel;
     Span          = span;
     Glyph         = glyph;
     Markup        = markup;
     Documentation = documentation;
 }
示例#10
0
 private QuickInfoModel(SemanticModel semanticModel, TextSpan span, Glyph glyph, SymbolMarkup markup, string documentation)
 {
     SemanticModel = semanticModel;
     Span = span;
     Glyph = glyph;
     Markup = markup;
     Documentation = documentation;
 }
示例#11
0
        private static CompletionItem CreateSymbolCompletion(Symbol symbol)
        {
            var displayText   = symbol.Name;
            var insertionText = symbol.Name;
            var description   = SymbolMarkup.ForSymbol(symbol).ToString();
            var glyph         = symbol.GetGlyph();

            return(new CompletionItem(displayText, insertionText, description, glyph, symbol));
        }
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <CoalesceExpressionSyntax>().Single();
            var span       = syntax.CoalesceKeyword.Span;
            var markup     = SymbolMarkup.ForCoalesceSymbol();

            return(new QuickInfoModel(semanticModel, span, Glyph.Function, markup));
        }
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <CountAllExpressionSyntax>().Single();
            var span       = syntax.Name.Span;
            var symbol     = GetCountAggregate(semanticModel.Compilation.DataContext);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.Aggregate, markup));
        }
示例#14
0
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <WildcardSelectColumnSyntax>().Single();
            var span       = syntax.TableName.Span;
            var symbol     = semanticModel.GetTableInstance(syntax);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.TableInstance, markup));
        }
示例#15
0
        private TextBlock GetTextBlock(SymbolMarkup markup)
        {
            var textBlock = new TextBlock
            {
                TextWrapping = TextWrapping.Wrap
            };

            textBlock.Inlines.AddRange(markup.Tokens.Select(GetInline));
            return(textBlock);
        }
示例#16
0
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <PropertyAccessExpressionSyntax>().Single();
            var span       = syntax.Name.Span;
            var symbol     = semanticModel.GetSymbol(syntax);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.Property, markup));
        }
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <ExpressionSelectColumnSyntax>().Single();
            var span       = syntax.Alias.Identifier.Span;
            var symbol     = semanticModel.GetDeclaredSymbol(syntax);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.Column, markup));
        }
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <DerivedTableReferenceSyntax>().Single();
            var span       = syntax.Name.Span;
            var symbol     = semanticModel.GetDeclaredSymbol(syntax);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.TableInstance, markup));
        }
示例#19
0
        protected override QuickInfoModel CreateExpectedModel(SemanticModel semanticModel)
        {
            var syntaxTree = semanticModel.SyntaxTree;
            var syntax     = syntaxTree.Root.DescendantNodes().OfType <MethodInvocationExpressionSyntax>().Last();
            var span       = syntax.Name.Span;
            var symbol     = semanticModel.GetSymbol(syntax);
            var markup     = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, Glyph.Method, markup));
        }
示例#20
0
        private TextBlock GetTextBlock(SymbolMarkup markup)
        {
            var textBlock = new TextBlock
            {
                VerticalAlignment = VerticalAlignment.Center,
                FontFamily        = new FontFamily(@"Consolas")
            };

            textBlock.Inlines.AddRange(markup.Tokens.Select(GetInline));
            return(textBlock);
        }
示例#21
0
        public static QuickInfoModel ForSymbol(SemanticModel semanticModel, TextSpan span, Symbol symbol)
        {
            if (symbol.Kind == SymbolKind.ErrorTable)
            {
                return(null);
            }

            var glyph        = symbol.GetGlyph();
            var symbolMarkup = SymbolMarkup.ForSymbol(symbol);

            return(new QuickInfoModel(semanticModel, span, glyph, symbolMarkup));
        }
        private static void AssertIsMatch(string query, Type type, string propertyName)
        {
            var completionModel = GetCompletionModel(query);
            var semanticModel   = completionModel.SemanticModel;

            var property       = semanticModel.LookupProperties(type).Single(p => p.Name == propertyName);
            var propertyItem   = completionModel.Items.Single(i => i.InsertionText == property.Name);
            var propertyMarkup = SymbolMarkup.ForSymbol(property);

            Assert.Equal(Glyph.Property, propertyItem.Glyph);
            Assert.Equal(property.Name, propertyItem.DisplayText);
            Assert.Equal(propertyMarkup.ToString(), propertyItem.Description);
            Assert.Equal(property, propertyItem.Symbol);
        }
示例#23
0
        private static SignatureItem ToSignatureItem <TSymbol>(this TSymbol symbol, Func <SymbolMarkupToken, bool> separatorPredicate)
            where TSymbol : InvocableSymbol
        {
            var markup = SymbolMarkup.ForSymbol(symbol);

            var sb             = new StringBuilder();
            var parameterStart = 0;
            var nextNonWhitespaceStartsParameter = false;
            var parameterSpans        = new List <TextSpan>();
            var parameterNamesAndDocs = new List <Tuple <string, string> >();

            foreach (var node in markup.Tokens)
            {
                var isParameterName    = node.Kind == SymbolMarkupKind.ParameterName;
                var isWhitespace       = node.Kind == SymbolMarkupKind.Whitespace;
                var isLeftParenthesis  = node.Kind == SymbolMarkupKind.Punctuation && node.Text == "(";
                var isRightParenthesis = node.Kind == SymbolMarkupKind.Punctuation && node.Text == ")";
                var isSeparator        = separatorPredicate(node);

                if (isParameterName)
                {
                    parameterNamesAndDocs.Add(Tuple.Create(node.Text, symbol.Parameters[parameterNamesAndDocs.Count].Documentation));
                }

                if (isLeftParenthesis)
                {
                    nextNonWhitespaceStartsParameter = true;
                }
                else if (isSeparator || isRightParenthesis)
                {
                    var end  = sb.Length;
                    var span = TextSpan.FromBounds(null, parameterStart, end);
                    parameterSpans.Add(span);
                    nextNonWhitespaceStartsParameter = true;
                }
                else if (!isWhitespace && nextNonWhitespaceStartsParameter)
                {
                    parameterStart = sb.Length;
                    nextNonWhitespaceStartsParameter = false;
                }

                sb.Append(node.Text);
            }

            var parameters = parameterSpans
                             .Zip(parameterNamesAndDocs, (s, n) => new ParameterItem(n.Item1, n.Item2, s))
                             .ToImmutableArray();

            return(new SignatureItem(symbol, sb.ToString(), symbol.Documentation, parameters));
        }
        private static void AssertIsMatch(string query, string tableName)
        {
            var completionModel = GetCompletionModel(query);
            var dataContext     = completionModel.SemanticModel.Compilation.DataContext;

            var table       = dataContext.Tables.Single(t => t.Name == tableName);
            var tableItem   = completionModel.Items.Single(i => i.InsertionText == table.Name);
            var tableMarkup = SymbolMarkup.ForSymbol(table);

            Assert.Equal(Glyph.Table, tableItem.Glyph);
            Assert.Equal(table.Name, tableItem.DisplayText);
            Assert.Equal(tableMarkup.ToString(), tableItem.Description);
            Assert.Equal(table, tableItem.Symbol);
        }
示例#25
0
        private static void AssertIsMatch(string query, string functionName)
        {
            var completionModel = GetCompletionModel(query);
            var dataContext     = completionModel.SemanticModel.Compilation.DataContext;

            var function       = dataContext.Functions.Single(t => t.Name == functionName);
            var functionItem   = completionModel.Items.Single(i => i.InsertionText == function.Name);
            var functionMarkup = SymbolMarkup.ForSymbol(function);

            Assert.Equal(Glyph.Function, functionItem.Glyph);
            Assert.Equal(function.Name, functionItem.DisplayText);
            Assert.Equal(functionMarkup.ToString(), functionItem.Description);
            Assert.Equal(function, functionItem.Symbol);
        }
示例#26
0
        private static void GetCompletionData(string query, string tableInstanceName, string columnName, out TableColumnInstanceSymbol column, out CompletionItem columnItem, out SymbolMarkup columnMarkup)
        {
            var completionModel = GetCompletionModel(query);
            var semanticModel   = completionModel.SemanticModel;
            var syntaxTree      = semanticModel.SyntaxTree;

            var tableReference = syntaxTree.Root.DescendantNodesAndSelf()
                                 .OfType <NamedTableReferenceSyntax>()
                                 .Select(semanticModel.GetDeclaredSymbol)
                                 .Single(s => s != null && s.Name == tableInstanceName);

            column       = tableReference.ColumnInstances.Single(c => c.Name == columnName);
            columnItem   = completionModel.Items.Single(i => i.InsertionText == columnName);
            columnMarkup = SymbolMarkup.ForSymbol(column);
        }
        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}'.");
        }
        private static SignatureItem ToSignatureItem(this SymbolMarkup markup, Func <SymbolMarkupToken, bool> separatorPredicate)
        {
            var sb             = new StringBuilder();
            var parameterStart = 0;
            var nextNonWhitespaceStartsParameter = false;
            var parameterSpans = new List <TextSpan>();
            var parameterNames = new List <string>();

            foreach (var node in markup.Tokens)
            {
                var isParameterName    = node.Kind == SymbolMarkupKind.ParameterName;
                var isWhitespace       = node.Kind == SymbolMarkupKind.Whitespace;
                var isLeftParenthesis  = node.Kind == SymbolMarkupKind.Punctuation && node.Text == @"(";
                var isRightParenthesis = node.Kind == SymbolMarkupKind.Punctuation && node.Text == @")";
                var isSeparator        = separatorPredicate(node);

                if (isParameterName)
                {
                    parameterNames.Add(node.Text);
                }

                if (isLeftParenthesis)
                {
                    nextNonWhitespaceStartsParameter = true;
                }
                else if (isSeparator || isRightParenthesis)
                {
                    var end  = sb.Length;
                    var span = TextSpan.FromBounds(parameterStart, end);
                    parameterSpans.Add(span);
                    nextNonWhitespaceStartsParameter = true;
                }
                else if (!isWhitespace && nextNonWhitespaceStartsParameter)
                {
                    parameterStart = sb.Length;
                    nextNonWhitespaceStartsParameter = false;
                }

                sb.Append(node.Text);
            }

            var parameters = parameterSpans.Zip(parameterNames, (s, n) => new ParameterItem(n, s)).ToImmutableArray();
            var content    = sb.ToString();

            return(new SignatureItem(content, parameters));
        }
示例#29
0
        private static void AssertIsMatch(string query, Type type, string methodName)
        {
            var completionModel = GetCompletionModel(query);
            var semanticModel   = completionModel.SemanticModel;

            var method = semanticModel.LookupMethods(type)
                         .Where(m => m.Name == methodName)
                         .OrderBy(m => m.Parameters.Length)
                         .First();
            var methodItem   = completionModel.Items.Single(i => i.InsertionText == method.Name);
            var methodMarkup = SymbolMarkup.ForSymbol(method);

            var overloadCount = semanticModel.LookupMethods(type)
                                .Count(m => m.Name == methodName) - 1;
            var expectedDescription = overloadCount == 0
                ? methodMarkup.ToString()
                : $"{methodMarkup} (+ {overloadCount} overload(s))";

            Assert.Equal(Glyph.Method, methodItem.Glyph);
            Assert.Equal(method.Name, methodItem.DisplayText);
            Assert.Equal(expectedDescription, methodItem.Description);
        }
示例#30
0
 public static QuickInfoModel ForMacroDefinition(SemanticModel semanticModel, TextSpan span, DefineDirectiveTriviaSyntax macroDefinition)
 {
     var glyph = Glyph.Macro;
     var symbolMarkup = new SymbolMarkup(new[] { new SymbolMarkupToken(SymbolMarkupKind.PlainText, $"(macro definition) {macroDefinition}") });
     return new QuickInfoModel(semanticModel, span, glyph, symbolMarkup, string.Empty);
 }
示例#31
0
 public static QuickInfoModel ForMacroReference(SemanticModel semanticModel, TextSpan span, MacroReference macroReference)
 {
     var glyph = Glyph.Macro;
     var symbolMarkup = new SymbolMarkup(new[] { new SymbolMarkupToken(SymbolMarkupKind.PlainText, $"(macro reference) {macroReference.DefineDirective.ToString(true)}") });
     return new QuickInfoModel(semanticModel, span, glyph, symbolMarkup, string.Empty);
 }
示例#32
0
 private TextBlock GetTextBlock(SymbolMarkup markup)
 {
     var textBlock = new TextBlock
     {
         TextWrapping = TextWrapping.Wrap
     };
     textBlock.Inlines.AddRange(markup.Tokens.Select(GetInline));
     return textBlock;
 }
        protected override QuickInfoModel CreateModel(SemanticModel semanticModel, int position, CoalesceExpressionSyntax node)
        {
            var keywordSpan = node.CoalesceKeyword.Span;

            return(!keywordSpan.ContainsOrTouches(position)
                       ? null
                       : new QuickInfoModel(semanticModel, keywordSpan, Glyph.Function, SymbolMarkup.ForCoalesceSymbol()));
        }
        public static HtmlContentProvider Create(Glyph glyph, SymbolMarkup symbolMarkup, INQueryClassificationTypes classificationTypes, IHighlightingStyleRegistry highlightingStyleRegistry)
        {
            var htmlSnippet = HtmlMarkupEmitter.GetHtml(glyph, symbolMarkup, classificationTypes, highlightingStyleRegistry);

            return(new HtmlContentProviderWithGlyph(htmlSnippet));
        }