Inheritance: ExpressionSyntax
示例#1
0
 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);
 }
示例#2
0
        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());
            }
        }
示例#3
0
        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;
            }
        }