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 bool ParseVariableDeclarationStatementSyntax(VariableDeclarationStatementSyntax syntax, List <string> registers) { VariableDeclarationSyntax varDeclaration = syntax.Declaration; TypeSyntax type = varDeclaration.Type; foreach (VariableDeclaratorSyntax var in varDeclaration.Variables) { AnnotationFactory.BeginVar(); AnnotationFactory.SetModifiers(varDeclaration.Modifiers); if (AnnotationFactory.IsGroupOpen()) { AnnotationFactory.SetType(type); AnnotationFactory.SetAnnotations(var.Annotations?.Annotations ?? null); InitializerSyntax initializer = var.Initializer; if (varDeclaration.Variables[0].ArrayRankSpecifiers.Count > 0) { LiteralExpressionSyntax litExpressionSyntax = varDeclaration.Variables[0].ArrayRankSpecifiers[0].Dimension as LiteralExpressionSyntax; AnnotationFactory.SetDimension((int)litExpressionSyntax.Token.Value); } if (initializer != null && initializer is EqualsValueClauseSyntax) { EqualsValueClauseSyntax evcSyntax = (EqualsValueClauseSyntax)initializer; if (evcSyntax.Value is NumericConstructorInvocationExpressionSyntax) { NumericConstructorInvocationExpressionSyntax ncieSyntax = (NumericConstructorInvocationExpressionSyntax)evcSyntax.Value; SeparatedSyntaxList <ExpressionSyntax> arguments = ncieSyntax.ArgumentList.Arguments; } else if (evcSyntax.Value is LiteralExpressionSyntax) { } } SyntaxToken name = var.Identifier; AnnotationFactory.SetName(name.ValueText); foreach (var qualifier in var.Qualifiers) { if (qualifier is RegisterLocation) { string register = ((RegisterLocation)qualifier).Register.ValueText; if (registers.Contains(register)) { MessageBox.Show($"Register: {register}\nDefined multiple times, ShaderBox can not decides which one needs to be binded.\n\nWill be resolved in a future release.", "Unsupported operation", MessageBoxButton.OK, MessageBoxImage.Error); AnnotationFactory.DestroyGroup(); return(false); } AnnotationFactory.SetRegister(register); } } if (string.IsNullOrWhiteSpace(AnnotationFactory.GetRegister())) { AnnotationFactory.DestroyGroup(); } else { AnnotationFactory.EndVar(); } } } return(true); }