Esempio n. 1
0
        private void ValidateAction(ParserContext parserContext, RuleAction action)
        {
            if (!action.Validate(validation))
            {
                // Choose the first one and throw it.
                ValidationError error = Validator.Errors[0];

                // Try to get the position, or just use zero if we can't.
                object errorObject = error.UserData[RuleUserDataKeys.ErrorObject];
                int position = 0;
                parserContext.exprPositions.TryGetValue(errorObject, out position);

                throw new RuleSyntaxException(error.ErrorNumber, error.ErrorText, position);
            }
        }
Esempio n. 2
0
            internal override CodeBinaryOperatorExpression CreateBinaryExpression(CodeExpression left, CodeExpression right, int operatorPosition, Parser parser, ParserContext parserContext, bool assignIsEquality)
            {
                CodePrimitiveExpression falseExpr = new CodePrimitiveExpression(false);
                parserContext.exprPositions[falseExpr] = operatorPosition;

                // Compare the comperands using "value-equality"
                CodeBinaryOperatorExpression binaryExpr = new CodeBinaryOperatorExpression(left, CodeBinaryOperatorType.ValueEquality, right);
                parserContext.exprPositions[binaryExpr] = operatorPosition;

                // Compare the result of that with false to simulate "value-inequality"
                binaryExpr = new CodeBinaryOperatorExpression(binaryExpr, CodeBinaryOperatorType.ValueEquality, falseExpr);
                parserContext.exprPositions[binaryExpr] = operatorPosition;
                parser.ValidateExpression(parserContext, binaryExpr, assignIsEquality, ValueCheck.Read);

                return binaryExpr;
            }
Esempio n. 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;
        }
Esempio n. 4
0
        private void ValidateExpression(ParserContext parserContext, CodeExpression expression, bool assignIsEquality, ValueCheck check)
        {
            // If the current token is an assignment operator, then make sure the expression is validated
            // correctly (written-to).  Note that because we allow "=" (Token.Assign) as a synonym for
            // "==" (Token.Equal), we need to distinguish whether we're parsing a condition vs an action.
            // In other words, we need to be sure that the "=" really is an "=".
            if (parserContext.CurrentToken.TokenID == TokenID.Assign && !assignIsEquality)
                check = ValueCheck.Write;

            // use value in check
            RuleExpressionInfo exprInfo = null;
            if ((check & ValueCheck.Read) != 0)
            {
                exprInfo = RuleExpressionWalker.Validate(Validator, expression, false);
                // check write if set and first validate succeeded
                if ((exprInfo != null) && ((check & ValueCheck.Write) != 0))
                    exprInfo = RuleExpressionWalker.Validate(Validator, expression, true);
            }
            else if ((check & ValueCheck.Write) != 0)
                exprInfo = RuleExpressionWalker.Validate(Validator, expression, true);

            if (exprInfo == null && Validator.Errors.Count > 0)
            {
                // Choose the first one and throw it.
                ValidationError error = Validator.Errors[0];

                // Try to get the position, or just use zero if we can't.
                object errorObject = error.UserData[RuleUserDataKeys.ErrorObject];
                int position = 0;
                parserContext.exprPositions.TryGetValue(errorObject, out position);

                throw new RuleSyntaxException(error.ErrorNumber, error.ErrorText, position);
            }
        }
Esempio n. 5
0
        private Type ParseGenericType(ParserContext parserContext, List<Type> candidateGenericTypes, string typeName)
        {
            System.Diagnostics.Debug.Assert(parserContext.CurrentToken.TokenID == TokenID.Less);

            Type[] typeArgs = ParseGenericTypeArgList(parserContext);

            foreach (Type candidateType in candidateGenericTypes)
            {
                Type[] genericArgs = candidateType.GetGenericArguments();
                if (genericArgs.Length == typeArgs.Length)
                    return candidateType.MakeGenericType(typeArgs);
            }

            // No valid candidate found.
            string message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_BadTypeArgCount, typeName);
            throw new RuleSyntaxException(ErrorNumbers.Error_BadTypeArgCount, message, parserContext.CurrentToken.StartPosition);
        }
Esempio n. 6
0
        // Parse:
        //      type-spec --> type-name
        //                --> type-name  rank-specifiers
        private Type TryParseTypeSpecifier(ParserContext parserContext, bool assignIsEquality)
        {
            Type type = TryParseTypeName(parserContext, assignIsEquality);
            if (type != null)
                type = ParseArrayType(parserContext, type);

            return type;
        }
Esempio n. 7
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;
        }
Esempio n. 8
0
 internal abstract CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality);
Esempio n. 9
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;
        }
Esempio n. 10
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;
        }
Esempio n. 11
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return(parser.ParseUnadornedMemberIdentifier(parserContext, this, assignIsEquality));
 }
Esempio n. 12
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return(parser.ParseRootOverloadedTypeIdentifier(parserContext, this.TypeSymbols, assignIsEquality));
 }
Esempio n. 13
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     // The root name is a type (might be generic or not).
     return(parser.ParseRootTypeIdentifier(parserContext, this, assignIsEquality));
 }
Esempio n. 14
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     // The root name is a type (might be generic or not).
     return parser.ParseRootTypeIdentifier(parserContext, this, assignIsEquality);
 }
Esempio n. 15
0
        // Parse:
        //     object-creation-expression --> NEW type-name method-call-arguments
        //     array-creation-expression --> NEW array-spec
        //                               --> NEW array-spec array-initializer
        private CodeExpression ParseObjectCreation(ParserContext parserContext, bool assignIsEquality)
        {
            CodeExpression primaryExpr = null;
            Token token = parserContext.CurrentToken;
            CodeExpression size;
            Type type = TryParseTypeSpecifierWithOptionalSize(parserContext, assignIsEquality, out size);

            // handle intellisense, regardless of whether we get a type back or not
            if (parserContext.provideIntellisense && parserContext.CurrentToken.TokenID == TokenID.EndOfInput)
            {
                // if we have a type, get only nested classes for it
                // if we don't have a type, then take whatever is already set for completions
                if (type != null)
                    parserContext.SetNestedClassCompletions(type, validation.ThisType);
                return null;
            }

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

            if (size == null)
            {
                // must be an object-creation-expression
                if (parserContext.CurrentToken.TokenID != TokenID.LParen)
                {
                    // [] are already handled by TryParseTypeSpecifierWithOptionalSize
                    throw new RuleSyntaxException(ErrorNumbers.Error_InvalidTypeArgument, Messages.Parser_InvalidNew, token.StartPosition);
                }
                primaryExpr = ParseConstructorArguments(parserContext, type, assignIsEquality);
            }
            else
            {
                // it's an array
                List<CodeExpression> initializers = ParseArrayCreationArguments(parserContext);
                if (initializers != null)
                {
                    if (size == defaultSize)
                        primaryExpr = new CodeArrayCreateExpression(type, initializers.ToArray());
                    else
                    {
                        // both specified
                        primaryExpr = new CodeArrayCreateExpression(type, size);
                        ((CodeArrayCreateExpression)primaryExpr).Initializers.AddRange(initializers.ToArray());
                    }
                }
                else
                {
                    // no initializers, so size matters
                    if (size != defaultSize)
                        primaryExpr = new CodeArrayCreateExpression(type, size);
                    else
                    {
                        // neither specified, so error
                        throw new RuleSyntaxException(ErrorNumbers.Error_NoArrayCreationSize,
                            Messages.Parser_NoArrayCreationSize,
                            parserContext.CurrentToken.StartPosition);
                    }
                }
                ValidateExpression(parserContext, primaryExpr, assignIsEquality, ValueCheck.Read);
            }

            return primaryExpr;
        }
Esempio n. 16
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return parser.ParseUnadornedMemberIdentifier(parserContext, this, assignIsEquality);
 }
Esempio n. 17
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;
        }
Esempio n. 18
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;
        }
Esempio n. 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;
        }
Esempio n. 20
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();
        }
Esempio n. 21
0
 // Parse:
 //     variable-initializer --> logical-expression
 private CodeExpression ParseInitializer(ParserContext parserContext, bool assignIsEquality)
 {
     // size we only handle 1 level arrays, initializers must be regular expressions
     return ParseBinaryExpression(parserContext, 0, assignIsEquality, ValueCheck.Read);
 }
Esempio n. 22
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;
        }
Esempio n. 23
0
        // Parse a root identifier which may be:
        //      1. A field/property/method with an implicit "this." prepended to it.
        //      2. A nested type within the type of this.
        //      2. An unqualified type name
        //      3. A namespace name.
        private CodeExpression ParseRootIdentifier(ParserContext parserContext, bool assignIsEquality)
        {
            Token token = parserContext.CurrentToken;
            string name = (string)token.Value;
            Symbol sym = null;

            // Consult the local unique symbol list first.  If we find a symbol here, that's the one.
            if (!localUniqueSymbols.TryGetValue(name, out sym))
            {
                // Wasn't found in the local unique symbols, try the global unique symbols.
                globalUniqueSymbols.TryGetValue(name, out sym);
            }

            if (sym == null)
            {
                // We couldn't find it in either location.  This is an error.
                string message = string.Format(CultureInfo.CurrentCulture, Messages.Parser_UnknownIdentifier, name);
                throw new RuleSyntaxException(ErrorNumbers.Error_UnknownIdentifier, message, token.StartPosition);
            }

            return sym.ParseRootIdentifier(this, parserContext, assignIsEquality);
        }
Esempio n. 24
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;
        }
Esempio n. 25
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;
        }
Esempio n. 26
0
        private void ValidateStatement(ParserContext parserContext, CodeStatement statement)
        {
            if (!CodeDomStatementWalker.Validate(Validator, statement) && Validator.Errors.Count > 0)
            {
                // Choose the first one and throw it.
                ValidationError error = Validator.Errors[0];

                // Try to get the position, or just use zero if we can't.
                object errorObject = error.UserData[RuleUserDataKeys.ErrorObject];
                int position = 0;
                parserContext.exprPositions.TryGetValue(errorObject, out position);

                throw new RuleSyntaxException(error.ErrorNumber, error.ErrorText, position);
            }
        }
Esempio n. 27
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);
        }
Esempio n. 28
0
 internal virtual CodeBinaryOperatorExpression CreateBinaryExpression(CodeExpression left, CodeExpression right, int operatorPosition, Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     CodeBinaryOperatorExpression binaryExpr = new CodeBinaryOperatorExpression(left, codeDomOperator, right);
     parserContext.exprPositions[binaryExpr] = operatorPosition;
     parser.ValidateExpression(parserContext, binaryExpr, assignIsEquality, ValueCheck.Read);
     return binaryExpr;
 }
Esempio n. 29
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);
        }
Esempio n. 30
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return parser.ParseRootNamespaceIdentifier(parserContext, this, assignIsEquality);
 }
Esempio n. 31
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);
        }
Esempio n. 32
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return parser.ParseRootOverloadedTypeIdentifier(parserContext, this.TypeSymbols, assignIsEquality);
 }
Esempio n. 33
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;
        }
 internal abstract CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality);
Esempio n. 35
0
 internal override CodeExpression ParseRootIdentifier(Parser parser, ParserContext parserContext, bool assignIsEquality)
 {
     return(parser.ParseRootNamespaceIdentifier(parserContext, this, assignIsEquality));
 }