protected FunctionSyntax(SyntaxKind kind, List<AttributeSyntax> attributes, List<SyntaxToken> modifiers, TypeSyntax returnType, DeclarationNameSyntax name, ParameterListSyntax parameterList, SemanticSyntax semantic) : base(kind) { RegisterChildNodes(out Attributes, attributes); RegisterChildNodes(out Modifiers, modifiers); RegisterChildNode(out ReturnType, returnType); RegisterChildNode(out Name, name); RegisterChildNode(out ParameterList, parameterList); RegisterChildNode(out Semantic, semantic); }
private BoundType BindType(TypeSyntax syntax, Symbol parent) { switch (syntax.Kind) { case SyntaxKind.PredefinedScalarType: return BindScalarType((ScalarTypeSyntax) syntax); case SyntaxKind.PredefinedVectorType: return BindVectorType((VectorTypeSyntax) syntax); case SyntaxKind.PredefinedGenericVectorType: return BindGenericVectorType((GenericVectorTypeSyntax) syntax); case SyntaxKind.PredefinedMatrixType: return BindMatrixType((MatrixTypeSyntax) syntax); case SyntaxKind.PredefinedGenericMatrixType: return BindGenericMatrixType((GenericMatrixTypeSyntax) syntax); case SyntaxKind.PredefinedObjectType: return new BoundObjectType(BindObjectType((PredefinedObjectTypeSyntax) syntax)); case SyntaxKind.StructType: { // Inline struct. return BindStructDeclaration((StructTypeSyntax) syntax, parent); } case SyntaxKind.IdentifierName: { var identifierName = (IdentifierNameSyntax) syntax; var symbols = LookupTypeSymbol(identifierName.Name).ToImmutableArray(); if (symbols.Length == 0) { Diagnostics.ReportUndeclaredType(syntax); return new BoundUnknownType(); } if (symbols.Length > 1) Diagnostics.ReportAmbiguousType(identifierName.Name, symbols); return new BoundName(symbols.First()); } case SyntaxKind.QualifiedName: { var qualifiedName = (QualifiedNameSyntax) syntax; return BindQualifiedType(qualifiedName); } default: throw new InvalidOperationException(syntax.Kind.ToString()); } }
private static string GetFunctionDescription(TypeSyntax returnType, SyntaxToken name, ParameterListSyntax parameterList, bool includeReturnType, bool includeParameterNames) { var result = new StringBuilder(); if (includeReturnType) result.Append($"{returnType.ToStringIgnoringMacroReferences()} "); result.Append(name.GetFullyQualifiedName()); result.Append("("); for (var i = 0; i < parameterList.Parameters.Count; i++) { var parameter = parameterList.Parameters[i]; result.Append(parameter.GetDescription(includeParameterNames)); if (i < parameterList.Parameters.Count - 1) result.Append(", "); } result.Append(")"); return result.ToString().Replace(Environment.NewLine, string.Empty); }
private void ParseVariableDeclaration(out TypeSyntax type, List<SyntaxNode> variables) { type = ParseType(false); ParseVariableDeclarators(type, variables, variableDeclarationsExpected: true); }
private VariableDeclaratorSyntax ParseVariableDeclarator(TypeSyntax parentType, bool isExpressionContext = false) { if (!isExpressionContext) { // Check for the common pattern of: // // C //<-- here // Console.WriteLine(); // // Standard greedy parsing will assume that this should be parsed as a variable // declaration: "C Console". We want to avoid that as it can confused parts of the // system further up. So, if we see certain things following the identifier, then we can // assume it's not the actual name. // // So, if we're after a newline and we see a name followed by the list below, then we // assume that we're accidently consuming too far into the next statement. // // <dot>, <arrow>, any binary operator (except =), <question>. None of these characters // are allowed in a normal variable declaration. This also provides a more useful error // message to the user. Instead of telling them that a semicolon is expected after the // following token, then instead get a useful message about an identifier being missing. // The above list prevents: // // C //<-- here // Console.WriteLine(); // // C //<-- here // Console->WriteLine(); // // C // A + B; // etc. // // C // A ? B : D; var resetPoint = GetResetPoint(); try { var currentTokenKind = Current.Kind; if (currentTokenKind == SyntaxKind.IdentifierToken && !parentType.IsMissing) { var isAfterNewLine = parentType.GetLastChildToken().TrailingTrivia.Any(t => t.Kind == SyntaxKind.EndOfLineTrivia); if (isAfterNewLine) { NextToken(); currentTokenKind = Current.Kind; var isNonEqualsBinaryToken = currentTokenKind != SyntaxKind.EqualsToken && SyntaxFacts.IsBinaryExpression(currentTokenKind); if (currentTokenKind == SyntaxKind.DotToken || isNonEqualsBinaryToken) { var missingIdentifier = InsertMissingToken(SyntaxKind.IdentifierToken); return new VariableDeclaratorSyntax(missingIdentifier, new List<ArrayRankSpecifierSyntax>(), new List<VariableDeclaratorQualifierSyntax>(), null, null); } } } } finally { Reset(ref resetPoint); } } var name = Match(SyntaxKind.IdentifierToken); var arrayRankSpecifiers = new List<ArrayRankSpecifierSyntax>(); if (Current.Kind == SyntaxKind.OpenBracketToken) ParseArrayRankSpecifiers(arrayRankSpecifiers, false); var qualifiers = new List<VariableDeclaratorQualifierSyntax>(); while (Current.Kind == SyntaxKind.ColonToken) { if (IsPossibleVariableDeclaratorQualifier(Lookahead)) { qualifiers.Add(ParseVariableDeclaratorQualifier()); } else { var action = SkipBadTokens( p => !p.IsPossibleVariableDeclaratorQualifier(Current), p => p.Current.Kind == SyntaxKind.EqualsToken || p.Current.Kind == SyntaxKind.OpenBraceToken || p.IsTerminator(), SyntaxKind.RegisterKeyword); if (action == PostSkipAction.Abort) break; } } AnnotationsSyntax annotations = null; if (Current.Kind == SyntaxKind.LessThanToken) annotations = ParseAnnotations(); InitializerSyntax initializer = null; if (Current.Kind == SyntaxKind.EqualsToken) { if (Lookahead.Kind == SyntaxKind.SamplerStateLegacyKeyword) { initializer = ParseSamplerStateInitializer(); } else { var equals = NextToken(); var init = ParseVariableInitializer(); initializer = new EqualsValueClauseSyntax(equals, init); } } else if (Current.Kind == SyntaxKind.OpenBraceToken) { if (Lookahead.Kind == SyntaxKind.OpenBraceToken) initializer = ParseStateArrayInitializer(); else initializer = ParseStateInitializer(); } return new VariableDeclaratorSyntax(name, arrayRankSpecifiers, qualifiers, annotations, initializer); }
private void ParseVariableDeclarators(TypeSyntax type, List<SyntaxNode> variables, bool variableDeclarationsExpected) { variables.Add(ParseVariableDeclarator(type)); while (true) { if (Current.Kind == SyntaxKind.SemiToken) break; if (Current.Kind == SyntaxKind.CommaToken) { variables.Add(Match(SyntaxKind.CommaToken)); variables.Add(ParseVariableDeclarator(type)); continue; } break; } }