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