/// <summary>
        /// Initializes a new instance of the LocalFunctionStatement class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the statement.
        /// </param>
        /// <param name="returnType">
        /// The return type of this local function.
        /// </param>
        /// <param name="returnTypeIsRef">
        /// The return type of this local function is ref.
        /// </param>
        /// <param name="identifier">
        /// The identifier of this local function.
        /// </param>
        /// <param name="parameters">
        /// The parameter information of this local function.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        private LocalFunctionStatement(
            CsTokenList tokens,
            TypeToken returnType,
            bool returnTypeIsRef,
            LiteralExpression identifier,
            IList <Parameter> parameters,
            ICollection <TypeParameterConstraintClause> typeConstraints)
            : base(StatementType.LocalFunction, tokens)
        {
            Param.AssertNotNull(returnType, nameof(returnType));
            Param.Ignore(returnTypeIsRef);
            Param.AssertNotNull(identifier, nameof(identifier));
            Param.AssertNotNull(parameters, nameof(parameters));
            Param.Ignore(typeConstraints);

            this.returnType      = returnType;
            this.returnTypeIsRef = returnTypeIsRef;
            this.identifier      = identifier;
            this.parameters      = parameters;
            this.typeConstraints = typeConstraints;

            this.AddExpression(this.identifier);

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the Parameter class.
        /// </summary>
        /// <param name="type">
        /// The type of the parameter.
        /// </param>
        /// <param name="name">
        /// The name of the parameter.
        /// </param>
        /// <param name="parent">
        /// The parent of the parameter.
        /// </param>
        /// <param name="modifiers">
        /// Modifiers applied to this parameter.
        /// </param>
        /// <param name="defaultArgument">
        /// The optional default argument for the parameter.
        /// </param>
        /// <param name="location">
        /// The location of the parameter in the code.
        /// </param>
        /// <param name="tokens">
        /// The tokens that form the parameter.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the parameter is located within a block of generated code.
        /// </param>
        internal Parameter(
            TypeToken type,
            string name,
            Reference <ICodePart> parent,
            ParameterModifiers modifiers,
            Expression defaultArgument,
            CodeLocation location,
            CsTokenList tokens,
            bool generated)
        {
            Param.Ignore(type);
            Param.AssertValidString(name, "name");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(modifiers);
            Param.Ignore(defaultArgument);
            Param.AssertNotNull(location, "location");
            Param.Ignore(tokens);
            Param.Ignore(generated);

            this.type            = type;
            this.name            = CodeLexer.DecodeEscapedText(name, true);
            this.parent          = parent;
            this.modifiers       = modifiers;
            this.defaultArgument = defaultArgument;
            this.location        = location;
            this.tokens          = tokens;
            this.generated       = generated;
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the Property class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The property return type.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Property(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken returnType, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Property, "property " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(returnType, "returnType");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType = returnType;

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }
        }
示例#4
0
        /// <summary>
        /// Initializes a new instance of the Property class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The property return type.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Property(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken returnType,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Property, "property " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(returnType, "returnType");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType = returnType;

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }
        }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the Event class.
        /// </summary>
        /// <param name="document">
        /// The document that contains this element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="eventHandlerType">
        /// The type of the event handler.
        /// </param>
        /// <param name="eventDeclarators">
        /// Declarators for the event.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Event(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken eventHandlerType,
            ICollection <EventDeclaratorExpression> eventDeclarators,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Event, "event " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(eventHandlerType, "eventHandlerType");
            Param.AssertNotNull(eventDeclarators, "eventDeclarators");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.eventHandlerType = eventHandlerType;
            this.eventDeclarators = eventDeclarators;

            foreach (EventDeclaratorExpression expression in this.eventDeclarators)
            {
                this.AddExpression(expression);
                expression.ParentEvent = this;
            }
        }
示例#6
0
        /// <summary>
        /// Initializes a new instance of the Field class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="fieldType">
        /// The type of the field.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Field(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken fieldType,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Field, "field " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(fieldType, "fieldType");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.type = fieldType;

            // Determine whether the item is const /readonly / static.
            this.isConst    = this.Declaration.ContainsModifier(CsTokenType.Const);
            this.isReadOnly = this.Declaration.ContainsModifier(CsTokenType.Readonly);
            this.isStatic   = this.Declaration.ContainsModifier(CsTokenType.Static);
        }
示例#7
0
        /// <summary>
        /// Initializes a new instance of the IsExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="leftSideExpression">
        /// The left hand side of the expression.
        /// </param>
        /// <param name="rightSideExpression">
        /// The right hand side of the expression.
        /// </param>
        /// <param name="matchVariable">
        /// The variable declared as part of pattern match of the expression.
        /// </param>
        internal IsExpression(CsTokenList tokens, Expression leftSideExpression, Expression rightSideExpression, Expression matchVariable)
            : base(ExpressionType.Is, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(leftSideExpression, "leftSideExpression");
            Param.AssertNotNull(rightSideExpression, "rightSideExpression");
            Param.Ignore(matchVariable);

            this.leftHandSideExpression  = leftSideExpression;
            this.rightHandSideExpression = rightSideExpression;
            this.matchVariable           = matchVariable;

            // Extract the type being compared to, if possible.
            LiteralExpression le = this.rightHandSideExpression as LiteralExpression;

            if (le != null)
            {
                this.type = CodeParser.TryExtractTypeTokenFromLiteralExpression(le);
            }

            this.AddExpression(this.leftHandSideExpression);
            this.AddExpression(this.rightHandSideExpression);

            if (this.matchVariable != null)
            {
                this.AddExpression(this.matchVariable);
            }
        }
        /// <summary>
        /// Initializes a new instance of the TypeofExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The type literal to get the type of.
        /// </param>
        internal TypeofExpression(CsTokenList tokens, LiteralExpression type)
            : base(ExpressionType.Typeof, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.AddExpression(type);
        }
示例#9
0
        /// <summary>
        /// Initializes a new instance of the TypeofExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The type literal to get the type of.
        /// </param>
        internal TypeofExpression(CsTokenList tokens, LiteralExpression type)
            : base(ExpressionType.Typeof, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.AddExpression(type);
        }
示例#10
0
        /// <summary>
        /// Initializes a new instance of the NameofExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="name">
        /// The type literal to get the name of.
        /// </param>
        internal NameofExpression(CsTokenList tokens, LiteralExpression name)
            : base(ExpressionType.NameOf, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(name, "name");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(name);
            this.AddExpression(name);
        }
示例#11
0
        /// <summary>
        /// Initializes a new instance of the NameofExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="name">
        /// The type literal to get the name of.
        /// </param>
        internal NameofExpression(CsTokenList tokens, LiteralExpression name)
            : base(ExpressionType.NameOf, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(name, "name");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(name);
            this.AddExpression(name);
        }
示例#12
0
        /// <summary>
        /// Checks a type to determine whether it should use one of the built-in types.
        /// </summary>
        /// <param name="type">
        /// The type to check.
        /// </param>
        /// <param name="document">
        /// The parent document.
        /// </param>
        private void CheckBuiltInType(Node <CsToken> type, CsDocument document)
        {
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(document, "document");

            Debug.Assert(type.Value is TypeToken, "The type must be a TypeToken");
            TypeToken typeToken = (TypeToken)type.Value;

            if (type.Value.CsTokenClass != CsTokenClass.GenericType)
            {
                for (int i = 0; i < this.builtInTypes.Length; ++i)
                {
                    string[] builtInType = this.builtInTypes[i];

                    if (CsTokenList.MatchTokens(typeToken.ChildTokens.First, builtInType[0]) ||
                        CsTokenList.MatchTokens(typeToken.ChildTokens.First, "System", ".", builtInType[0]))
                    {
                        // If the previous token is an equals sign, then this is a using alias directive. For example:
                        // using SomeAlias = System.String;
                        // If the previous token is the 'static' keyword, then this is a using static directive. For example:
                        // using static System.String;
                        bool shouldBuiltInTypeAliasBeUsed = true;
                        for (Node <CsToken> previous = type.Previous; previous != null; previous = previous.Previous)
                        {
                            if (previous.Value.CsTokenType != CsTokenType.EndOfLine && previous.Value.CsTokenType != CsTokenType.MultiLineComment &&
                                previous.Value.CsTokenType != CsTokenType.SingleLineComment && previous.Value.CsTokenType != CsTokenType.WhiteSpace)
                            {
                                if (previous.Value.Text == "=" || previous.Value.Text == "static")
                                {
                                    shouldBuiltInTypeAliasBeUsed = false;
                                }

                                break;
                            }
                        }

                        if (shouldBuiltInTypeAliasBeUsed)
                        {
                            this.AddViolation(
                                typeToken.FindParentElement(), typeToken.LineNumber, Rules.UseBuiltInTypeAlias, builtInType[2], builtInType[0], builtInType[1]);
                        }

                        break;
                    }
                }
            }

            for (Node <CsToken> childToken = typeToken.ChildTokens.First; childToken != null; childToken = childToken.Next)
            {
                if (childToken.Value.CsTokenClass == CsTokenClass.Type || childToken.Value.CsTokenClass == CsTokenClass.GenericType)
                {
                    this.CheckBuiltInType(childToken, document);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the DefaultValueExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The type to obtain the default value of.
        /// </param>
        /// <param name="parent">
        /// The parent reference of this expression.
        /// </param>
        internal DefaultValueExpression(CsTokenList tokens, LiteralExpression type, Reference <ICodePart> parent)
            : base(ExpressionType.DefaultValue, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.AddExpression(type);

            this.parent = parent;
        }
        /// <summary>
        /// Initializes a new instance of the DefaultValueExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The type to obtain the default value of.
        /// </param>
        /// <param name="parent">
        /// The parent reference of this expression.
        /// </param>
        internal DefaultValueExpression(CsTokenList tokens, LiteralExpression type, Reference<ICodePart> parent)
            : base(ExpressionType.DefaultValue, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.AddExpression(type);

            this.parent = parent;
        }
示例#15
0
        /// <summary>
        /// Extracts the generic types from the type list and saves them.
        /// </summary>
        private void ExtractGenericTypes()
        {
            List <GenericTypeParameter> genericTypes = new List <GenericTypeParameter>();

            bool start = false;
            ParameterModifiers modifiers = ParameterModifiers.None;
            TypeToken          type      = null;

            for (Node <CsToken> tokenNode = this.ChildTokens.First; tokenNode != null; tokenNode = tokenNode.Next)
            {
                if (tokenNode.Value.CsTokenType == CsTokenType.OpenGenericBracket)
                {
                    start = true;
                }
                else if (start)
                {
                    if (tokenNode.Value.CsTokenType == CSharp.CsTokenType.CloseGenericBracket)
                    {
                        if (type != null)
                        {
                            genericTypes.Add(new GenericTypeParameter(type, modifiers));
                        }

                        break;
                    }

                    if (tokenNode.Value.CsTokenType == CsTokenType.Comma)
                    {
                        if (type != null)
                        {
                            genericTypes.Add(new GenericTypeParameter(type, modifiers));
                        }

                        type      = null;
                        modifiers = ParameterModifiers.None;
                    }
                    else if (tokenNode.Value.CsTokenType == CsTokenType.Out)
                    {
                        modifiers = ParameterModifiers.Out;
                    }
                    else if (tokenNode.Value.CsTokenType == CsTokenType.In)
                    {
                        modifiers = ParameterModifiers.In;
                    }
                    else if (tokenNode.Value.CsTokenType == CsTokenType.Other && type == null)
                    {
                        type = tokenNode.Value as TypeToken;
                    }
                }
            }

            this.typeParameters = genericTypes.ToArray();
        }
        /// <summary>
        /// Initializes a new instance of the IsExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="value">
        /// The value to check.
        /// </param>
        /// <param name="type">
        /// The type to check.
        /// </param>
        internal IsExpression(CsTokenList tokens, Expression value, LiteralExpression type)
            : base(ExpressionType.Is, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(value, "value");
            Param.AssertNotNull(type, "type");

            this.value = value;
            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);

            this.AddExpression(value);
            this.AddExpression(type);
        }
示例#17
0
 /// <summary>
 /// Initializes a new instance of the LocalFunctionStatement class.
 /// </summary>
 /// <param name="tokens">
 /// The list of tokens that form the statement.
 /// </param>
 /// <param name="returnType">
 /// The return type of this local function.
 /// </param>
 /// <param name="returnTypeIsRef">
 /// The return type of this local function is ref.
 /// </param>
 /// <param name="identifier">
 /// The identifier of this local function.
 /// </param>
 /// <param name="parameters">
 /// The parameter information of this local function.
 /// </param>
 /// <param name="functionBodyExpression">
 /// An expression that represents the body of this local function.
 /// </param>
 public LocalFunctionStatement(
     CsTokenList tokens,
     TypeToken returnType,
     bool returnTypeIsRef,
     LiteralExpression identifier,
     IList <Parameter> parameters,
     Expression functionBodyExpression)
     : this(tokens, returnType, returnTypeIsRef, identifier, parameters)
 {
     Param.AssertNotNull(functionBodyExpression, nameof(functionBodyExpression));
     this.functionBody = functionBodyExpression;
     this.AddExpression(functionBodyExpression);
 }
示例#18
0
        /// <summary>
        /// Initializes a new instance of the CastExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The cast type.
        /// </param>
        /// <param name="castedExpression">
        /// The expression being casted.
        /// </param>
        internal CastExpression(CsTokenList tokens, LiteralExpression type, Expression castedExpression)
            : base(ExpressionType.Cast, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(castedExpression, "castedExpression");

            this.type             = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.castedExpression = castedExpression;

            this.AddExpression(type);
            this.AddExpression(castedExpression);
        }
        /// <summary>
        /// Initializes a new instance of the CastExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="type">
        /// The cast type.
        /// </param>
        /// <param name="castedExpression">
        /// The expression being casted.
        /// </param>
        internal CastExpression(CsTokenList tokens, LiteralExpression type, Expression castedExpression)
            : base(ExpressionType.Cast, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(castedExpression, "castedExpression");

            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.castedExpression = castedExpression;

            this.AddExpression(type);
            this.AddExpression(castedExpression);
        }
示例#20
0
        /// <summary>
        /// Initializes a new instance of the AsExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the expression.
        /// </param>
        /// <param name="value">
        /// The value to convert.
        /// </param>
        /// <param name="type">
        /// The type of the conversion.
        /// </param>
        internal AsExpression(CsTokenList tokens, Expression value, LiteralExpression type)
            : base(ExpressionType.As, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(value, "value");
            Param.AssertNotNull(type, "type");

            this.value = value;
            this.type  = CodeParser.ExtractTypeTokenFromLiteralExpression(type);

            this.AddExpression(value);
            this.AddExpression(type);
        }
 /// <summary>
 /// Initializes a new instance of the LocalFunctionStatement class.
 /// </summary>
 /// <param name="tokens">
 /// The list of tokens that form the statement.
 /// </param>
 /// <param name="returnType">
 /// The return type of this local function.
 /// </param>
 /// <param name="returnTypeIsRef">
 /// The return type of this local function is ref.
 /// </param>
 /// <param name="identifier">
 /// The identifier of this local function.
 /// </param>
 /// <param name="parameters">
 /// The parameter information of this local function.
 /// </param>
 /// <param name="typeConstraints">
 /// The list of type constraints on the element.
 /// </param>
 /// <param name="functionBodyExpression">
 /// An expression that represents the body of this local function.
 /// </param>
 internal LocalFunctionStatement(
     CsTokenList tokens,
     TypeToken returnType,
     bool returnTypeIsRef,
     LiteralExpression identifier,
     IList <Parameter> parameters,
     ICollection <TypeParameterConstraintClause> typeConstraints,
     Expression functionBodyExpression)
     : this(tokens, returnType, returnTypeIsRef, identifier, parameters, typeConstraints)
 {
     Param.AssertNotNull(functionBodyExpression, nameof(functionBodyExpression));
     this.functionBody = functionBodyExpression;
     this.AddExpression(functionBodyExpression);
 }
示例#22
0
        /// <summary>
        /// Fills in the details of the set accessor.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillSetAccessorDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            Reference <ICodePart> accessorReference = new Reference <ICodePart>(this);

            Property property = parent as Property;

            if (property != null)
            {
                // Set accessors on properties do not have a return type but have an
                // implied input parameter.
                this.returnType = CreateVoidTypeToken(accessorReference);

                this.parameters = new[]
                {
                    new Parameter(
                        property.ReturnType,
                        "value",
                        accessorReference,
                        ParameterModifiers.None,
                        null,
                        CodeLocation.Empty,
                        null,
                        property.ReturnType.Generated)
                };
            }
            else
            {
                // Set accessors on indexers do not have a return type but, but have the input
                // parameters of the parent indexer.
                Indexer indexer = (Indexer)parent;

                this.returnType = CreateVoidTypeToken(accessorReference);

                Parameter[] tempParameters = new Parameter[indexer.Parameters.Count + 1];
                int         i = 0;
                foreach (Parameter parameter in indexer.Parameters)
                {
                    tempParameters[i++] = parameter;
                }

                // Add the implicit value parameter since this is a set accessor.
                tempParameters[i] = new Parameter(
                    indexer.ReturnType, "value", accessorReference, ParameterModifiers.None, null, CodeLocation.Empty, null, indexer.ReturnType.Generated);

                this.parameters = tempParameters;
            }
        }
        /// <summary>
        /// Initializes a new instance of the Variable class.
        /// </summary>
        /// <param name="type">
        /// The type of the variable.
        /// </param>
        /// <param name="name">
        /// The name of the variable.
        /// </param>
        /// <param name="modifiers">
        /// Modifiers applied to this variable.
        /// </param>
        /// <param name="location">
        /// The location of the variable.
        /// </param>
        /// <param name="parent">
        /// The parent code part.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the variable is located within a block of generated code.
        /// </param>
        internal Variable(TypeToken type, string name, VariableModifiers modifiers, CodeLocation location, Reference<ICodePart> parent, bool generated)
        {
            Param.Ignore(type);
            Param.AssertValidString(name, "name");
            Param.Ignore(modifiers);
            Param.AssertNotNull(location, "location");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(generated);

            this.type = type;
            this.name = CodeLexer.DecodeEscapedText(name, true);
            this.modifiers = modifiers;
            this.location = location;
            this.parent = parent;
            this.generated = generated;
        }
示例#24
0
        /// <summary>
        /// Initializes a new instance of the Variable class.
        /// </summary>
        /// <param name="type">
        /// The type of the variable.
        /// </param>
        /// <param name="name">
        /// The name of the variable.
        /// </param>
        /// <param name="modifiers">
        /// Modifiers applied to this variable.
        /// </param>
        /// <param name="location">
        /// The location of the variable.
        /// </param>
        /// <param name="parent">
        /// The parent code part.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the variable is located within a block of generated code.
        /// </param>
        internal Variable(TypeToken type, string name, VariableModifiers modifiers, CodeLocation location, Reference <ICodePart> parent, bool generated)
        {
            Param.Ignore(type);
            Param.AssertValidString(name, "name");
            Param.Ignore(modifiers);
            Param.AssertNotNull(location, "location");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(generated);

            this.type      = type;
            this.name      = CodeLexer.DecodeEscapedText(name, true);
            this.modifiers = modifiers;
            this.location  = location;
            this.parent    = parent;
            this.generated = generated;
        }
示例#25
0
        /// <summary>
        /// Initializes a new instance of the Delegate class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The return type.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the delegate.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether this is generated code.
        /// </param>
        internal Delegate(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken returnType,
            IList <Parameter> parameters,
            ICollection <TypeParameterConstraintClause> typeConstraints,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Delegate, "delegate " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(returnType, "returnType");
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(typeConstraints);
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType      = returnType;
            this.typeConstraints = typeConstraints;
            this.parameters      = parameters;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Add the qualifications
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                Debug.Assert(typeConstraints.IsReadOnly, "The collection of type constraints should be read-only.");

                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
示例#26
0
        /// <summary>
        /// Initializes a new instance of the LocalFunctionStatement class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the statement.
        /// </param>
        /// <param name="returnType">
        /// The return type of this local function.
        /// </param>
        /// <param name="returnTypeIsRef">
        /// The return type of this local function is ref.
        /// </param>
        /// <param name="identifier">
        /// The identifier of this local function.
        /// </param>
        /// <param name="parameters">
        /// The parameter information of this local function.
        /// </param>
        private LocalFunctionStatement(
            CsTokenList tokens,
            TypeToken returnType,
            bool returnTypeIsRef,
            LiteralExpression identifier,
            IList <Parameter> parameters)
            : base(StatementType.LocalFunction, tokens)
        {
            Param.AssertNotNull(returnType, nameof(returnType));
            Param.Ignore(returnTypeIsRef);
            Param.AssertNotNull(identifier, nameof(identifier));
            Param.AssertNotNull(parameters, nameof(parameters));

            this.returnType      = returnType;
            this.returnTypeIsRef = returnTypeIsRef;
            this.identifier      = identifier;
            this.parameters      = parameters;

            this.AddExpression(this.identifier);
        }
示例#27
0
        /// <summary>
        /// Initializes a new instance of the VariableDeclarationExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the statement.
        /// </param>
        /// <param name="type">
        /// The type of the variable or variables being declared.
        /// </param>
        /// <param name="declarators">
        /// The list of declarators in the expression.
        /// </param>
        internal VariableDeclarationExpression(CsTokenList tokens, LiteralExpression type, ICollection <VariableDeclaratorExpression> declarators)
            : base(ExpressionType.VariableDeclaration, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(declarators, "declarators");

            this.declarators = declarators;

            Debug.Assert(declarators.IsReadOnly, "The declarators collection should be read-only.");

            this.AddExpression(type);
            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);

            foreach (VariableDeclaratorExpression expression in declarators)
            {
                this.AddExpression(expression);
                expression.ParentVariable = this;
            }
        }
        /// <summary>
        /// Initializes a new instance of the VariableDeclarationExpression class.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens that form the statement.
        /// </param>
        /// <param name="type">
        /// The type of the variable or variables being declared.
        /// </param>
        /// <param name="declarators">
        /// The list of declarators in the expression.
        /// </param>
        internal VariableDeclarationExpression(CsTokenList tokens, LiteralExpression type, ICollection<VariableDeclaratorExpression> declarators)
            : base(ExpressionType.VariableDeclaration, tokens)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(declarators, "declarators");

            this.declarators = declarators;

            Debug.Assert(declarators.IsReadOnly, "The declarators collection should be read-only.");

            this.AddExpression(type);
            this.type = CodeParser.ExtractTypeTokenFromLiteralExpression(type);

            foreach (VariableDeclaratorExpression expression in declarators)
            {
                this.AddExpression(expression);
                expression.ParentVariable = this;
            }
        }
示例#29
0
        /// <summary>
        /// Fills in the details of the get accessor.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillGetAccessorDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            Property property = parent as Property;

            if (property != null)
            {
                // Get accessors on properties have the return type of their parent property,
                // and have no input parameters.
                this.returnType = property.ReturnType;
            }
            else
            {
                // Get accessors on indexers have the return type of their parent indexer,
                // and have the input parameters of the parent indexer.
                Indexer indexer = (Indexer)parent;

                this.returnType = indexer.ReturnType;
                this.parameters = indexer.Parameters;
            }
        }
示例#30
0
        /// <summary>
        /// Initializes a new instance of the Indexer class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The return type of the indexer.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the indexer.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Indexer(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken returnType,
            IList <Parameter> parameters,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Indexer, "indexer " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.Ignore(returnType);
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType = returnType;
            this.parameters = parameters;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Add the qualifications
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }
        }
示例#31
0
        /// <summary>
        /// Fills in the details of the accessor based on its type.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            // Set the return type and parameters.
            if (this.accessorType == AccessorType.Get)
            {
                this.FillGetAccessorDetails(parent);
            }
            else if (this.accessorType == AccessorType.Set)
            {
                this.FillSetAccessorDetails(parent);
            }
            else
            {
                // Add and remove accessors have no return type but have an implied
                // parameter based on the type of the event handler.
                Event parentEvent = (Event)parent;
                Reference <ICodePart> accessorReference = new Reference <ICodePart>(this);

                this.returnType = CreateVoidTypeToken(accessorReference);

                this.parameters = new[]
                {
                    new Parameter(
                        parentEvent.EventHandlerType,
                        "value",
                        accessorReference,
                        ParameterModifiers.None,
                        null,
                        CodeLocation.Empty,
                        null,
                        parentEvent.EventHandlerType.Generated)
                };
            }
        }
        /// <summary>
        /// Initializes a new instance of the Indexer class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The return type of the indexer.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the indexer.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Indexer(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken returnType, 
            IList<Parameter> parameters, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Indexer, "indexer " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.Ignore(returnType);
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType = returnType;
            this.parameters = parameters;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Add the qualifications
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }
        }
 /// <summary>
 /// The save.
 /// </summary>
 /// <param name="typeToken">
 /// The type token.
 /// </param>
 private void Save(TypeToken typeToken)
 {
     this.Save(typeToken, this.headerWriter, SavingOptions.UseFullyQualifiedNames);
 }
示例#34
0
        /// <summary>
        /// Checks for the presence of a return value tag on an element.
        /// </summary>
        /// <param name="element">
        /// The element to parse.
        /// </param>
        /// <param name="returnType">
        /// The return type.
        /// </param>
        /// <param name="formattedDocs">
        /// The formatted Xml document that comprises the header.
        /// </param>
        private void CheckHeaderReturnValue(CsElement element, TypeToken returnType, XmlDocument formattedDocs)
        {
            Param.AssertNotNull(element, "element");
            Param.Ignore(returnType);
            Param.AssertNotNull(formattedDocs, "formattedDocs");

            if (returnType != null)
            {
                XmlNode returnNode = formattedDocs.SelectSingleNode("root/returns");
                if (returnType.Text != "void")
                {
                    if (null == returnNode)
                    {
                        this.AddViolation(element, Rules.ElementReturnValueMustBeDocumented);
                    }
                    else if (returnNode.InnerXml == null || returnNode.InnerXml.Length == 0)
                    {
                        // Use InnerXml here because it might just contain a <seeref>
                        this.AddViolation(element, Rules.ElementReturnValueDocumentationMustHaveText);
                    }
                    else
                    {
                        this.CheckDocumentationValidity(element, element.LineNumber, returnNode, "return");
                    }
                }
                else
                {
                    if (null != returnNode)
                    {
                        this.AddViolation(element, Rules.VoidReturnValueMustNotBeDocumented);
                    }
                }
            }
        }
示例#35
0
        /// <summary>
        /// Checks a type to determine whether it should use one of the built-in types.
        /// </summary>
        /// <param name="type">The type to check.</param>
        /// <param name="parentElement">The parent element.</param>
        private void CheckBuiltInType(TypeToken type, Element parentElement)
        {
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(parentElement, "parentElement");

            if (!type.IsGeneric)
            {
                for (int i = 0; i < this.builtInTypes.Length; ++i)
                {
                    string[] builtInType = this.builtInTypes[i];

                    if (type.MatchTokens(builtInType[ShortNameIndex]) ||
                        type.MatchTokens("System", ".", builtInType[ShortNameIndex]))
                    {
                        // If the previous token is an equals sign, then this is a using alias directive. For example:
                        // using SomeAlias = System.String;
                        bool usingAliasDirective = false;
                        for (LexicalElement previous = type.FindPreviousLexicalElement(); previous != null; previous = previous.FindPreviousLexicalElement())
                        {
                            if (previous.LexicalElementType != LexicalElementType.Comment &&
                                previous.LexicalElementType != LexicalElementType.WhiteSpace &&
                                previous.LexicalElementType != LexicalElementType.EndOfLine)
                            {
                                if (previous.Text == "=")
                                {
                                    usingAliasDirective = true;
                                }

                                break;
                            }
                        }

                        if (!usingAliasDirective)
                        {
                            this.Violation(
                                Rules.UseBuiltInTypeAlias,
                                new ViolationContext(parentElement, type.LineNumber, builtInType[AliasIndex], builtInType[ShortNameIndex], builtInType[LongNameIndex]),
                                (c, o) =>
                                {
                                    // Insert a new type token with the correct aliased version of the type.
                                    CsDocument document = type.Document;
                                    TypeToken aliasType = document.CreateTypeToken(document.CreateLiteralToken(builtInType[AliasIndex]));
                                    document.Replace(type, aliasType);
                                });
                        }

                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the Parameter class.
        /// </summary>
        /// <param name="type">
        /// The type of the parameter.
        /// </param>
        /// <param name="name">
        /// The name of the parameter.
        /// </param>
        /// <param name="parent">
        /// The parent of the parameter.
        /// </param>
        /// <param name="modifiers">
        /// Modifiers applied to this parameter.
        /// </param>
        /// <param name="defaultArgument">
        /// The optional default argument for the parameter.
        /// </param>
        /// <param name="location">
        /// The location of the parameter in the code.
        /// </param>
        /// <param name="tokens">
        /// The tokens that form the parameter.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the parameter is located within a block of generated code.
        /// </param>
        internal Parameter(
            TypeToken type, 
            string name, 
            Reference<ICodePart> parent, 
            ParameterModifiers modifiers, 
            Expression defaultArgument, 
            CodeLocation location, 
            CsTokenList tokens, 
            bool generated)
        {
            Param.Ignore(type);
            Param.AssertValidString(name, "name");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(modifiers);
            Param.Ignore(defaultArgument);
            Param.AssertNotNull(location, "location");
            Param.Ignore(tokens);
            Param.Ignore(generated);

            this.type = type;
            this.name = CodeLexer.DecodeEscapedText(name, true);
            this.parent = parent;
            this.modifiers = modifiers;
            this.defaultArgument = defaultArgument;
            this.location = location;
            this.tokens = tokens;
            this.generated = generated;
        }
 public TypeResolver(TypeToken typeTokenReference, INamesResolver namesInfoHolder)
     : this(typeTokenReference.Text, namesInfoHolder)
 {
 }
        /// <summary>
        /// Parses and returns the declarators for a field.
        /// </summary>
        /// <param name="fieldReference">
        /// A reference to the field.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code is marked as unsafe.
        /// </param>
        /// <param name="fieldType">
        /// The field type.
        /// </param>
        /// <returns>
        /// Returns the declarators.
        /// </returns>
        private IList<VariableDeclaratorExpression> ParseFieldDeclarators(Reference<ICodePart> fieldReference, bool unsafeCode, TypeToken fieldType)
        {
            Param.AssertNotNull(fieldReference, "fieldReference");
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(fieldType, "fieldType");

            List<VariableDeclaratorExpression> declarators = new List<VariableDeclaratorExpression>();
            Symbol symbol = this.GetNextSymbol(fieldReference);

            while (symbol.SymbolType != SymbolType.Semicolon)
            {
                Reference<ICodePart> expressionReference = new Reference<ICodePart>();

                // Get the identifier.
                CsToken identifier = this.GetElementNameToken(expressionReference, unsafeCode, true);
                Node<CsToken> identifierTokenNode = this.tokens.InsertLast(identifier);

                Expression initialization = null;

                // Check whether there is an equals sign.
                symbol = this.GetNextSymbol(expressionReference);
                if (symbol.SymbolType == SymbolType.Equals)
                {
                    this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, expressionReference));

                    // Get the expression after the equals sign. If the expression starts with an
                    // opening curly bracket, then this is an initialization expression or an
                    // anonymous type initialization expression.
                    symbol = this.GetNextSymbol(expressionReference);
                    if (symbol.SymbolType == SymbolType.OpenCurlyBracket)
                    {
                        // Determine whether this is an array or an anonymous type.
                        if (fieldType.Text == "var" || (fieldType.Text != "Array" && fieldType.Text != "System.Array" && !fieldType.Text.Contains("[")))
                        {
                            initialization = this.GetAnonymousTypeInitializerExpression(expressionReference, unsafeCode);
                        }
                        else
                        {
                            initialization = this.GetArrayInitializerExpression(unsafeCode);
                        }
                    }
                    else
                    {
                        initialization = this.GetNextExpression(ExpressionPrecedence.None, expressionReference, unsafeCode);
                    }

                    if (initialization == null)
                    {
                        throw this.CreateSyntaxException();
                    }
                }

                VariableDeclaratorExpression variableDeclarationExpression =
                    new VariableDeclaratorExpression(
                        new CsTokenList(this.tokens, identifierTokenNode, this.tokens.Last), new LiteralExpression(this.tokens, identifierTokenNode), initialization);

                expressionReference.Target = variableDeclarationExpression;
                declarators.Add(variableDeclarationExpression);

                // If the next symbol is a comma, continue.
                symbol = this.GetNextSymbol(fieldReference);
                if (symbol.SymbolType == SymbolType.Comma)
                {
                    this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, fieldReference));
                    symbol = this.GetNextSymbol(fieldReference);
                }
            }

            // Return the declarators as a read-only collection.
            return declarators.ToArray();
        }
示例#39
0
        /// <summary>
        /// Fills in the details of the set accessor.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillSetAccessorDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            Reference<ICodePart> accessorReference = new Reference<ICodePart>(this);

            Property property = parent as Property;
            if (property != null)
            {
                // Set accessors on properties do not have a return type but have an 
                // implied input parameter.
                this.returnType = CreateVoidTypeToken(accessorReference);

                this.parameters = new[]
                                      {
                                          new Parameter(
                                              property.ReturnType, 
                                              "value", 
                                              accessorReference, 
                                              ParameterModifiers.None, 
                                              null, 
                                              CodeLocation.Empty, 
                                              null, 
                                              property.ReturnType.Generated)
                                      };
            }
            else
            {
                // Set accessors on indexers do not have a return type but, but have the input
                // parameters of the parent indexer.
                Indexer indexer = (Indexer)parent;

                this.returnType = CreateVoidTypeToken(accessorReference);

                Parameter[] tempParameters = new Parameter[indexer.Parameters.Count + 1];
                int i = 0;
                foreach (Parameter parameter in indexer.Parameters)
                {
                    tempParameters[i++] = parameter;
                }

                // Add the implicit value parameter since this is a set accessor.
                tempParameters[i] = new Parameter(
                    indexer.ReturnType, "value", accessorReference, ParameterModifiers.None, null, CodeLocation.Empty, null, indexer.ReturnType.Generated);

                this.parameters = tempParameters;
            }
        }
        /// <summary>
        /// Initializes a new instance of the Method class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The method's return type.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the method.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Method(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken returnType, 
            IList<Parameter> parameters, 
            ICollection<TypeParameterConstraintClause> typeConstraints, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Method, "method " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.Ignore(returnType);
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(typeConstraints);
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            Debug.Assert(
                returnType != null || declaration.ContainsModifier(CsTokenType.Explicit, CsTokenType.Implicit), 
                "A method's return type can only be null in an explicit or implicit operator overload method.");

            this.returnType = returnType;
            this.parameters = parameters;
            this.typeConstraints = typeConstraints;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Determine whether this is an extension method. The method must be static.
            if (this.parameters.Count > 0 && this.Declaration.ContainsModifier(CsTokenType.Static))
            {
                // Look at this first parameter. Since the parameters collection is not an indexable list, the 
                // easiest way to do this is to foreach through the parameter list and break after the first one.
                foreach (Parameter parameter in this.parameters)
                {
                    if ((parameter.Modifiers & ParameterModifiers.This) != 0)
                    {
                        this.extensionMethod = true;
                    }

                    break;
                }
            }

            // Add the qualifications.
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the Delegate class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The return type.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the delegate.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether this is generated code.
        /// </param>
        internal Delegate(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken returnType, 
            IList<Parameter> parameters, 
            ICollection<TypeParameterConstraintClause> typeConstraints, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Delegate, "delegate " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(returnType, "returnType");
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(typeConstraints);
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.returnType = returnType;
            this.typeConstraints = typeConstraints;
            this.parameters = parameters;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Add the qualifications
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                Debug.Assert(typeConstraints.IsReadOnly, "The collection of type constraints should be read-only.");

                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
        /// <summary>
        /// The save suffix.
        /// </summary>
        /// <param name="typeReference">
        /// The type reference.
        /// </param>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="fieldDeclaration">
        /// The field declaration.
        /// </param>
        private void SaveSuffix(
            TypeToken typeReference, Expression expression, IndentedTextWriter writer, bool fieldDeclaration = true)
        {
            var typeReferenceString = typeReference.ToString();

            var pos = typeReferenceString.IndexOf("[");
            if (pos != -1)
            {
                // var typeResolverReference = new ResolvedTypeReference(typeReference, this);

                // CXXConverterLogic.WriteArrayIndexes(
                // expression, writer, typeReferenceString, pos, typeResolverReference, fieldDeclaration);
            }
        }
示例#43
0
        /// <summary>
        /// Fills in the details of the accessor based on its type.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            // Set the return type and parameters.
            if (this.accessorType == AccessorType.Get)
            {
                this.FillGetAccessorDetails(parent);
            }
            else if (this.accessorType == AccessorType.Set)
            {
                this.FillSetAccessorDetails(parent);
            }
            else
            {
                // Add and remove accessors have no return type but have an implied
                // parameter based on the type of the event handler.
                Event parentEvent = (Event)parent;
                Reference<ICodePart> accessorReference = new Reference<ICodePart>(this);

                this.returnType = CreateVoidTypeToken(accessorReference);

                this.parameters = new[]
                                      {
                                          new Parameter(
                                              parentEvent.EventHandlerType, 
                                              "value", 
                                              accessorReference, 
                                              ParameterModifiers.None, 
                                              null, 
                                              CodeLocation.Empty, 
                                              null, 
                                              parentEvent.EventHandlerType.Generated)
                                      };
            }
        }
示例#44
0
        /// <summary>
        /// Fills in the details of the get accessor.
        /// </summary>
        /// <param name="parent">
        /// The parent of the accessor.
        /// </param>
        private void FillGetAccessorDetails(CsElement parent)
        {
            Param.AssertNotNull(parent, "parent");

            Property property = parent as Property;
            if (property != null)
            {
                // Get accessors on properties have the return type of their parent property, 
                // and have no input parameters.
                this.returnType = property.ReturnType;
            }
            else
            {
                // Get accessors on indexers have the return type of their parent indexer, 
                // and have the input parameters of the parent indexer.
                Indexer indexer = (Indexer)parent;

                this.returnType = indexer.ReturnType;
                this.parameters = indexer.Parameters;
            }
        }
        /// <summary>
        /// Parses and returns the declarators for a property (C#6).
        /// </summary>
        /// <param name="propertyReference">A reference to the field.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="propertyType">The field type.</param>
        /// <param name="identifierTokenNode">The identifier token node (Should be the property name).</param>
        /// <returns>
        /// Returns the declarators.
        /// </returns>
        private IList<VariableDeclaratorExpression> ParsePropertyDeclarators(Reference<ICodePart> propertyReference, bool unsafeCode, TypeToken propertyType, Node<CsToken> identifierTokenNode)
        {
            Param.AssertNotNull(propertyReference, nameof(propertyReference));
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(propertyType, nameof(propertyType));
            Param.AssertNotNull(identifierTokenNode, nameof(propertyType));

            List<VariableDeclaratorExpression> declarators = new List<VariableDeclaratorExpression>();
            Symbol symbol = this.GetNextSymbol(propertyReference);

            Reference<ICodePart> expressionReference = new Reference<ICodePart>();
            Expression initialization = null;

            while (symbol.SymbolType != SymbolType.Semicolon)
            {
                symbol = this.GetNextSymbol(expressionReference);
                if (symbol.SymbolType == SymbolType.Equals)
                {
                    this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, expressionReference));

                    initialization = this.GetNextExpression(ExpressionPrecedence.None, expressionReference, unsafeCode);
                    if (initialization == null)
                    {
                        throw this.CreateSyntaxException();
                    }
                }

                VariableDeclaratorExpression variableDeclarationExpression =
                    new VariableDeclaratorExpression(
                        new CsTokenList(this.tokens, identifierTokenNode, this.tokens.Last), new LiteralExpression(this.tokens, identifierTokenNode), initialization);

                expressionReference.Target = variableDeclarationExpression;
                declarators.Add(variableDeclarationExpression);

                // Get next symbol without change index.
                symbol = this.symbols.Peek(1);
            }

            // Return the declarators as a read-only collection.
            return declarators.ToArray();
        }
示例#46
0
        /// <summary>
        /// Initializes a new instance of the Method class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The method's return type.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the method.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Method(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken returnType,
            IList <Parameter> parameters,
            ICollection <TypeParameterConstraintClause> typeConstraints,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Method, "method " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.Ignore(returnType);
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(typeConstraints);
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            Debug.Assert(
                returnType != null || declaration.ContainsModifier(CsTokenType.Explicit, CsTokenType.Implicit),
                "A method's return type can only be null in an explicit or implicit operator overload method.");

            this.returnType      = returnType;
            this.parameters      = parameters;
            this.typeConstraints = typeConstraints;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Determine whether this is an extension method. The method must be static.
            if (this.parameters.Count > 0 && this.Declaration.ContainsModifier(CsTokenType.Static))
            {
                // Look at this first parameter. Since the parameters collection is not an indexable list, the
                // easiest way to do this is to foreach through the parameter list and break after the first one.
                foreach (Parameter parameter in this.parameters)
                {
                    if ((parameter.Modifiers & ParameterModifiers.This) != 0)
                    {
                        this.extensionMethod = true;
                    }

                    break;
                }
            }

            // Add the qualifications.
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
        /// <summary>
        /// The save prefix.
        /// </summary>
        /// <param name="typeReference">
        /// The type reference.
        /// </param>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        private void SavePrefix(TypeToken typeReference, Expression expression, IndentedTextWriter writer)
        {
            var typeReferenceString = typeReference.ToString();

            var pos = typeReferenceString.IndexOf("[");
            if (pos != -1)
            {
                // CXXConverterLogic.WriteArrayPointerIndexes(expression, writer, typeReferenceString, pos);
            }
        }
示例#48
0
        /// <summary>
        /// Checks the return comments
        /// </summary>
        /// <param name='element'>
        /// Element of the document
        /// </param>
        /// <param name='returnType'>
        /// Return type.
        /// </param>
        /// <param name='document'>
        /// Document XML
        /// </param>
        private void CheckReturn(CsElement element, TypeToken returnType, XmlDocument document)
        {
            this.WriteMessage("CheckReturn");
            XmlNode returnNode = document.SelectSingleNode(XmlHeader + "/returns");
            this.WriteMessage("Looking for <returns> tag");
            if (returnType != null && returnType.Text != "void" && null != returnNode && (returnNode.InnerXml != null || returnNode.InnerXml.Length > 0))
            {
                this.WriteMessage("<returns> tag found");
                this.SpellCheck(element, element.LineNumber, returnNode, "return");
            }

            this.WriteMessage("Done checking returns");
        }
 /// <summary>
 /// The save.
 /// </summary>
 /// <param name="typeReference">
 /// The type reference.
 /// </param>
 /// <param name="writer">
 /// The writer.
 /// </param>
 /// <param name="savingOptions">
 /// The saving Options.
 /// </param>
 private void Save(TypeToken typeReference, IndentedTextWriter writer, SavingOptions savingOptions)
 {
     this.Save(new TypeResolver(typeReference, this), writer, savingOptions);
 }
        /// <summary>
        /// Converts the given expression into a literal expression containing a type token.
        /// </summary>
        /// <param name="expression">
        /// The expression to convert.
        /// </param>
        /// <returns>
        /// Returns the converted expression.
        /// </returns>
        private LiteralExpression ConvertTypeExpression(Expression expression)
        {
            Param.AssertNotNull(expression, "expression");

            // Get the first and last token in the expression.
            Node<CsToken> firstTokenNode = expression.Tokens.First;
            Node<CsToken> lastTokenNode = expression.Tokens.Last;

            Reference<ICodePart> typeTokenReference = new Reference<ICodePart>();
            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            // Create a new token list containing these tokens.
            List<CsToken> tokenList = new List<CsToken>();
            foreach (CsToken token in expression.Tokens)
            {
                tokenList.Add(token);
                token.ParentRef = typeTokenReference;
            }

            // Remove the extra tokens from the master list.
            if (firstTokenNode != null && expression.Tokens.First != null)
            {
                Node<CsToken> temp = firstTokenNode.Next;
                if (!expression.Tokens.OutOfBounds(temp))
                {
                    this.tokens.RemoveRange(temp, expression.Tokens.Last);
                }
            }

            // Add the child tokens to a token list.
            MasterList<CsToken> childTokens = new MasterList<CsToken>(tokenList);

            // Create the new type token.
            TypeToken typeToken = new TypeToken(childTokens, CsToken.JoinLocations(firstTokenNode, lastTokenNode), expressionReference, firstTokenNode.Value.Generated);
            typeTokenReference.Target = typeToken;

            // Insert the new token.
            Node<CsToken> typeTokenNode = this.tokens.Replace(firstTokenNode, typeToken);

            // Create the literal expression.
            LiteralExpression literalExpression = new LiteralExpression(new CsTokenList(this.tokens, firstTokenNode, firstTokenNode), typeTokenNode);

            expressionReference.Target = literalExpression;

            return literalExpression;
        }
        /// <summary>
        /// Initializes a new instance of the Field class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="fieldType">
        /// The type of the field.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Field(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken fieldType, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Field, "field " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(fieldType, "fieldType");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.type = fieldType;

            // Determine whether the item is const /readonly / static.
            this.isConst = this.Declaration.ContainsModifier(CsTokenType.Const);
            this.isReadOnly = this.Declaration.ContainsModifier(CsTokenType.Readonly);
            this.isStatic = this.Declaration.ContainsModifier(CsTokenType.Static);
        }
        /// <summary>
        /// Initializes a new instance of the Event class.
        /// </summary>
        /// <param name="document">
        /// The document that contains this element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="eventHandlerType">
        /// The type of the event handler.
        /// </param>
        /// <param name="eventDeclarators">
        /// Declarators for the event.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Event(
            CsDocument document, 
            CsElement parent, 
            XmlHeader header, 
            ICollection<Attribute> attributes, 
            Declaration declaration, 
            TypeToken eventHandlerType, 
            ICollection<EventDeclaratorExpression> eventDeclarators, 
            bool unsafeCode, 
            bool generated)
            : base(document, parent, ElementType.Event, "event " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.AssertNotNull(eventHandlerType, "eventHandlerType");
            Param.AssertNotNull(eventDeclarators, "eventDeclarators");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            this.eventHandlerType = eventHandlerType;
            this.eventDeclarators = eventDeclarators;

            foreach (EventDeclaratorExpression expression in this.eventDeclarators)
            {
                this.AddExpression(expression);
                expression.ParentEvent = this;
            }
        }
        /// <summary>
        /// Gets a token representing a type identifier.
        /// </summary>
        /// <param name="typeTokenReference">
        /// A reference to the type token.
        /// </param>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code being parsed resides in an unsafe code block.
        /// </param>
        /// <param name="includeArrayBrackets">
        /// Indicates whether to include array brackets in the type token.
        /// </param>
        /// <param name="isExpression">
        /// Indicates whether this type token comes at the end of an 'is' expression.
        /// </param>
        /// <param name="startIndex">
        /// The start position in the symbol list of the first symbol in the type token.
        /// </param>
        /// <param name="endIndex">
        /// Returns the index of the last symbol in the type token.
        /// </param>
        /// <returns>
        /// Returns the token.
        /// </returns>
        private TypeToken GetTypeTokenAux(
            Reference<ICodePart> typeTokenReference, 
            Reference<ICodePart> parentReference, 
            bool unsafeCode, 
            bool includeArrayBrackets, 
            bool isExpression, 
            int startIndex, 
            out int endIndex)
        {
            Param.AssertNotNull(typeTokenReference, "typeTokenReference");
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);
            Param.Ignore(includeArrayBrackets);
            Param.Ignore(isExpression);
            Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex");

            // Get the next symbol and make sure it is an unknown word.
            Symbol symbol = this.symbols.Peek(startIndex);
            Debug.Assert(symbol != null && symbol.SymbolType == SymbolType.Other, "Expected a text symbol");

            // Create a token list to store all the tokens forming the type.
            MasterList<CsToken> typeTokens = new MasterList<CsToken>();

            // Get the name of the type token plus any generic symbols and types.
            GenericType generic;

            this.GetTypeTokenBaseName(typeTokenReference, ref typeTokens, ref startIndex, out generic, unsafeCode);

            bool allowNullableType = true;

            // Add dereference symbols if they exist.
            if (unsafeCode)
            {
                if (this.GetTypeTokenDereferenceSymbols(typeTokenReference, typeTokens, ref startIndex))
                {
                    allowNullableType = false;
                }
            }

            // Now look for the nullable type symbol, if needed.
            if (allowNullableType)
            {
                this.GetTypeTokenNullableTypeSymbol(typeTokenReference, typeTokens, isExpression, ref startIndex);
            }

            // Get the array brackets if they exist.
            if (includeArrayBrackets)
            {
                this.GetTypeTokenArrayBrackets(typeTokenReference, typeTokens, ref startIndex);
            }

            if (typeTokens.Count == 0)
            {
                throw this.CreateSyntaxException();
            }

            // Set the end index.
            endIndex = startIndex - 1;

            // If the type is a generic type, determine whether to just return the generic type directly.
            if (generic != null && typeTokens.Count == 1)
            {
                // This type is only composed of the generic type and nothing else. Just return the generic type.
                generic.ParentRef = parentReference;
                return generic;
            }

            // The type is either not generic, or else it is composed of a more complex type which includes a generic 
            // (for example, an array of a generic type). Return the more complex type.
            CodeLocation location = CsToken.JoinLocations(typeTokens.First, typeTokens.Last);
            TypeToken typeToken = new TypeToken(typeTokens, location, parentReference, this.symbols.Generated);
            typeTokenReference.Target = typeToken;

            return typeToken;
        }