private CodeExpression ParseMemberOperator(ParserContext parserContext, CodeExpression primaryExpr, bool assignIsEquality, ValueCheck check)
 {
     Token token = parserContext.NextToken();
     if (token.TokenID != TokenID.Identifier)
     {
         if (!parserContext.provideIntellisense || (token.TokenID != TokenID.EndOfInput))
         {
             throw new RuleSyntaxException(0x185, Messages.Parser_MissingIdentifierAfterDot, parserContext.CurrentToken.StartPosition);
         }
         parserContext.SetTypeMemberCompletions(this.validation.ExpressionInfo(primaryExpr).ExpressionType, this.validation.ThisType, primaryExpr is CodeTypeReferenceExpression, this.validation);
         return null;
     }
     string methodName = (string) token.Value;
     int startPosition = token.StartPosition;
     if (parserContext.NextToken().TokenID == TokenID.LParen)
     {
         return this.ParseMethodInvoke(parserContext, primaryExpr, methodName, true);
     }
     return this.ParseFieldOrProperty(parserContext, primaryExpr, methodName, startPosition, assignIsEquality, check);
 }
Example #2
0
        private Type[] ParseGenericTypeArgList(ParserContext parserContext)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.Less);

            List<Type> typeArgs = new List<Type>();

            Token token;
            do
            {
                // Eat the opening '<' or ','.
                token = parserContext.NextToken();

                Type type = TryParseTypeSpecifier(parserContext, true);
                if (type == null)
                    throw new RuleSyntaxException(ErrorNumbers.Error_InvalidTypeArgument, Messages.Parser_InvalidTypeArgument, token.StartPosition);

                typeArgs.Add(type);
            } while (parserContext.CurrentToken.TokenID == TokenID.Comma);

            if (parserContext.CurrentToken.TokenID != TokenID.Greater)
                throw new RuleSyntaxException(ErrorNumbers.Error_MissingCloseAngleBracket, Messages.Parser_MissingCloseAngleBracket, parserContext.CurrentToken.StartPosition);
            parserContext.NextToken(); // Eat the '>'

            return typeArgs.ToArray();
        }
Example #3
0
        // Parse:
        //     array-spec --> type-name
        //                --> type-name  array-rank-specifiers
        //     array-rank-specifiers -->  [  binary-expression  ]
        //                           -->  [  ]
        private Type TryParseTypeSpecifierWithOptionalSize(ParserContext parserContext, bool assignIsEquality, out CodeExpression size)
        {
            Type type = null;
            size = null;

            Token currentToken = parserContext.CurrentToken;
            type = TryParseTypeName(parserContext, assignIsEquality);

            // see if size specified
            if ((type != null) && (parserContext.CurrentToken.TokenID == TokenID.LBracket))
            {
                Token next = parserContext.NextToken();    // skip '['
                // get the size, if specified
                if (next.TokenID != TokenID.RBracket)
                    size = ParseBinaryExpression(parserContext, 0, false, ValueCheck.Read);
                else
                    size = defaultSize;

                if (parserContext.CurrentToken.TokenID != TokenID.RBracket)
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingCloseSquareBracket,
                        Messages.Parser_MissingCloseSquareBracket1,
                        parserContext.CurrentToken.StartPosition);

                parserContext.NextToken();     // Eat the ']'
            }

            return type;
        }
Example #4
0
        internal CodeExpression ParseRootTypeIdentifier(ParserContext parserContext, TypeSymbol typeSym, bool assignIsEquality)
        {
            string message = null;
            int typePosition = parserContext.CurrentToken.StartPosition;

            Token token = parserContext.NextToken();

            if (typeSym.GenericArgCount > 0 && token.TokenID != TokenID.Less)
            {
                // This is a generic type, but no argument list was provided.
                message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_MissingTypeArguments, typeSym.Name);
                throw new RuleSyntaxException(ErrorNumbers.Error_MissingTypeArguments, message, token.StartPosition);
            }

            Type type = typeSym.Type;

            if (token.TokenID == TokenID.Less)
            {
                // Start of a generic argument list... the type had better be generic.
                if (typeSym.GenericArgCount == 0)
                {
                    message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_NotAGenericType, RuleDecompiler.DecompileType(type));
                    throw new RuleSyntaxException(ErrorNumbers.Error_NotAGenericType, message, token.StartPosition);
                }

                Type[] typeArgs = ParseGenericTypeArgList(parserContext);

                if (typeArgs.Length != typeSym.GenericArgCount)
                {
                    message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_BadTypeArgCount, RuleDecompiler.DecompileType(type));
                    throw new RuleSyntaxException(ErrorNumbers.Error_BadTypeArgCount, message, parserContext.CurrentToken.StartPosition);
                }

                // if we are creating generics with design-time types, then the generic needs to be 
                // a wrapped type to create the generic properly, so we look up the generic to get back the wrapper
                type = Validator.ResolveType(type.AssemblyQualifiedName);
                type = type.MakeGenericType(typeArgs);
            }

            token = parserContext.CurrentToken;
            if (token.TokenID == TokenID.Dot)
            {
                Type nestedType = ParseNestedType(parserContext, type);
                if (nestedType != null)
                    type = nestedType;
            }

            return ParseTypeRef(parserContext, type, typePosition, assignIsEquality);
        }
Example #5
0
        private CodeExpression ParseTypeRef(ParserContext parserContext, Type type, int typePosition, bool assignIsEquality)
        {
            CodeExpression result = null;

            if (parserContext.CurrentToken.TokenID == TokenID.LParen)
            {
                // A '(' after a typename is only valid if it's an IRuleExpression.
                if (TypeProvider.IsAssignable(typeof(IRuleExpression), type))
                {
                    int lparenPosition = parserContext.CurrentToken.StartPosition;
                    parserContext.NextToken(); // Eat the '('

                    List<CodeExpression> arguments = ParseArgumentList(parserContext);

                    result = (CodeExpression)ConstructCustomType(type, arguments, lparenPosition);

                    parserContext.exprPositions[result] = lparenPosition;
                    ValidateExpression(parserContext, result, assignIsEquality, ValueCheck.Read);
                    return result;
                }
            }

            CodeTypeReference typeRef = new CodeTypeReference(type);
            validation.AddTypeReference(typeRef, type);

            result = new CodeTypeReferenceExpression(typeRef);
            parserContext.exprPositions[result] = typePosition;
            ValidateExpression(parserContext, result, assignIsEquality, ValueCheck.Read);
            return result;
        }
Example #6
0
        private CodeExpression ParseConstructorArguments(ParserContext parserContext, Type type, bool assignIsEquality)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.LParen);

            // Start of a constructor parameter list.
            int lparenPosition = parserContext.CurrentToken.StartPosition;
            parserContext.NextToken();

            if (parserContext.CurrentToken.TokenID == TokenID.EndOfInput && parserContext.provideIntellisense)
            {
                parserContext.SetConstructorCompletions(type, Validator.ThisType);
                return null;
            }

            List<CodeExpression> arguments = ParseArgumentList(parserContext);

            if ((type.IsValueType) && (arguments.Count == 0))
            {
                // this is always allowed
            }
            else if (type.IsAbstract)
            {
                // this is not allowed
                string message = string.Format(CultureInfo.CurrentCulture,
                    Messages.UnknownConstructor,
                    RuleDecompiler.DecompileType(type));
                throw new RuleSyntaxException(ErrorNumbers.Error_MethodNotExists, message, lparenPosition);
            }
            else
            {
                // Binding flags include all public & non-public, all instance, and all static.
                // All are possible candidates for unadorned method references.
                BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance;
                if (type.Assembly == validation.ThisType.Assembly)
                    bindingFlags |= BindingFlags.NonPublic;
                ValidationError error = null;
                RuleConstructorExpressionInfo constructorInvokeInfo = validation.ResolveConstructor(type, bindingFlags, arguments, out error);

                if (constructorInvokeInfo == null)
                    throw new RuleSyntaxException(error.ErrorNumber, error.ErrorText, lparenPosition);
            }

            CodeExpression postfixExpr = new CodeObjectCreateExpression(type, arguments.ToArray());
            parserContext.exprPositions[postfixExpr] = lparenPosition;
            ValidateExpression(parserContext, postfixExpr, assignIsEquality, ValueCheck.Read);

            return postfixExpr;
        }
Example #7
0
        // Parser:
        //      primary-expr --> ...
        //                   --> IDENTIFIER
        //                   --> IDENTIFIER  method-call-arguments  
        //                   --> ...
        internal CodeExpression ParseUnadornedMemberIdentifier(ParserContext parserContext, MemberSymbol symbol, bool assignIsEquality)
        {
            // This is an implicit member reference off "this", so add the "this".  (Or an implicit
            // static member reference of the type of "this", so add the type name.)
            Token token = parserContext.CurrentToken;
            int namePosition = token.StartPosition;

            parserContext.NextToken(); // eat the identifier

            CodeExpression primaryExpr = null;
            if (parserContext.CurrentToken.TokenID == TokenID.LParen)
                primaryExpr = ParseUnadornedMethodInvoke(parserContext, symbol.Name, true);
            else
                primaryExpr = ParseUnadornedFieldOrProperty(parserContext, symbol.Name, namePosition, assignIsEquality);

            return primaryExpr;
        }
Example #8
0
        // Parse:
        //      assign-statement --> postfix-expression ASSIGN logical-expression
        //                       --> postfix-expression
        private CodeStatement ParseAssignmentStatement(ParserContext parserContext)
        {
            CodeStatement result = null;

            // Parse the postfix-expression
            CodeExpression postfixExpr = ParsePostfixExpression(parserContext, false, ValueCheck.Read);

            // See if we need to parse the assignment statement.
            Token token = parserContext.CurrentToken;
            if (token.TokenID == TokenID.Assign)
            {
                int assignPosition = token.StartPosition;
                parserContext.NextToken(); // eat the '='

                CodeExpression rhsExpr = ParseBinaryExpression(parserContext, 0, true, ValueCheck.Read);

                result = new CodeAssignStatement(postfixExpr, rhsExpr);
                parserContext.exprPositions[result] = assignPosition;
            }
            else
            {
                result = new CodeExpressionStatement(postfixExpr);
                parserContext.exprPositions[result] = parserContext.exprPositions[postfixExpr];
            }

            ValidateStatement(parserContext, result);

            return result;
        }
Example #9
0
        // Parse:
        //
        // binary-expression    --> unary-expresssion binary-expression-tail
        //                      --> unary-expression
        //
        // binary-expression-tail --> binary-operator-precedence unary-expression binary-expression-tail
        //                        --> binary-operator-precedence unary-expression
        //
        // binary-operator-precedence   --> 0:{ ||  OR }
        //                              --> 1:{ &&  AND }
        //                              --> 2:{ | }
        //                              --> 3:{ & }
        //                              --> 4:{ =  ==  != }
        //                              --> 5:{ <  >  <=  >= }
        //                              --> 6:{ +  - }
        //                              --> 7:{ *  /  %  MOD }
        //
        // This method is still recursive descent, but parses each precedence group by using the operator precedence
        // tables defined in this class.
        private CodeExpression ParseBinaryExpression(ParserContext parserContext, int precedence, bool assignIsEquality, ValueCheck check)
        {
            // Must parse at least one left-hand operand.
            CodeExpression leftResult = (precedence == precedences.Length - 1) ? ParseUnaryExpression(parserContext, assignIsEquality, check) : ParseBinaryExpression(parserContext, precedence + 1, assignIsEquality, check);
            if (leftResult != null)
            {
                for (;;)
                {
                    Token operatorToken = parserContext.CurrentToken;

                    BinaryPrecedenceDescriptor precedenceDescriptor = precedences[precedence];

                    BinaryOperationDescriptor operationDescriptor = precedenceDescriptor.FindOperation(operatorToken.TokenID);
                    if (operationDescriptor == null)
                        break; // we're finished; no applicable binary operator token at this precedence level.

                    parserContext.NextToken();

                    // Parse the right-hand side now.
                    CodeExpression rightResult = (precedence == precedences.Length - 1) ? ParseUnaryExpression(parserContext, true, check) : ParseBinaryExpression(parserContext, precedence + 1, true, check);

                    leftResult = operationDescriptor.CreateBinaryExpression(leftResult, rightResult, operatorToken.StartPosition, this, parserContext, assignIsEquality);
                }
            }

            return leftResult;
        }
Example #10
0
        // Parse:
        //      statement-list --> statement statement-list-tail
        //                     --> statement
        //
        //      statement-list-tail --> statement statement-list-tail
        //                          --> statement
        private List<RuleAction> ParseStatements(ParserContext parserContext)
        {
            List<RuleAction> statements = new List<RuleAction>();
            while (parserContext.CurrentToken.TokenID != TokenID.EndOfInput)
            {
                RuleAction statement = ParseStatement(parserContext);
                if (statement == null)
                    break;

                statements.Add(statement);

                // Eat any (optional) semi-colons. They aren't necessary but are comfortable
                // for a lot of programmers.
                while (parserContext.CurrentToken.TokenID == TokenID.Semicolon)
                    parserContext.NextToken();
            }

            return statements;
        }
Example #11
0
        // Parse:
        //              statement       --> assign-statement
        //                              --> update-statement
        //                              --> HALT
        //
        //              update-statement --> UPDATE ( "path" )
        //                               --> UPDATE ( postfix-expr )
        private RuleAction ParseStatement(ParserContext parserContext)
        {
            RuleAction action = null;
            Token statementToken = parserContext.CurrentToken;
            if (statementToken.TokenID == TokenID.Halt)
            {
                parserContext.NextToken(); // eat the "halt"
                action = new RuleHaltAction();
                parserContext.exprPositions[action] = statementToken.StartPosition;
                ValidateAction(parserContext, action);
            }
            else if (statementToken.TokenID == TokenID.Update)
            {
                string message;

                parserContext.NextToken(); // eat the "update"

                if (parserContext.CurrentToken.TokenID != TokenID.LParen)
                {
                    message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_MissingLparenAfterCommand, "UPDATE");
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingLparenAfterCommand, message, parserContext.CurrentToken.StartPosition);
                }

                parserContext.NextToken(); // Eat the "("

                string pathString = null;

                Token updateArgToken = parserContext.CurrentToken;
                if (updateArgToken.TokenID == TokenID.StringLiteral)
                {
                    // Treat UPDATE("foo/bar") as a literal path.
                    pathString = (string)updateArgToken.Value;
                    parserContext.NextToken(); // Eat the path string.
                }
                else
                {
                    CodeExpression pathExpr = ParsePostfixExpression(parserContext, true, ValueCheck.Read);

                    RuleAnalysis analysis = new RuleAnalysis(validation, true);
                    RuleExpressionWalker.AnalyzeUsage(analysis, pathExpr, false, true, null);
                    ICollection<string> paths = analysis.GetSymbols();

                    if (paths.Count == 0 || paths.Count > 1)
                    {
                        // The expression did not modify anything, or it modified more than one.
                        throw new RuleSyntaxException(ErrorNumbers.Error_InvalidUpdateExpression, Messages.Parser_InvalidUpdateExpression, updateArgToken.StartPosition);
                    }
                    else
                    {
                        IEnumerator<string> enumerator = paths.GetEnumerator();
                        enumerator.MoveNext();
                        pathString = enumerator.Current;
                    }
                }

                if (parserContext.CurrentToken.TokenID != TokenID.RParen)
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingRParenAfterArgumentList, Messages.Parser_MissingRParenAfterArgumentList, parserContext.CurrentToken.StartPosition);

                parserContext.NextToken(); // Eat the ")"

                action = new RuleUpdateAction((string)pathString);
                parserContext.exprPositions[action] = statementToken.StartPosition;
                ValidateAction(parserContext, action);
            }
            else
            {
                // Try to parse a custom RuleAction.

                int savedTokenState = parserContext.SaveCurrentToken();

                Type type = TryParseTypeSpecifier(parserContext, false);

                if (type != null &&
                    parserContext.CurrentToken.TokenID == TokenID.LParen &&
                    TypeProvider.IsAssignable(typeof(RuleAction), type))
                {
                    // The statement started with a "type (", and the type derived from RuleAction.
                    // This is a custom rule action.

                    int lparenPosition = parserContext.CurrentToken.StartPosition;
                    parserContext.NextToken(); // Eat the '('

                    List<CodeExpression> arguments = ParseArgumentList(parserContext);

                    action = (RuleAction)ConstructCustomType(type, arguments, lparenPosition);

                    parserContext.exprPositions[action] = statementToken.StartPosition;
                    ValidateAction(parserContext, action);
                }
                else
                {
                    // It wasn't a custom action.
                    // In some cases it may have looked like one up to a point, such as:
                    //
                    //      MyType.MyMember(
                    //
                    // but "MyMember" is a static method.

                    // Reset the scanner state, and re-parse as an assignment.
                    parserContext.RestoreCurrentToken(savedTokenState);

                    CodeStatement statement = ParseAssignmentStatement(parserContext);
                    if (statement != null)
                    {
                        // Create a rule statement action around it.  No need to validate it, as
                        // the underlying CodeDom statement has been validated already.
                        action = new RuleStatementAction(statement);
                    }
                }
            }

            return action;
        }
        private CodeExpression ParsePrimaryExpression(ParserContext parserContext, bool assignIsEquality)
        {
            CodeExpression expression = null;
            Token currentToken = parserContext.CurrentToken;
            switch (currentToken.TokenID)
            {
                case TokenID.Identifier:
                    return this.ParseRootIdentifier(parserContext, assignIsEquality);

                case TokenID.LParen:
                    parserContext.NextToken();
                    expression = this.ParseBinaryExpression(parserContext, 0, assignIsEquality, ValueCheck.Read);
                    parserContext.exprPositions[expression] = currentToken.StartPosition;
                    if (parserContext.CurrentToken.TokenID != TokenID.RParen)
                    {
                        throw new RuleSyntaxException(0x184, Messages.Parser_MissingRParenInSubexpression, parserContext.CurrentToken.StartPosition);
                    }
                    parserContext.NextToken();
                    return expression;

                case TokenID.StringLiteral:
                case TokenID.CharacterLiteral:
                case TokenID.IntegerLiteral:
                case TokenID.DecimalLiteral:
                case TokenID.FloatLiteral:
                case TokenID.True:
                case TokenID.False:
                case TokenID.Null:
                    parserContext.NextToken();
                    expression = new CodePrimitiveExpression(currentToken.Value);
                    parserContext.exprPositions[expression] = currentToken.StartPosition;
                    this.ValidateExpression(parserContext, expression, assignIsEquality, ValueCheck.Read);
                    return expression;

                case TokenID.This:
                    parserContext.NextToken();
                    expression = new CodeThisReferenceExpression();
                    parserContext.exprPositions[expression] = currentToken.StartPosition;
                    this.ValidateExpression(parserContext, expression, assignIsEquality, ValueCheck.Read);
                    return expression;

                case TokenID.TypeName:
                {
                    parserContext.NextToken();
                    Type type = (Type) currentToken.Value;
                    CodeTypeReference typeRef = new CodeTypeReference(type);
                    this.validation.AddTypeReference(typeRef, type);
                    expression = new CodeTypeReferenceExpression(typeRef);
                    parserContext.exprPositions[expression] = currentToken.StartPosition;
                    this.ValidateExpression(parserContext, expression, assignIsEquality, ValueCheck.Read);
                    return expression;
                }
                case TokenID.New:
                    parserContext.NextToken();
                    return this.ParseObjectCreation(parserContext, assignIsEquality);

                case TokenID.EndOfInput:
                    throw new RuleSyntaxException(0x183, Messages.Parser_MissingOperand, currentToken.StartPosition);
            }
            throw new RuleSyntaxException(0x187, Messages.Parser_UnknownLiteral, currentToken.StartPosition);
        }
 private Type ParseNestedType(ParserContext parserContext, Type currentType)
 {
     Type type = null;
     while (parserContext.CurrentToken.TokenID == TokenID.Dot)
     {
         int tokenValue = parserContext.SaveCurrentToken();
         Token token = parserContext.NextToken();
         if (token.TokenID != TokenID.Identifier)
         {
             if (!parserContext.provideIntellisense || (token.TokenID != TokenID.EndOfInput))
             {
                 throw new RuleSyntaxException(0x185, Messages.Parser_MissingIdentifierAfterDot, parserContext.CurrentToken.StartPosition);
             }
             parserContext.SetTypeMemberCompletions(currentType, this.validation.ThisType, true, this.validation);
             return null;
         }
         string typeName = (string) token.Value;
         BindingFlags @public = BindingFlags.Public;
         if (currentType.Assembly == this.validation.ThisType.Assembly)
         {
             @public |= BindingFlags.NonPublic;
         }
         if (parserContext.NextToken().TokenID == TokenID.Less)
         {
             List<Type> candidateGenericTypes = new List<Type>();
             Type[] nestedTypes = currentType.GetNestedTypes(@public);
             string str2 = typeName + "`";
             for (int i = 0; i < nestedTypes.Length; i++)
             {
                 Type item = nestedTypes[i];
                 if (item.Name.StartsWith(str2, StringComparison.Ordinal))
                 {
                     candidateGenericTypes.Add(item);
                 }
             }
             if (candidateGenericTypes.Count == 0)
             {
                 parserContext.RestoreCurrentToken(tokenValue);
                 return currentType;
             }
             type = this.ParseGenericType(parserContext, candidateGenericTypes, typeName);
             currentType = type;
         }
         else
         {
             MemberInfo[] member = currentType.GetMember(typeName, @public);
             if (((member == null) || (member.Length != 1)) || ((member[0].MemberType != MemberTypes.NestedType) && (member[0].MemberType != MemberTypes.TypeInfo)))
             {
                 parserContext.RestoreCurrentToken(tokenValue);
                 return currentType;
             }
             type = (Type) member[0];
             if (currentType.IsGenericType && type.IsGenericTypeDefinition)
             {
                 type = type.MakeGenericType(currentType.GetGenericArguments());
             }
             currentType = type;
         }
     }
     return type;
 }
 private CodeExpression ParseMethodInvoke(ParserContext parserContext, CodeExpression postfixExpr, string methodName, bool assignIsEquality)
 {
     int startPosition = parserContext.CurrentToken.StartPosition;
     parserContext.NextToken();
     if ((parserContext.CurrentToken.TokenID == TokenID.EndOfInput) && parserContext.provideIntellisense)
     {
         bool includeStatic = postfixExpr is CodeTypeReferenceExpression;
         parserContext.SetMethodCompletions(this.validation.ExpressionInfo(postfixExpr).ExpressionType, this.validation.ThisType, methodName, includeStatic, !includeStatic, this.validation);
         return null;
     }
     List<CodeExpression> list = this.ParseArgumentList(parserContext);
     postfixExpr = new CodeMethodInvokeExpression(postfixExpr, methodName, list.ToArray());
     parserContext.exprPositions[postfixExpr] = startPosition;
     this.ValidateExpression(parserContext, postfixExpr, assignIsEquality, ValueCheck.Read);
     return postfixExpr;
 }
Example #15
0
        // Parse:
        //              argument --> direction logical-expression
        //                       --> logical-expression
        //              
        //              direction --> IN
        //                        --> OUT 
        //                        --> REF 
        private CodeExpression ParseArgument(ParserContext parserContext, bool assignIsEquality)
        {
            CodeExpression argResult = null;

            Token token = parserContext.CurrentToken;
            int directionPosition = token.StartPosition;
            FieldDirection? direction = null;
            ValueCheck check = ValueCheck.Read;
            switch (token.TokenID)
            {
                case TokenID.In:
                    direction = FieldDirection.In;
                    parserContext.NextToken(); // eat the direction token
                    break;
                case TokenID.Out:
                    direction = FieldDirection.Out;
                    parserContext.NextToken();
                    check = ValueCheck.Write;
                    break;
                case TokenID.Ref:
                    direction = FieldDirection.Ref;
                    parserContext.NextToken();
                    check = ValueCheck.Read | ValueCheck.Write;
                    break;
            }

            argResult = ParseBinaryExpression(parserContext, 0, true, check);
            if (direction != null)
            {
                argResult = new CodeDirectionExpression(direction.Value, argResult);
                parserContext.exprPositions[argResult] = directionPosition;
                ValidateExpression(parserContext, argResult, assignIsEquality, ValueCheck.Read);
            }

            return argResult;
        }
Example #16
0
        // Parse:
        //              unary-expression --> unary-operator unary-expression
        //                               --> postfix-expression
        private CodeExpression ParseUnaryExpression(ParserContext parserContext, bool assignIsEquality, ValueCheck check)
        {
            Token currentToken = parserContext.CurrentToken;

            CodeExpression unaryResult = null;
            if (currentToken.TokenID == TokenID.Not)
            {
                int notPosition = currentToken.StartPosition;
                parserContext.NextToken();

                unaryResult = ParseUnaryExpression(parserContext, true, check);

                // This becomes "subExpr == false"
                unaryResult = new CodeBinaryOperatorExpression(unaryResult, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false));
                parserContext.exprPositions[unaryResult] = notPosition;
                ValidateExpression(parserContext, unaryResult, assignIsEquality, check);
            }
            else if (currentToken.TokenID == TokenID.Minus)
            {
                int negativePosition = currentToken.StartPosition;
                parserContext.NextToken();

                unaryResult = ParseUnaryExpression(parserContext, true, check);

                // This becomes "0 - subExpr"
                unaryResult = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(0), CodeBinaryOperatorType.Subtract, unaryResult);
                parserContext.exprPositions[unaryResult] = negativePosition;
                ValidateExpression(parserContext, unaryResult, assignIsEquality, check);
            }
            else if (currentToken.TokenID == TokenID.LParen)
            {
                int lparenPosition = currentToken.StartPosition;

                // Save the state.  This may actually be a parenthesized subexpression.
                int savedTokenState = parserContext.SaveCurrentToken();

                currentToken = parserContext.NextToken(); // Eat the '('

                Type type = TryParseTypeSpecifier(parserContext, assignIsEquality);

                if (type == null || parserContext.CurrentToken.TokenID != TokenID.RParen)
                {
                    // It wasn't a cast.
                    // In some cases it may have looked like a cast up to a point, such as:
                    //
                    //      (MyType.MyMember
                    //
                    // but "MyMember" is a static field, property, or enum.

                    // Reset the scanner state, and re-parse as a postfix-expr
                    parserContext.RestoreCurrentToken(savedTokenState);
                    unaryResult = ParsePostfixExpression(parserContext, assignIsEquality, check);
                }
                else
                {
                    // It is a cast.  It must have a balancing ')'.
                    if (parserContext.CurrentToken.TokenID != TokenID.RParen)
                        throw new RuleSyntaxException(ErrorNumbers.Error_MissingRParenInSubexpression, Messages.Parser_MissingRParenInSubexpression, parserContext.CurrentToken.StartPosition);

                    parserContext.NextToken();

                    unaryResult = ParseUnaryExpression(parserContext, true, check);

                    CodeTypeReference typeRef = new CodeTypeReference(type);
                    validation.AddTypeReference(typeRef, type);

                    unaryResult = new CodeCastExpression(typeRef, unaryResult);
                    parserContext.exprPositions[unaryResult] = lparenPosition;
                    ValidateExpression(parserContext, unaryResult, assignIsEquality, check);
                }
            }
            else
            {
                unaryResult = ParsePostfixExpression(parserContext, assignIsEquality, check);
            }

            return unaryResult;
        }
Example #17
0
        // Parse:
        // primary-expression   --> ( logical-expression )
        //                      --> IDENTIFIER
        //                      --> IDENTIFIER  method-call-arguments  
        //                      --> type-name
        //                      --> object-creation-expression
        //                      --> array-creation-expression
        //                      --> integer-constant
        //                      --> decimal-constant
        //                      --> float-constant
        //                      --> character-constant
        //                      --> string-constant
        //                      --> NULL
        //                      --> THIS
        //                      --> TRUE
        //                      --> FALSE
        private CodeExpression ParsePrimaryExpression(ParserContext parserContext, bool assignIsEquality)
        {
            CodeExpression primaryExpr = null;

            Token token = parserContext.CurrentToken;

            switch (token.TokenID)
            {
                case TokenID.LParen:
                    // A parenthesized subexpression
                    parserContext.NextToken();

                    primaryExpr = ParseBinaryExpression(parserContext, 0, assignIsEquality, ValueCheck.Read);
                    parserContext.exprPositions[primaryExpr] = token.StartPosition;

                    token = parserContext.CurrentToken;
                    if (token.TokenID != TokenID.RParen)
                        throw new RuleSyntaxException(ErrorNumbers.Error_MissingRParenInSubexpression, Messages.Parser_MissingRParenInSubexpression, parserContext.CurrentToken.StartPosition);

                    parserContext.NextToken(); // eat the ')'
                    break;

                case TokenID.Identifier:
                    primaryExpr = ParseRootIdentifier(parserContext, assignIsEquality);
                    break;

                case TokenID.This:
                    parserContext.NextToken(); // eat "this"

                    primaryExpr = new CodeThisReferenceExpression();
                    parserContext.exprPositions[primaryExpr] = token.StartPosition;
                    ValidateExpression(parserContext, primaryExpr, assignIsEquality, ValueCheck.Read);
                    break;

                case TokenID.TypeName:
                    parserContext.NextToken(); // eat the type name

                    Type type = (Type)token.Value;
                    CodeTypeReference typeRef = new CodeTypeReference(type);
                    validation.AddTypeReference(typeRef, type);

                    primaryExpr = new CodeTypeReferenceExpression(typeRef);
                    parserContext.exprPositions[primaryExpr] = token.StartPosition;
                    ValidateExpression(parserContext, primaryExpr, assignIsEquality, ValueCheck.Read);
                    break;

                case TokenID.New:
                    parserContext.NextToken(); // eat "new"
                    primaryExpr = ParseObjectCreation(parserContext, assignIsEquality);
                    break;

                case TokenID.IntegerLiteral:
                case TokenID.FloatLiteral:
                case TokenID.DecimalLiteral:
                case TokenID.CharacterLiteral:
                case TokenID.StringLiteral:
                case TokenID.True:
                case TokenID.False:
                case TokenID.Null:
                    parserContext.NextToken(); // eat the literal

                    primaryExpr = new CodePrimitiveExpression(token.Value);
                    parserContext.exprPositions[primaryExpr] = token.StartPosition;
                    ValidateExpression(parserContext, primaryExpr, assignIsEquality, ValueCheck.Read);
                    break;

                case TokenID.EndOfInput:
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingOperand, Messages.Parser_MissingOperand, token.StartPosition);

                default:
                    throw new RuleSyntaxException(ErrorNumbers.Error_UnknownLiteral, Messages.Parser_UnknownLiteral, token.StartPosition);
            }

            return primaryExpr;
        }
Example #18
0
        // Parse:
        //              element-operator --> [  expression-list  ]
        private CodeExpression ParseElementOperator(ParserContext parserContext, CodeExpression primaryExpr, bool assignIsEquality)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.LBracket);
            int lbracketPosition = parserContext.CurrentToken.StartPosition;

            parserContext.NextToken(); // Consume the '['

            List<CodeExpression> indexList = ParseIndexList(parserContext);
            CodeExpression[] indices = indexList.ToArray();

            CodeExpression resultExpr = null;

            RuleExpressionInfo primaryExprInfo = validation.ExpressionInfo(primaryExpr);
            if (primaryExprInfo.ExpressionType.IsArray)
            {
                // The primary is an array type, so create an array indexer expression.
                resultExpr = new CodeArrayIndexerExpression(primaryExpr, indices);
            }
            else
            {
                // The primary isn't an array, so assume it has an indexer property.
                resultExpr = new CodeIndexerExpression(primaryExpr, indices);
            }

            parserContext.exprPositions[resultExpr] = lbracketPosition;
            ValidateExpression(parserContext, resultExpr, assignIsEquality, ValueCheck.Read);

            return resultExpr;
        }
Example #19
0
        // Parse:
        //     array-initializer --> {  variable-initializer-list  }
        //                           {  }
        //     variable-initializer-list --> variable-initializer variable-initializer-list-tail
        //                               --> variable-initializer
        //     variable-initializer-list-tail --> , variable-initializer variable-initializer-list-tail
        //                                    --> , variable-initializer
        private List<CodeExpression> ParseArrayCreationArguments(ParserContext parserContext)
        {
            // if there are no initializers, return null
            if (parserContext.CurrentToken.TokenID != TokenID.LCurlyBrace)
                return null;

            List<CodeExpression> initializers = new List<CodeExpression>();
            parserContext.NextToken();     // skip '{'

            if (parserContext.CurrentToken.TokenID != TokenID.RCurlyBrace)
            {
                initializers.Add(ParseInitializer(parserContext, true));
                while (parserContext.CurrentToken.TokenID == TokenID.Comma)
                {
                    parserContext.NextToken(); // eat the comma
                    initializers.Add(ParseInitializer(parserContext, true));
                }

                if (parserContext.CurrentToken.TokenID != TokenID.RCurlyBrace)
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingRCurlyAfterInitializers,
                        Messages.Parser_MissingRCurlyAfterInitializers,
                        parserContext.CurrentToken.StartPosition);
            }

            parserContext.NextToken();     // eat the '}'
            return initializers;
        }
Example #20
0
        // Parse:
        //              expression-list --> logical-expression  expression-list-tail
        //                              --> logical-expression
        //
        //              expression-list-tail --> ,  logical-expression  expression-list-tail
        //                                   --> ,  logical-expression
        private List<CodeExpression> ParseIndexList(ParserContext parserContext)
        {
            List<CodeExpression> indexList = new List<CodeExpression>();

            CodeExpression indexExpr = ParseBinaryExpression(parserContext, 0, true, ValueCheck.Read); //ParseLogicalExpression();
            indexList.Add(indexExpr);

            while (parserContext.CurrentToken.TokenID == TokenID.Comma)
            {
                parserContext.NextToken(); // eat the comma

                indexExpr = ParseBinaryExpression(parserContext, 0, true, ValueCheck.Read); //ParseLogicalExpression();
                indexList.Add(indexExpr);
            }

            if (parserContext.CurrentToken.TokenID != TokenID.RBracket)
                throw new RuleSyntaxException(ErrorNumbers.Error_MissingCloseSquareBracket, Messages.Parser_MissingCloseSquareBracket, parserContext.CurrentToken.StartPosition);

            parserContext.NextToken(); // consume the ']'

            return indexList;
        }
Example #21
0
        // Parse:
        //      namespace-qualified-type-name --> NAMESPACE-NAME namespace-qualifier-tail . TYPE-NAME
        //                                    --> NAMESPACE-NAME . TYPE-NAME
        //                                    --> TYPE-NAME
        //
        //      namespace-qualifier-tail --> . NAMESPACE-NAME namespace-qualifier-tail
        internal CodeExpression ParseRootNamespaceIdentifier(ParserContext parserContext, NamespaceSymbol nsSym, bool assignIsEquality)
        {
            // Loop through all the namespace qualifiers until we find something that's not a namespace.
            Symbol nestedSym = null;
            while (nsSym != null)
            {
                Token token = parserContext.NextToken();
                if (token.TokenID != TokenID.Dot)
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingDotAfterNamespace, Messages.Parser_MissingDotAfterNamespace, token.StartPosition);

                token = parserContext.NextToken();
                if (token.TokenID != TokenID.Identifier)
                {
                    if (parserContext.provideIntellisense && token.TokenID == TokenID.EndOfInput)
                    {
                        parserContext.SetNamespaceCompletions(nsSym);
                        return null;
                    }
                    else
                    {
                        throw new RuleSyntaxException(ErrorNumbers.Error_MissingIdentifierAfterDot, Messages.Parser_MissingIdentifierAfterDot, token.StartPosition);
                    }
                }

                string name = (string)token.Value;
                nestedSym = nsSym.FindMember(name);
                if (nestedSym == null)
                {
                    string message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_UnknownNamespaceMember, name, nsSym.GetQualifiedName());
                    throw new RuleSyntaxException(ErrorNumbers.Error_UnknownNamespaceMember, message, token.StartPosition);
                }

                nsSym = nestedSym as NamespaceSymbol;
            }

            // We are sitting at a type (or overloaded type).
            return nestedSym.ParseRootIdentifier(this, parserContext, assignIsEquality);
        }
Example #22
0
        // Parse:
        //              member-operator --> . IDENTIFIER method-call-arguments
        //                              --> . IDENTIFIER
        //              
        //              method-call-arguments --> ( argument-list )
        //                                    --> ( )
        //
        //              argument-list --> argument argument-list-tail
        //                            --> argument
        //
        //              argument-list-tail --> , argument argument-list-tail
        //                                 --> , argument
        private CodeExpression ParseMemberOperator(ParserContext parserContext, CodeExpression primaryExpr, bool assignIsEquality, ValueCheck check)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.Dot);

            Token token = parserContext.NextToken(); // Consume the '.'
            if (token.TokenID != TokenID.Identifier)
            {
                if (parserContext.provideIntellisense && token.TokenID == TokenID.EndOfInput)
                {
                    parserContext.SetTypeMemberCompletions(validation.ExpressionInfo(primaryExpr).ExpressionType, validation.ThisType, primaryExpr is CodeTypeReferenceExpression, validation);
                    return null;
                }
                else
                {
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingIdentifierAfterDot, Messages.Parser_MissingIdentifierAfterDot, parserContext.CurrentToken.StartPosition);
                }
            }

            string idName = (string)token.Value;
            int idPosition = token.StartPosition;

            CodeExpression postfixExpr = null;

            if (parserContext.NextToken().TokenID == TokenID.LParen)
            {
                postfixExpr = ParseMethodInvoke(parserContext, primaryExpr, idName, true);
            }
            else
            {
                postfixExpr = ParseFieldOrProperty(parserContext, primaryExpr, idName, idPosition, assignIsEquality, check);
            }

            return postfixExpr;
        }
Example #23
0
        internal CodeExpression ParseRootOverloadedTypeIdentifier(ParserContext parserContext, List<TypeSymbol> candidateTypeSymbols, bool assignIsEquality)
        {
            Token token = parserContext.CurrentToken;
            string typeName = (string)token.Value;
            int namePosition = token.StartPosition;

            // Get the next token after the identifier.
            token = parserContext.NextToken();
            Type type = null;

            if (token.TokenID == TokenID.Less)
            {
                // Choose from the generic candidates.
                List<Type> candidateTypes = new List<Type>(candidateTypeSymbols.Count);
                foreach (TypeSymbol typeSym in candidateTypeSymbols)
                {
                    if (typeSym.GenericArgCount > 0)
                        candidateTypes.Add(typeSym.Type);
                }

                type = ParseGenericType(parserContext, candidateTypes, typeName);
            }
            else
            {
                // See if there's a non-generic candidate.
                TypeSymbol typeSym = candidateTypeSymbols.Find(delegate(TypeSymbol s) { return s.GenericArgCount == 0; });
                if (typeSym == null)
                {
                    // No argument list was provided, but there's no non-generic overload.
                    string message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_MissingTypeArguments, typeName);
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingTypeArguments, message, namePosition);
                }

                type = typeSym.Type;
            }

            if (parserContext.CurrentToken.TokenID == TokenID.Dot)
            {
                Type nestedType = ParseNestedType(parserContext, type);
                if (nestedType != null)
                    type = nestedType;
            }

            return ParseTypeRef(parserContext, type, namePosition, assignIsEquality);
        }
Example #24
0
        private CodeExpression ParseMethodInvoke(ParserContext parserContext, CodeExpression postfixExpr, string methodName, bool assignIsEquality)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.LParen);

            // Start of a method call parameter list.
            int lparenPosition = parserContext.CurrentToken.StartPosition;

            parserContext.NextToken();

            if (parserContext.CurrentToken.TokenID == TokenID.EndOfInput && parserContext.provideIntellisense)
            {
                bool isStatic = postfixExpr is CodeTypeReferenceExpression;
                parserContext.SetMethodCompletions(validation.ExpressionInfo(postfixExpr).ExpressionType, validation.ThisType, methodName, isStatic, !isStatic, validation);
                return null;
            }

            List<CodeExpression> arguments = ParseArgumentList(parserContext);

            postfixExpr = new CodeMethodInvokeExpression(postfixExpr, methodName, arguments.ToArray());
            parserContext.exprPositions[postfixExpr] = lparenPosition;
            ValidateExpression(parserContext, postfixExpr, assignIsEquality, ValueCheck.Read);

            return postfixExpr;
        }
Example #25
0
        // Parse nested types.
        private Type ParseNestedType(ParserContext parserContext, Type currentType)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.Dot);

            Type nestedType = null;

            while (parserContext.CurrentToken.TokenID == TokenID.Dot)
            {
                // Save the state of the scanner.  Since we can't tell if we're parsing a nested
                // type or a member, we'll need to backtrack if we go too far.
                int savedTokenState = parserContext.SaveCurrentToken();

                Token token = parserContext.NextToken();
                if (token.TokenID != TokenID.Identifier)
                {
                    if (parserContext.provideIntellisense && token.TokenID == TokenID.EndOfInput)
                    {
                        parserContext.SetTypeMemberCompletions(currentType, validation.ThisType, true, validation);
                        return null;
                    }
                    else
                    {
                        throw new RuleSyntaxException(ErrorNumbers.Error_MissingIdentifierAfterDot, Messages.Parser_MissingIdentifierAfterDot, parserContext.CurrentToken.StartPosition);
                    }
                }

                string name = (string)token.Value;

                BindingFlags bindingFlags = BindingFlags.Public;
                if (currentType.Assembly == validation.ThisType.Assembly)
                    bindingFlags |= BindingFlags.NonPublic;

                if (parserContext.NextToken().TokenID == TokenID.Less)
                {
                    // Might be a generic type.
                    List<Type> candidateGenericTypes = new List<Type>();

                    Type[] nestedTypes = currentType.GetNestedTypes(bindingFlags);
                    string prefix = name + "`";
                    for (int i = 0; i < nestedTypes.Length; ++i)
                    {
                        Type candidateType = nestedTypes[i];
                        if (candidateType.Name.StartsWith(prefix, StringComparison.Ordinal))
                            candidateGenericTypes.Add(candidateType);
                    }

                    if (candidateGenericTypes.Count == 0)
                    {
                        // It wasn't a generic type.  Reset the scanner to the saved state.
                        parserContext.RestoreCurrentToken(savedTokenState);
                        // Also reset the deepenst nested type.
                        nestedType = currentType;
                        break;
                    }

                    nestedType = ParseGenericType(parserContext, candidateGenericTypes, name);
                    currentType = nestedType;
                }
                else
                {
                    // Might be a non-generic type.
                    MemberInfo[] mi = currentType.GetMember(name, bindingFlags);
                    if (mi == null || mi.Length != 1 || (mi[0].MemberType != MemberTypes.NestedType && mi[0].MemberType != MemberTypes.TypeInfo))
                    {
                        // We went too far, reset the state.
                        parserContext.RestoreCurrentToken(savedTokenState);
                        // Also reset the deepest nested type.
                        nestedType = currentType;
                        break;
                    }

                    nestedType = (Type)mi[0];

                    if (currentType.IsGenericType && nestedType.IsGenericTypeDefinition)
                    {
                        // The outer type was generic (and bound), but the nested type is not.  We have
                        // to re-bind the generic arguments.
                        nestedType = nestedType.MakeGenericType(currentType.GetGenericArguments());
                    }

                    currentType = nestedType;
                }
            }

            return nestedType;
        }
Example #26
0
        private List<CodeExpression> ParseArgumentList(ParserContext parserContext)
        {
            List<CodeExpression> argList = new List<CodeExpression>();

            if (parserContext.CurrentToken.TokenID != TokenID.RParen)
            {
                CodeExpression argResult = ParseArgument(parserContext, true);
                argList.Add(argResult);
                while (parserContext.CurrentToken.TokenID == TokenID.Comma)
                {
                    parserContext.NextToken(); // eat the comma

                    argResult = ParseArgument(parserContext, true);
                    argList.Add(argResult);
                }

                if (parserContext.CurrentToken.TokenID != TokenID.RParen)
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingRParenAfterArgumentList, Messages.Parser_MissingRParenAfterArgumentList, parserContext.CurrentToken.StartPosition);
            }

            parserContext.NextToken(); // consume the ')'

            return argList;
        }
Example #27
0
        private Type TryParseTypeName(ParserContext parserContext, bool assignIsEquality)
        {
            Type type = null;

            Token currentToken = parserContext.CurrentToken;
            if (currentToken.TokenID == TokenID.TypeName)
            {
                type = (Type)currentToken.Value;
                parserContext.NextToken(); // eat the type name
            }
            else if (currentToken.TokenID == TokenID.Identifier)
            {
                Symbol sym = null;
                if (globalUniqueSymbols.TryGetValue((string)currentToken.Value, out sym))
                {
                    CodeExpression identExpr = sym.ParseRootIdentifier(this, parserContext, assignIsEquality);

                    if (identExpr is CodeTypeReferenceExpression)
                        type = validation.ExpressionInfo(identExpr).ExpressionType;
                }
            }

            return type;
        }
Example #28
0
        private CodeExpression ParseUnadornedMethodInvoke(ParserContext parserContext, string methodName, bool assignIsEquality)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.LParen);

            Type thisType = Validator.ThisType;

            // Start of a method call parameter list.
            int lparenPosition = parserContext.CurrentToken.StartPosition;
            parserContext.NextToken();

            if (parserContext.CurrentToken.TokenID == TokenID.EndOfInput && parserContext.provideIntellisense)
            {
                parserContext.SetMethodCompletions(thisType, thisType, methodName, true, true, validation);
                return null;
            }

            List<CodeExpression> arguments = ParseArgumentList(parserContext);

            // Binding flags include all public & non-public, all instance, and all static.
            // All are possible candidates for unadorned method references.
            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Instance;
            ValidationError error = null;
            RuleMethodInvokeExpressionInfo methodInvokeInfo = validation.ResolveMethod(thisType, methodName, bindingFlags, arguments, out error);

            if (methodInvokeInfo == null)
                throw new RuleSyntaxException(error.ErrorNumber, error.ErrorText, lparenPosition);

            MethodInfo mi = methodInvokeInfo.MethodInfo;

            CodeExpression primaryExpr = null;
            if (mi.IsStatic)
                primaryExpr = new CodeTypeReferenceExpression(thisType);
            else
                primaryExpr = new CodeThisReferenceExpression();

            CodeExpression postfixExpr = new CodeMethodInvokeExpression(primaryExpr, methodName, arguments.ToArray());
            parserContext.exprPositions[postfixExpr] = lparenPosition;
            ValidateExpression(parserContext, postfixExpr, assignIsEquality, ValueCheck.Read);

            return postfixExpr;
        }
Example #29
0
        // Parse:
        //      rank-specifiers --> rank-specifier  rank-specifier-tail
        //                      --> rank-specifier
        //
        //      rank-specifier-tail -->  rank-specifier  rank-specifier-tail
        //
        //      rank-specifier --> [  dim-separators  ]
        //                     --> [  ]
        //
        //      dim-separators --> ,  dim-separators-tail
        //                     --> ,
        //
        //      dim-separators-tail --> ,  dim-separators-tail
        private static Type ParseArrayType(ParserContext parserContext, Type baseType)
        {
            Type type = baseType;

            while (parserContext.CurrentToken.TokenID == TokenID.LBracket)
            {
                int rank = 1;
                while (parserContext.NextToken().TokenID == TokenID.Comma)
                    ++rank;

                if (parserContext.CurrentToken.TokenID == TokenID.RBracket)
                    parserContext.NextToken(); // Eat the ']'
                else
                    throw new RuleSyntaxException(ErrorNumbers.Error_MissingCloseSquareBracket, Messages.Parser_MissingCloseSquareBracket, parserContext.CurrentToken.StartPosition);

                if (rank == 1)
                    type = type.MakeArrayType();
                else
                    type = type.MakeArrayType(rank);
            }

            return type;
        }
 private List<CodeExpression> ParseIndexList(ParserContext parserContext)
 {
     List<CodeExpression> list = new List<CodeExpression>();
     CodeExpression item = this.ParseBinaryExpression(parserContext, 0, true, ValueCheck.Read);
     list.Add(item);
     while (parserContext.CurrentToken.TokenID == TokenID.Comma)
     {
         parserContext.NextToken();
         item = this.ParseBinaryExpression(parserContext, 0, true, ValueCheck.Read);
         list.Add(item);
     }
     if (parserContext.CurrentToken.TokenID != TokenID.RBracket)
     {
         throw new RuleSyntaxException(410, Messages.Parser_MissingCloseSquareBracket, parserContext.CurrentToken.StartPosition);
     }
     parserContext.NextToken();
     return list;
 }