Type parameter definition for generic types.
Inheritance: ICloneable
Example #1
0
        /// <summary>
        /// Adds a type parameter to the type parameter list.
        /// </summary>
        /// <param name="typeParameter">The type parameter.</param>
        public void AddTypeParameter(TypeParameter typeParameter)
        {
            if (typeParameter == null)
            {
                throw new ArgumentNullException("typeParameter");
            }

            TypeParametersBase.Add(typeParameter);
        }
Example #2
0
        public void CreateTest()
        {
            TypeParameter typeParameter = new TypeParameter();

            //
            // Verify default values.
            //
            Assert.AreEqual(string.Empty, typeParameter.Name, "Unexpected default value for name.");
            Assert.IsNotNull(typeParameter.Constraints, "Constraints collection should be instantiated.");
            Assert.AreEqual(0, typeParameter.Constraints.Count, "Constraints collection should be empty.");
        }
Example #3
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            TypeParameter clone = new TypeParameter();

            //
            // Copy state
            //
            clone._name = _name;
            foreach (string constraint in Constraints)
            {
                clone.AddConstraint(constraint);
            }

            return(clone);
        }
Example #4
0
        public void CloneTest()
        {
            TypeParameter typeParameter = new TypeParameter();
            typeParameter.Name = "T";
            typeParameter.AddConstraint("IDisposable");
            typeParameter.AddConstraint("new()");

            TypeParameter clone = typeParameter.Clone() as TypeParameter;
            Assert.IsNotNull(clone, "Clone should return a TypeParameter instance.");

            Assert.AreEqual(typeParameter.Name, clone.Name, "Name property was not copied correctly.");
            Assert.AreEqual(typeParameter.Constraints.Count, clone.Constraints.Count, "Constraints property was not copied correctly.");
            Assert.AreEqual(typeParameter.Constraints[0], clone.Constraints[0], "Constraints property was not copied correctly.");
            Assert.AreEqual(typeParameter.Constraints[1], clone.Constraints[1], "Constraints property was not copied correctly.");
        }
Example #5
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>Clone of the instance with the member element state copied.</returns>
        protected override MemberElement DoMemberClone()
        {
            DelegateElement clone = new DelegateElement();

            //
            // Copy state
            //
            clone._params = _params;

            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return(clone);
        }
Example #6
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// Clone of the instance with the interface member element state copied.
        /// </returns>
        protected override InterfaceMemberElement DoInterfaceMemberClone()
        {
            MethodElement clone = new MethodElement();

            //
            // Copy state
            //
            clone._params       = _params;
            clone._isOperator   = _isOperator;
            clone._operatorType = _operatorType;
            clone._isAsync      = _isAsync;

            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return(clone);
        }
Example #7
0
        /// <summary>
        /// Clones an attributed element.
        /// </summary>
        /// <returns>Cloned attribute element state.</returns>
        protected override AttributedElement DoAttributedClone()
        {
            TypeElement clone = new TypeElement();

            //
            // Copy state
            //
            clone._typeModifiers = _typeModifiers;
            clone._type          = _type;
            foreach (InterfaceReference interfaceReference in Interfaces)
            {
                InterfaceReference referenceClone = interfaceReference.Clone() as InterfaceReference;
                clone.AddInterface(referenceClone);
            }
            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return(clone);
        }
Example #8
0
        /// <summary>
        /// Parses type parameters.
        /// </summary>
        /// <param name="genericElement">The generic element.</param>
        private void ParseTypeParameters(IGenericElement genericElement)
        {
            EatWhiteSpace();

            if (NextChar == VBSymbol.EndParameterList ||
                NextChar == EmptyChar)
            {
                this.OnParseError("Expected type parameter");
            }

            while (NextChar != VBSymbol.EndParameterList &&
                NextChar != EmptyChar)
            {
                if (genericElement.TypeParameters.Count > 0 && NextChar == VBSymbol.AliasSeparator)
                {
                    TryReadChar();
                }

                string typeParameterName = CaptureWord();

                EatWhiteSpace();

                if (NextChar == EmptyChar)
                {
                    break;
                }

                TypeParameter typeParameter = new TypeParameter();
                typeParameter.Name = typeParameterName;

                if (NextChar != VBSymbol.AliasSeparator &&
                    NextChar != VBSymbol.EndParameterList)
                {
                    if (char.ToLower(NextChar) == char.ToLower(VBKeyword.As[0]))
                    {
                        TryReadChar();

                        if (char.ToLower(NextChar) == char.ToLower(VBKeyword.As[1]))
                        {
                            TryReadChar();

                            EatWhiteSpace();

                            if (NextChar == VBSymbol.EndParameterList)
                            {
                                this.OnParseError("Expected type parameter constraint");
                            }

                            if (NextChar == VBSymbol.BeginTypeConstraintList)
                            {
                                TryReadChar();

                                while (NextChar != VBSymbol.EndTypeConstraintList &&
                                    NextChar != EmptyChar)
                                {
                                    string typeParameterConstraint;
                                    typeParameterConstraint = ParseTypeParameterConstraint();
                                    typeParameter.AddConstraint(typeParameterConstraint);
                                }

                                EatChar(VBSymbol.EndTypeConstraintList);
                            }
                            else
                            {
                                while (NextChar != VBSymbol.EndParameterList &&
                                    NextChar != EmptyChar)
                                {
                                    string typeParameterConstraint;
                                    typeParameterConstraint = ParseTypeParameterConstraint();
                                    typeParameter.AddConstraint(typeParameterConstraint);
                                }
                            }
                        }
                    }
                }

                genericElement.AddTypeParameter(typeParameter);
            }

            EatChar(VBSymbol.EndParameterList);
        }
        /// <summary>
        /// Writes the type parameter constraints.
        /// </summary>
        /// <param name="typeParameter">The type parameter.</param>
        private void WriteTypeParameterConstraints(TypeParameter typeParameter)
        {
            if (typeParameter.Constraints.Count > 0)
            {
                Writer.Write(' ');
                Writer.Write(VBKeyword.As);
                Writer.Write(' ');

                if (typeParameter.Constraints.Count > 1)
                {
                    Writer.Write(VBSymbol.BeginTypeConstraintList);
                }

                for (int constraintIndex = 0; constraintIndex < typeParameter.Constraints.Count;
                    constraintIndex++)
                {
                    string constraint = typeParameter.Constraints[constraintIndex];
                    Writer.Write(constraint);

                    if (constraintIndex < typeParameter.Constraints.Count - 1)
                    {
                        Writer.Write(VBSymbol.AliasSeparator);
                        Writer.Write(' ');
                    }
                }

                if (typeParameter.Constraints.Count > 1)
                {
                    Writer.Write(VBSymbol.EndTypeConstraintList);
                }
            }
        }
Example #10
0
        /// <summary>
        /// Adds a type parameter to the type parameter list.
        /// </summary>
        /// <param name="typeParameter">The type parameter to add.</param>
        public void AddTypeParameter(TypeParameter typeParameter)
        {
            if (typeParameter == null)
            {
                throw new ArgumentNullException("typeParameter");
            }

            TypeParametersBase.Add(typeParameter);
        }
        /// <summary>
        /// Parses a delegate.
        /// </summary>
        /// <param name="memberName">Member name</param>
        /// <param name="access">Code access</param>
        /// <param name="memberAttributes">Member attributes</param>
        /// <param name="returnType">Return type</param>
        /// <returns>A delegate code element.</returns>
        private DelegateElement ParseDelegate(
            string memberName, CodeAccess access, MemberModifiers memberAttributes, string returnType)
        {
            DelegateElement delegateElement = new DelegateElement();
            delegateElement.Name = memberName;
            delegateElement.Access = access;
            delegateElement.Type = returnType;
            delegateElement.MemberModifiers = memberAttributes;

            int genericIndex = memberName.IndexOf(CSharpSymbol.BeginGeneric);
            bool isGeneric = genericIndex >= 0 && genericIndex < memberName.Length - 1;
            if (isGeneric)
            {
                delegateElement.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);
                foreach (string typeParameterName in typeParameterNames)
                {
                    TypeParameter typeParameter = new TypeParameter();
                    typeParameter.Name = typeParameterName;
                    delegateElement.AddTypeParameter(typeParameter);
                }
            }

            delegateElement.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(delegateElement);
            }

            EatChar(CSharpSymbol.EndOfStatement);

            return delegateElement;
        }
        /// <summary>
        /// Parses a type definition.
        /// </summary>
        /// <param name="access">Type accessibility.</param>
        /// <param name="typeAttributes">Type modifiers.</param>
        /// <param name="elementType">Type element type.</param>
        /// <returns>Type code element.</returns>
        private TypeElement ParseType(
            CodeAccess access,
            TypeModifiers typeAttributes,
            TypeElementType elementType)
        {
            TypeElement typeElement = new TypeElement();

            EatWhiteSpace();
            string className = CaptureWord();
            typeElement.Name = className;
            typeElement.Access = access;
            typeElement.Type = elementType;
            typeElement.TypeModifiers = typeAttributes;

            EatWhiteSpace();

            if (elementType == TypeElementType.Enum)
            {
                EatWhiteSpace();

                if (NextChar == CSharpSymbol.TypeImplements)
                {
                    TryReadChar();
                    string interfaceName = CaptureTypeName();
                    InterfaceReference interfaceReference =
                        new InterfaceReference(interfaceName, InterfaceReferenceType.None);
                    typeElement.AddInterface(interfaceReference);
                }

                string enumText = ParseBlock(true, typeElement);

                // TODO: Parse enum values as fields
                typeElement.BodyText = enumText;
            }
            else
            {
                bool isGeneric = TryReadChar(CSharpSymbol.BeginGeneric);
                if (isGeneric)
                {
                    string[] typeParameterNames = ParseAliasList();
                    foreach (string typeParameterName in typeParameterNames)
                    {
                        TypeParameter typeParameter = new TypeParameter();
                        typeParameter.Name = typeParameterName;
                        typeElement.AddTypeParameter(typeParameter);
                    }

                    EatWhiteSpace();

                    if (!TryReadChar(CSharpSymbol.EndGeneric))
                    {
                        this.OnParseError("Expected " + CSharpSymbol.EndGeneric);
                    }
                }

                EatWhiteSpace();

                bool implements = TryReadChar(CSharpSymbol.TypeImplements);

                if (implements)
                {
                    string[] typeList = ParseAliasList();
                    foreach (string type in typeList)
                    {
                        InterfaceReference interfaceReference =
                            new InterfaceReference(type, InterfaceReferenceType.None);
                        typeElement.AddInterface(interfaceReference);
                    }
                }

                EatWhiteSpace();

                ParseTypeParameterConstraints(typeElement);

                // Associate any additional comments in the type definition with the type.
                ReadOnlyCollection<ICommentElement> extraComments = ParseComments();
                foreach (ICommentElement comment in extraComments)
                {
                    typeElement.AddHeaderComment(comment);
                }

                EatChar(CSharpSymbol.BeginBlock);

                EatWhiteSpace();

                if (NextChar != CSharpSymbol.EndBlock)
                {
                    //
                    // Parse child elements
                    //
                    List<ICodeElement> childElements = ParseElements(typeElement);
                    foreach (ICodeElement childElement in childElements)
                    {
                        typeElement.AddChild(childElement);
                    }
                }

                EatChar(CSharpSymbol.EndBlock);
            }

            //
            // Types allow a trailing semi-colon
            //
            EatTrailingEndOfStatement();

            return typeElement;
        }
        /// <summary>
        /// Parses a method.
        /// </summary>
        /// <param name="memberName">Member name.</param>
        /// <param name="access">Code access.</param>
        /// <param name="memberAttributes">Member attributes.</param>
        /// <param name="returnType">Return type.</param>
        /// <param name="isOperator">Whether or not the method is an operator.</param>
        /// <param name="operatorType">Type of the operator.</param>
        /// <returns>Method code element.</returns>
        private MethodElement ParseMethod(
            string memberName,
            CodeAccess access,
            MemberModifiers memberAttributes,
            string returnType,
            bool isOperator,
            OperatorType operatorType)
        {
            MethodElement method = new MethodElement();
            method.Name = memberName;
            method.Access = access;
            method.Type = returnType;
            method.MemberModifiers = memberAttributes;
            method.IsOperator = isOperator;
            method.OperatorType = operatorType;
            if (isOperator &&
                (operatorType == OperatorType.Implicit || operatorType == OperatorType.Explicit))
            {
                method.Type = memberName;
                method.Name = null;
            }

            int genericIndex = memberName.LastIndexOf(CSharpSymbol.BeginGeneric);
            int lastQualifierIndex = memberName.LastIndexOf(CSharpSymbol.AliasQualifier);
            bool isGeneric = !isOperator &&
                (genericIndex >= 0 && genericIndex < memberName.Length - 1 &&
                (lastQualifierIndex < 0 || lastQualifierIndex < genericIndex));
            if (isGeneric)
            {
                method.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);
                foreach (string typeParameterName in typeParameterNames)
                {
                    TypeParameter typeParameter = new TypeParameter();
                    typeParameter.Name = typeParameterName;
                    method.AddTypeParameter(typeParameter);
                }
            }

            method.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(method);
            }

            EatWhiteSpace();
            bool endOfStatement = NextChar == CSharpSymbol.EndOfStatement;
            if (endOfStatement)
            {
                TryReadChar();
                method.BodyText = null;
            }
            else
            {
                method.BodyText = this.ParseBlock(true, method);
            }

            return method;
        }
Example #14
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            TypeParameter clone = new TypeParameter();

            //
            // Copy state
            //
            clone._name = _name;
            foreach (string constraint in Constraints)
            {
                clone.AddConstraint(constraint);
            }

            return clone;
        }
Example #15
0
        /// <summary>
        /// Parses a delegate.
        /// </summary>
        /// <param name="memberName">Member name</param>
        /// <param name="access">Code access</param>
        /// <param name="memberAttributes">Member attributes</param>
        /// <param name="returnType">Return type</param>
        /// <returns>A delegate code element.</returns>
        private DelegateElement ParseDelegate(
			string memberName, CodeAccess access, MemberModifiers memberAttributes, string returnType)
        {
            DelegateElement delegateElement = new DelegateElement();
            delegateElement.Name = memberName;
            delegateElement.Access = access;
            delegateElement.Type = returnType;
            delegateElement.MemberModifiers = memberAttributes;

            int genericIndex = memberName.IndexOf(CSharpSymbol.BeginGeneric);
            bool isGeneric = genericIndex >= 0 && genericIndex < memberName.Length - 1;
            if (isGeneric)
            {
                delegateElement.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);

                bool checkVariance = false;
                for (int i = 0; i < typeParameterNames.Length; i++)
                {
                    string typeParameterName = typeParameterNames[i];
                    if (typeParameterName == "in" || typeParameterName == "out")
                    {
                        checkVariance = true;
                        continue;
                    }
                    TypeParameter typeParameter = new TypeParameter();

                    if (checkVariance)
                    {
                        checkVariance = false;
                        typeParameter.IsIn = typeParameterNames[i - 1] == "in";
                        typeParameter.IsOut = typeParameterNames[i - 1] == "out";
                    }
                    typeParameter.Name = typeParameterName;
                    delegateElement.AddTypeParameter(typeParameter);
                }
            }

            delegateElement.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(delegateElement);
            }

            EatChar(CSharpSymbol.EndOfStatement);

            return delegateElement;
        }
Example #16
0
        /// <summary>
        /// Parses a method.
        /// </summary>
        /// <param name="memberName">Member name.</param>
        /// <param name="access">Code access.</param>
        /// <param name="memberAttributes">Member attributes.</param>
        /// <param name="returnType">Return type.</param>
        /// <param name="isOperator">Whether or not the method is an operator.</param>
        /// <param name="operatorType">Type of the operator.</param>
        /// <returns>Method code element.</returns>
        private MethodElement ParseMethod(
			string memberName,
			CodeAccess access,
			MemberModifiers memberAttributes,
			string returnType,
			bool isOperator,
			OperatorType operatorType)
        {
            MethodElement method = new MethodElement();
            method.Name = memberName;
            method.Access = access;
            method.Type = returnType;
            method.MemberModifiers = memberAttributes;
            method.IsOperator = isOperator;
            method.OperatorType = operatorType;
            if (isOperator &&
                (operatorType == OperatorType.Implicit || operatorType == OperatorType.Explicit))
            {
                method.Type = memberName;
                method.Name = null;
            }

            int genericIndex = memberName.LastIndexOf(CSharpSymbol.BeginGeneric);
            int lastQualifierIndex = memberName.LastIndexOf(CSharpSymbol.AliasQualifier);
            bool isGeneric = !isOperator &&
                             (genericIndex >= 0 && genericIndex < memberName.Length - 1 &&
                              (lastQualifierIndex < 0 || lastQualifierIndex < genericIndex));
            if (isGeneric)
            {
                method.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);
                foreach (string typeParameterName in typeParameterNames)
                {
                    TypeParameter typeParameter = new TypeParameter();
                    typeParameter.Name = typeParameterName;
                    method.AddTypeParameter(typeParameter);
                }
            }

            method.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(method);
            }

            EatWhiteSpace();
            bool endOfStatement = NextChar == CSharpSymbol.EndOfStatement;
            if (endOfStatement)
            {
                TryReadChar();
                method.BodyText = null;
            }
            else
            {
                bool expression = NextChar == CSharpSymbol.Assignment;
                if (expression)
                {
                    var expressionHead = new[] { CSharpSymbol.ExpressionBodyArrow1, CSharpSymbol.ExpressionBodyArrow2 };
                    // lucky for us, expressions can only have one statement (unlike expression lambdas),
                    // therefore we must have text like this "=> followed.by.a.statement;" which ParseOptionalAssignment will automatically trim to "followed.by.a.statement"
                    method.BodyText = this.ParseOptionalExpression(expressionHead);
                    method.HasExpressionBody = true;
                    if (string.IsNullOrEmpty(method.BodyText))
                    {
                        // is expression, but no suitable body found
                        this.OnParseError("Unexpected end of method. Expected " + new string(expressionHead) + " or a method body.");
                    }
                }
                else
                {
                    method.BodyText = this.ParseBlock(true, method);
                }
            }

            return method;
        }