public BoundFunctionInvocationExpression(FunctionInvocationExpressionSyntax syntax, ImmutableArray <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression) { Syntax = syntax; Arguments = arguments; Result = result; }
public BoundFunctionInvocationExpression(FunctionInvocationExpressionSyntax syntax, ImmutableArray<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression) { Syntax = syntax; Arguments = arguments; Result = result; }
private ExpressionSyntax ParseDirectiveTerm() { ExpressionSyntax expr; var tk = Current.Kind; switch (tk) { case SyntaxKind.IdentifierToken: expr = ParseIdentifier(); break; case SyntaxKind.FalseKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.IntegerLiteralToken: case SyntaxKind.FloatLiteralToken: expr = new LiteralExpressionSyntax(SyntaxFacts.GetLiteralExpression(Current.Kind), NextToken()); break; case SyntaxKind.OpenParenToken: expr = ParseDirectiveParenthesizedExpression(); break; default: expr = CreateMissingIdentifierName(); if (tk == SyntaxKind.EndOfFileToken) { expr = WithDiagnostic(expr, DiagnosticId.ExpressionExpected); } else { expr = WithDiagnostic(expr, DiagnosticId.InvalidExprTerm, tk.GetText()); } break; } // Might be function invocation. We only have one function in the preprocessor - "defined". if (Current.Kind == SyntaxKind.OpenParenToken && expr.Kind == SyntaxKind.IdentifierName && ((IdentifierNameSyntax)expr).Name.ContextualKind == SyntaxKind.DefinedKeyword) { _lexer.ExpandMacros = false; var openParen = Match(SyntaxKind.OpenParenToken); var name = new IdentifierNameSyntax(NextToken()); _lexer.ExpandMacros = true; var closeParen = Match(SyntaxKind.CloseParenToken); expr = new FunctionInvocationExpressionSyntax((IdentifierNameSyntax)expr, new ArgumentListSyntax( openParen, new SeparatedSyntaxList <ExpressionSyntax>(new List <SyntaxNodeBase> { name }), closeParen)); } return(expr); }
private BoundExpression BindFunctionInvocationExpression(FunctionInvocationExpressionSyntax syntax) { // Don't try to bind CompileShader function calls, for now. if ((syntax.Name.Kind == SyntaxKind.IdentifierName) && ((IdentifierNameSyntax)syntax.Name).Name.ContextualKind == SyntaxKind.CompileShaderKeyword) { return(new BoundFunctionInvocationExpression(syntax, syntax.ArgumentList.Arguments.Select(x => (BoundExpression) new BoundErrorExpression()).ToImmutableArray(), OverloadResolutionResult <FunctionSymbolSignature> .None)); } var name = syntax.Name; var boundArguments = BindArgumentList(syntax.ArgumentList); var argumentTypes = boundArguments.Select(a => a.Type).ToImmutableArray(); var anyErrorsInArguments = argumentTypes.Any(a => a.IsError()); if (anyErrorsInArguments) { return(new BoundFunctionInvocationExpression(syntax, boundArguments, OverloadResolutionResult <FunctionSymbolSignature> .None)); } ContainerSymbol containerSymbol; SyntaxToken actualName; switch (name.Kind) { case SyntaxKind.IdentifierName: containerSymbol = null; actualName = ((IdentifierNameSyntax)name).Name; break; case SyntaxKind.QualifiedName: containerSymbol = LookupContainer(((QualifiedNameSyntax)syntax.Name).Left); actualName = ((QualifiedNameSyntax)name).Right.Name; break; default: throw new InvalidOperationException(); } var result = (containerSymbol?.Binder ?? this).LookupFunction(actualName, argumentTypes); if (result.Best == null) { if (result.Selected == null) { Diagnostics.ReportUndeclaredFunction(syntax, argumentTypes); return(new BoundErrorExpression()); } var symbol1 = result.Selected.Signature.Symbol; var symbol2 = result.Candidates.First(c => !c.Signature.Symbol.Equals(symbol1)).Signature.Symbol; Diagnostics.ReportAmbiguousInvocation(syntax.GetTextSpanSafe(), symbol1, symbol2, argumentTypes); } var convertedArguments = boundArguments.Select((a, i) => BindArgument(a, result, i, syntax.ArgumentList.Arguments[i].GetTextSpanSafe())).ToImmutableArray(); return(new BoundFunctionInvocationExpression(syntax, convertedArguments, result)); }
private BoundExpression BindAggregateInvocationExpression(FunctionInvocationExpressionSyntax node, AggregateSymbol aggregate) { var argument = node.ArgumentList.Arguments[0]; var argumentBinder = CreateAggregateArgumentBinder(); var boundArgument = argumentBinder.BindExpression(argument); var boundAggregatable = BindAggregatable(node.Span, aggregate, boundArgument); var boundAggregate = new BoundAggregateExpression(aggregate, boundAggregatable, boundArgument); return(BindAggregate(node, boundAggregate)); }
public override void VisitFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { var symbol = _semanticModel.GetSymbol(node); if (symbol != null) { CreateTag(node.Name.GetUnqualifiedName().Name, HlslClassificationTypeNames.FunctionIdentifier); } base.VisitFunctionInvocationExpression(node); }
private ExpressionSyntax ParseSubExpression(uint precedence) { if (Current.Kind == SyntaxKind.CompileKeyword) { var compile = Match(SyntaxKind.CompileKeyword); var shaderTarget = Match(SyntaxKind.IdentifierToken); var shaderFunctionName = ParseIdentifier(); var shaderFunction = new FunctionInvocationExpressionSyntax(shaderFunctionName, ParseParenthesizedArgumentList(false)); return new CompileExpressionSyntax(compile, shaderTarget, shaderFunction); } ExpressionSyntax leftOperand; SyntaxKind opKind; // No left operand, so we need to parse one -- possibly preceded by a // unary operator. var tk = Current.Kind; if (SyntaxFacts.IsPrefixUnaryExpression(tk)) { opKind = SyntaxFacts.GetPrefixUnaryExpression(tk); leftOperand = ParsePrefixUnaryExpression(opKind); } else { // Not a unary operator - get a primary expression. leftOperand = ParseTerm(); } while (true) { // We either have a binary or assignment or compound operator here, or we're finished. tk = Current.Kind; ExpressionOperatorType operatorType; if (SyntaxFacts.IsBinaryExpression(tk) && (!_greaterThanTokenIsNotOperator || tk != SyntaxKind.GreaterThanToken) && (tk != SyntaxKind.GreaterThanToken || !_allowGreaterThanTokenAroundRhsExpression || Lookahead.Kind != SyntaxKind.SemiToken)) { operatorType = ExpressionOperatorType.BinaryExpression; opKind = SyntaxFacts.GetBinaryExpression(tk); } else if (SyntaxFacts.IsAssignmentExpression(tk)) { operatorType = ExpressionOperatorType.AssignmentExpression; opKind = SyntaxFacts.GetAssignmentExpression(tk); } else if (tk == SyntaxKind.CommaToken && CommaIsSeparatorStack.Peek() == false) { operatorType = ExpressionOperatorType.CompoundExpression; opKind = SyntaxKind.CompoundExpression; } else { break; } var newPrecedence = SyntaxFacts.GetOperatorPrecedence(opKind); Debug.Assert(newPrecedence > 0); // All binary operators must have precedence > 0! // Check the precedence to see if we should "take" this operator if (newPrecedence < precedence) break; // Same precedence, but not right-associative -- deal with this "later" if (newPrecedence == precedence && !SyntaxFacts.IsRightAssociative(opKind)) break; // Precedence is okay, so we'll "take" this operator. var opToken = NextToken(); SyntaxToken lessThanToken = null; if (operatorType == ExpressionOperatorType.AssignmentExpression && _allowGreaterThanTokenAroundRhsExpression) lessThanToken = NextTokenIf(SyntaxKind.LessThanToken); var rightOperand = ParseSubExpression(newPrecedence); SyntaxToken greaterThanToken = null; if (lessThanToken != null) greaterThanToken = NextTokenIf(SyntaxKind.GreaterThanToken); switch (operatorType) { case ExpressionOperatorType.BinaryExpression: leftOperand = new BinaryExpressionSyntax(opKind, leftOperand, opToken, rightOperand); break; case ExpressionOperatorType.AssignmentExpression: leftOperand = new AssignmentExpressionSyntax(opKind, leftOperand, opToken, lessThanToken, rightOperand, greaterThanToken); break; case ExpressionOperatorType.CompoundExpression: leftOperand = new CompoundExpressionSyntax(opKind, leftOperand, opToken, rightOperand); break; default: throw new ArgumentOutOfRangeException(); } } var conditionalPrecedence = SyntaxFacts.GetOperatorPrecedence(SyntaxKind.ConditionalExpression); if (tk == SyntaxKind.QuestionToken && precedence <= conditionalPrecedence) { var questionToken = NextToken(); var colonLeft = ParseSubExpression(conditionalPrecedence); var colon = Match(SyntaxKind.ColonToken); var colonRight = ParseSubExpression(conditionalPrecedence); leftOperand = new ConditionalExpressionSyntax(leftOperand, questionToken, colonLeft, colon, colonRight); } return leftOperand; }
public CompileExpressionSyntax(SyntaxToken compileKeyword, SyntaxToken shaderTargetToken, FunctionInvocationExpressionSyntax shaderFunction) : base(SyntaxKind.CompileExpression) { RegisterChildNode(out CompileKeyword, compileKeyword); RegisterChildNode(out ShaderTargetToken, shaderTargetToken); RegisterChildNode(out ShaderFunction, shaderFunction); }
private ExpressionSyntax ParseSubExpression(uint precedence) { if (Current.Kind == SyntaxKind.CompileKeyword) { var compile = Match(SyntaxKind.CompileKeyword); var shaderTarget = Match(SyntaxKind.IdentifierToken); var shaderFunctionName = ParseIdentifier(); var shaderFunction = new FunctionInvocationExpressionSyntax(shaderFunctionName, ParseParenthesizedArgumentList(false)); return(new CompileExpressionSyntax(compile, shaderTarget, shaderFunction)); } ExpressionSyntax leftOperand; SyntaxKind opKind; // No left operand, so we need to parse one -- possibly preceded by a // unary operator. var tk = Current.Kind; if (SyntaxFacts.IsPrefixUnaryExpression(tk)) { opKind = SyntaxFacts.GetPrefixUnaryExpression(tk); leftOperand = ParsePrefixUnaryExpression(opKind); } else { // Not a unary operator - get a primary expression. leftOperand = ParseTerm(); } while (true) { // We either have a binary or assignment or compound operator here, or we're finished. tk = Current.Kind; ExpressionOperatorType operatorType; if (SyntaxFacts.IsBinaryExpression(tk) && (!_greaterThanTokenIsNotOperator || tk != SyntaxKind.GreaterThanToken) && (tk != SyntaxKind.GreaterThanToken || !_allowGreaterThanTokenAroundRhsExpression || Lookahead.Kind != SyntaxKind.SemiToken)) { operatorType = ExpressionOperatorType.BinaryExpression; opKind = SyntaxFacts.GetBinaryExpression(tk); } else if (SyntaxFacts.IsAssignmentExpression(tk)) { operatorType = ExpressionOperatorType.AssignmentExpression; opKind = SyntaxFacts.GetAssignmentExpression(tk); } else if (tk == SyntaxKind.CommaToken && CommaIsSeparatorStack.Peek() == false) { operatorType = ExpressionOperatorType.CompoundExpression; opKind = SyntaxKind.CompoundExpression; } else { break; } var newPrecedence = SyntaxFacts.GetOperatorPrecedence(opKind); Debug.Assert(newPrecedence > 0); // All binary operators must have precedence > 0! // Check the precedence to see if we should "take" this operator if (newPrecedence < precedence) { break; } // Same precedence, but not right-associative -- deal with this "later" if (newPrecedence == precedence && !SyntaxFacts.IsRightAssociative(opKind)) { break; } // Precedence is okay, so we'll "take" this operator. var opToken = NextToken(); SyntaxToken lessThanToken = null; if (operatorType == ExpressionOperatorType.AssignmentExpression && _allowGreaterThanTokenAroundRhsExpression) { lessThanToken = NextTokenIf(SyntaxKind.LessThanToken); } var rightOperand = ParseSubExpression(newPrecedence); SyntaxToken greaterThanToken = null; if (lessThanToken != null) { greaterThanToken = NextTokenIf(SyntaxKind.GreaterThanToken); } switch (operatorType) { case ExpressionOperatorType.BinaryExpression: leftOperand = new BinaryExpressionSyntax(opKind, leftOperand, opToken, rightOperand); break; case ExpressionOperatorType.AssignmentExpression: leftOperand = new AssignmentExpressionSyntax(opKind, leftOperand, opToken, lessThanToken, rightOperand, greaterThanToken); break; case ExpressionOperatorType.CompoundExpression: leftOperand = new CompoundExpressionSyntax(opKind, leftOperand, opToken, rightOperand); break; default: throw new ArgumentOutOfRangeException(); } } var conditionalPrecedence = SyntaxFacts.GetOperatorPrecedence(SyntaxKind.ConditionalExpression); if (tk == SyntaxKind.QuestionToken && precedence <= conditionalPrecedence) { var questionToken = NextToken(); var colonLeft = ParseSubExpression(conditionalPrecedence); var colon = Match(SyntaxKind.ColonToken); var colonRight = ParseSubExpression(conditionalPrecedence); leftOperand = new ConditionalExpressionSyntax(leftOperand, questionToken, colonLeft, colon, colonRight); } return(leftOperand); }
public static void ReportFunctionMissingImplementation(this ICollection <Diagnostic> diagnostics, FunctionInvocationExpressionSyntax syntax) { diagnostics.Report(syntax.Name.SourceRange, DiagnosticId.FunctionMissingImplementation, syntax.Name.ToStringIgnoringMacroReferences()); }
public static void ReportOverloadResolutionFailure(this ICollection <Diagnostic> diagnostics, FunctionInvocationExpressionSyntax node, int argumentCount) { var name = node.Name.ToStringIgnoringMacroReferences(); diagnostics.Report(node.SourceRange, DiagnosticId.FunctionOverloadResolutionFailure, name, argumentCount); }
public static void ReportUndeclaredFunction(this ICollection <Diagnostic> diagnostics, FunctionInvocationExpressionSyntax node, IEnumerable <TypeSymbol> argumentTypes) { var name = node.Name.ToStringIgnoringMacroReferences(); var argumentTypeList = string.Join(@", ", argumentTypes.Select(t => t.ToDisplayName())); diagnostics.Report(node.SourceRange, DiagnosticId.UndeclaredFunction, name, argumentTypeList); }
private ExpressionSyntax ParseDirectiveTerm() { ExpressionSyntax expr; var tk = Current.Kind; switch (tk) { case SyntaxKind.IdentifierToken: expr = ParseIdentifier(); break; case SyntaxKind.FalseKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.IntegerLiteralToken: case SyntaxKind.FloatLiteralToken: expr = new LiteralExpressionSyntax(SyntaxFacts.GetLiteralExpression(Current.Kind), NextToken()); break; case SyntaxKind.OpenParenToken: expr = ParseDirectiveParenthesizedExpression(); break; default: expr = CreateMissingIdentifierName(); if (tk == SyntaxKind.EndOfFileToken) expr = WithDiagnostic(expr, DiagnosticId.ExpressionExpected); else expr = WithDiagnostic(expr, DiagnosticId.InvalidExprTerm, tk.GetText()); break; } // Might be function invocation. We only have one function in the preprocessor - "defined". if (Current.Kind == SyntaxKind.OpenParenToken && expr.Kind == SyntaxKind.IdentifierName && ((IdentifierNameSyntax) expr).Name.ContextualKind == SyntaxKind.DefinedKeyword) { _lexer.ExpandMacros = false; var openParen = Match(SyntaxKind.OpenParenToken); var name = new IdentifierNameSyntax(NextToken()); _lexer.ExpandMacros = true; var closeParen = Match(SyntaxKind.CloseParenToken); expr = new FunctionInvocationExpressionSyntax((IdentifierNameSyntax) expr, new ArgumentListSyntax( openParen, new SeparatedSyntaxList<ExpressionSyntax>(new List<SyntaxNode> { name }), closeParen)); } return expr; }
public virtual void VisitFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { DefaultVisit(node); }
public static void ReportUndeclaredFunction(this ICollection<Diagnostic> diagnostics, FunctionInvocationExpressionSyntax node, IEnumerable<TypeSymbol> argumentTypes) { var name = node.Name.ToStringIgnoringMacroReferences(); var argumentTypeList = string.Join(@", ", argumentTypes.Select(t => t.ToDisplayName())); diagnostics.Report(node.GetTextSpanSafe(), DiagnosticId.UndeclaredFunction, name, argumentTypeList); }
public override void VisitFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { var symbol = _semanticModel.GetSymbol(node); if (symbol != null) CreateTag(node.Name.GetUnqualifiedName().Name, _classificationService.FunctionIdentifier); base.VisitFunctionInvocationExpression(node); }
public static void ReportUndeclaredFunction(this ICollection <Diagnostic> diagnostics, FunctionInvocationExpressionSyntax node, IEnumerable <Type> argumentTypes) { var name = node.Name.ValueText; var argumentTypeList = string.Join(@", ", argumentTypes.Select(t => t.ToDisplayName())); diagnostics.Report(node.Span, DiagnosticId.UndeclaredFunction, name, argumentTypeList); }
private BoundExpression BindFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { if (node.ArgumentList.Arguments.Count == 1) { // Could be an aggregate or a function. var aggregates = LookupAggregate(node.Name).ToImmutableArray(); var funcionCandidate = LookupFunctionWithSingleParameter(node.Name).FirstOrDefault(); if (aggregates.Length > 0) { if (funcionCandidate != null) { var symbols = new Symbol[] { aggregates[0], funcionCandidate }; Diagnostics.ReportAmbiguousName(node.Name, symbols); } else { if (aggregates.Length > 1) { Diagnostics.ReportAmbiguousAggregate(node.Name, aggregates); } var aggregate = aggregates[0]; return(BindAggregateInvocationExpression(node, aggregate)); } } } var name = node.Name; var arguments = node.ArgumentList.Arguments.Select(BindExpression).ToImmutableArray(); var argumentTypes = arguments.Select(a => a.Type).ToImmutableArray(); // To avoid cascading errors, we'll return a node that isn't bound to any function // if we couldn't resolve any of our arguments. var anyErrorsInArguments = argumentTypes.Any(a => a.IsError()); if (anyErrorsInArguments) { return(new BoundFunctionInvocationExpression(arguments, OverloadResolutionResult <FunctionSymbolSignature> .None)); } var result = LookupFunction(name, argumentTypes); if (result.Best == null) { if (result.Selected == null) { Diagnostics.ReportUndeclaredFunction(node, argumentTypes); return(new BoundErrorExpression()); } var symbol1 = result.Selected.Signature.Symbol; var symbol2 = result.Candidates.First(c => c.IsSuitable && c.Signature.Symbol != symbol1).Signature.Symbol; Diagnostics.ReportAmbiguousInvocation(node.Span, symbol1, symbol2, argumentTypes); } // Convert all arguments (if necessary) var convertedArguments = arguments.Select((a, i) => BindArgument(a, result, i)).ToImmutableArray(); return(new BoundFunctionInvocationExpression(convertedArguments, result)); }
public virtual TResult VisitFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { return(DefaultVisit(node)); }
public static void ReportFunctionMissingImplementation(this ICollection<Diagnostic> diagnostics, FunctionInvocationExpressionSyntax syntax) { diagnostics.Report(syntax.Name.GetTextSpanSafe(), DiagnosticId.FunctionMissingImplementation, syntax.Name.ToStringIgnoringMacroReferences()); }
private void ClassifyFunctionInvocationExpression(FunctionInvocationExpressionSyntax node) { ClassifyExpression(node, node.Name); ClassifyNode(node.ArgumentList); }