/// <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); }
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."); }
/// <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); }
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."); }
/// <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); }
/// <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); }
/// <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); }
/// <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); } } }
/// <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; }
/// <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; }
/// <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; }
/// <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; }