protected virtual void AsTextContent(CodeWriter writer, RenderFlags flags) { writer.EscapeUnicode = false; if (_content is string) { DocText.AsTextText(writer, GetContentForDisplay(flags), flags); } else if (_content is ChildList <DocComment> ) { ChildList <DocComment> content = (ChildList <DocComment>)_content; for (int i = 0; i < content.Count; ++i) { DocComment docComment = content[i]; if (docComment is DocText) { DocText.AsTextText(writer, GetContentForDisplay((DocText)docComment, i == 0, i == content.Count - 1, flags), flags); } else { docComment.AsText(writer, flags); } } } else if (_content is CodeObject) { // Turn on translation of '<', '&', and '>' for content writer.InDocCommentContent = true; ((CodeObject)_content).AsText(writer, flags); writer.InDocCommentContent = false; } writer.EscapeUnicode = true; }
/// <summary> /// Move any trailing post annotations on the last base type to the first constraint (if any) as prefix annotations. /// </summary> protected void AdjustBaseTypePostComments() { if (_baseTypes != null) { int baseTypes = _baseTypes.Count; if (baseTypes > 0 && _baseTypes[baseTypes - 1].HasPostAnnotations && HasConstraintClauses) { ChildList <Annotation> annotations = _baseTypes[baseTypes - 1].Annotations; for (int i = 0; i < annotations.Count;) { Annotation annotation = annotations[i]; if (annotation.IsPostfix) { annotation.IsPostfix = false; annotations.RemoveAt(i); if (annotation.IsListed) { NotifyListedAnnotationRemoved(annotation); } ConstraintClauses[0].AttachAnnotation(annotation); continue; } ++i; } if (annotations.Count == 0) { _baseTypes[baseTypes - 1].Annotations = null; } } } }
/// <summary> /// Create an <see cref="IndexerDecl"/>. /// </summary> public IndexerDecl(Expression name, Expression type, Modifiers modifiers, params ParameterDecl[] parameters) : base(CheckUnresolvedThisRef(name), type, modifiers) { // Save any parameters - these are NOT stored on the SetterDecl/GetterDecl, but are // instead accessed through the parent. _parameters = new ChildList <ParameterDecl>(parameters, this); }
/// <summary> /// Get the declaring generic type or method. /// </summary> public TypeRefBase GetDeclaringTypeOrMethod() { object reference = GetReferencedType(); if (reference is TypeParameter) { CodeObject parent = ((TypeParameter)reference).Parent; if (parent is GenericMethodDecl) { GenericMethodDecl methodDecl = (GenericMethodDecl)parent; return(methodDecl.CreateRef(ChildList <Expression> .CreateListOfNulls(methodDecl.TypeParameterCount))); } if (parent is ITypeDecl) { ITypeDecl typeDecl = (ITypeDecl)parent; return(typeDecl.CreateRef(ChildList <Expression> .CreateListOfNulls(typeDecl.TypeParameterCount))); } } else if (reference is Type) { Type typeParameter = (Type)reference; if (typeParameter.DeclaringMethod != null) { return(MethodRef.Create(typeParameter.DeclaringMethod)); } Type declaringType = ((Type)reference).DeclaringType; return(declaringType != null ? Create(declaringType) : null); } return(null); }
/// <summary> /// Create a multi field declaration from an array of FieldDecls. /// </summary> /// <param name="fieldDecls">An array of FieldDecls.</param> public MultiFieldDecl(params FieldDecl[] fieldDecls) : base(null, null) { _fieldDecls = new ChildList <FieldDecl>(this); if (fieldDecls.Length > 0) { // Acquire the Parent, Type, and Modifiers from the first FieldDecl FieldDecl fieldDecl1 = fieldDecls[0]; Parent = fieldDecl1.Parent; fieldDecl1.Parent = null; // Break parent link to avoid clone on Add SetField(ref _type, (Expression)fieldDecl1.Type.Clone(), true); _modifiers = fieldDecl1.Modifiers; // Also move any annotations from the first FieldDecl if (fieldDecl1.HasAnnotations) { Annotations = fieldDecl1.Annotations; fieldDecl1.Annotations = null; } // Add with internal method to avoid changes to Type, etc. foreach (FieldDecl fieldDecl in fieldDecls) { AddInternal(fieldDecl); } } }
public static void AsTextConstraints(CodeWriter writer, ChildList <ConstraintClause> constraints, RenderFlags flags) { if (constraints != null && constraints.Count > 0) { writer.WriteList(constraints, flags | RenderFlags.NoItemSeparators | (constraints[0].IsFirstOnLine ? 0 : RenderFlags.PrefixSpace), constraints.Parent); } }
/// <summary> /// Add the specified text to the documentation comment. /// </summary> public virtual void Add(string text) { if (text != null) { if (_content == null) { _content = text; } else if (_content is string) { _content += text; } else if (_content is ChildList <DocComment> ) { ChildList <DocComment> children = (ChildList <DocComment>)_content; if (children.Count == 0) { _content = text; } else if (children.Last is DocText) { children.Last.Add(text); } else { children.Add(new DocText(text)); } } else { throw new Exception("Can't add to a DocComment that contains code objects - add to the contained BlockDecl instead."); } } }
/// <summary> /// Parse an <see cref="Initializer"/>. /// </summary> public Initializer(Parser parser, CodeObject parent) : base(parser, parent) { MoveComments(parser.LastToken); // Associate any skipped comment objects // If the initializer doesn't start on a new line, or it's indented less than the parent object, set the NoIndentation // flag to prevent it from being formatted relative to the parent object. if (!IsFirstOnLine || parser.CurrentTokenIndentedLessThan(parser.ParentStartingToken)) { SetFormatFlag(FormatFlags.NoIndentation, true); } parser.NextToken(); // Move past '{' Token lastToken = parser.LastToken; MoveEOLCommentAsInfix(lastToken); // Parse the list of expressions _expressions = ParseList(parser, this, ParseTokenEnd); // Attach any skipped regular comment to the first item in the list if (_expressions != null && _expressions.Count > 0) { _expressions[0].MoveComments(lastToken); } if (ParseExpectedToken(parser, ParseTokenEnd)) // Move past '}' { EndNewLines = parser.LastToken.NewLines; // Set the newline count for the '}' MoveEOLComment(parser.LastToken); } }
/// <summary> /// Create the list of <see cref="Catch"/>s, or return the existing one. /// </summary> public ChildList <Catch> CreateCatches() { if (_catches == null) { _catches = new ChildList <Catch>(this); } return(_catches); }
/// <summary> /// Create the list of <see cref="TypeParameterConstraint"/>s, or return the existing one. /// </summary> public ChildList <TypeParameterConstraint> CreateConstraints() { if (_constraints == null) { _constraints = new ChildList <TypeParameterConstraint>(this); } return(_constraints); }
/// <summary> /// Create the list of argument <see cref="Expression"/>s, or return the existing one. /// </summary> public ChildList <Expression> CreateArguments() { if (_arguments == null) { _arguments = new ChildList <Expression>(this); } return(_arguments); }
/// <summary> /// Create the list of <see cref="Expression"/>s, or return the existing one. /// </summary> /// <returns></returns> public ChildList <Expression> CreateExpressions() { if (_expressions == null) { _expressions = new ChildList <Expression>(this); } return(_expressions); }
protected void ParseParameters(Parser parser) { // Parse the parameter declarations bool isEndFirstOnLine; _parameters = ParameterDecl.ParseList(parser, this, ParseTokenStart, ParseTokenEnd, false, out isEndFirstOnLine); IsEndFirstOnLine = isEndFirstOnLine; }
/// <summary> /// Create the list of <see cref="ConstraintClause"/>s, or return the existing one. /// </summary> public ChildList <ConstraintClause> CreateConstraintClauses() { if (_constraintClauses == null) { _constraintClauses = new ChildList <ConstraintClause>(this); } return(_constraintClauses); }
/// <summary> /// Create the list of <see cref="ParameterDecl"/>s, or return the existing one. /// </summary> public ChildList <ParameterDecl> CreateParameters() { if (_parameters == null) { _parameters = new ChildList <ParameterDecl>(this); } return(_parameters); }
/// <summary> /// Create the list of base type <see cref="Expression"/>s, or return the existing one. /// </summary> public ChildList <Expression> CreateBaseTypes() { if (_baseTypes == null) { _baseTypes = new ChildList <Expression>(this); } return(_baseTypes); }
/// <summary> /// Create the list of <see cref="TypeParameter"/>s, or return the existing one. /// </summary> public ChildList <TypeParameter> CreateTypeParameters() { if (_typeParameters == null) { _typeParameters = new ChildList <TypeParameter>(this); } return(_typeParameters); }
protected void ParseNameTypeParameters(Parser parser) { MoveComments(parser.LastToken); _name = parser.GetIdentifierText(); // Parse the name MoveEOLComment(parser.LastToken); // Associate any skipped EOL comment _typeParameters = TypeParameter.ParseList(parser, this); // Parse any type parameters MoveEOLComment(parser.LastToken); // Associate any skipped EOL comment }
/// <summary> /// Create a multi field declaration. /// </summary> /// <param name="type">The type of the multi field declaration.</param> /// <param name="names">The list of names to be used.</param> public MultiLocalDecl(Expression type, params string[] names) : base(null, type) { _localDecls = new ChildList <LocalDecl>(this); foreach (string name in names) { Add(new LocalDecl(name, (Expression)type.Clone())); } }
/// <summary> /// Create a multi field declaration. /// </summary> /// <param name="type">The type of the multi field declaration.</param> /// <param name="modifiers">The modifiers of the multi field declaration.</param> /// <param name="names">The list of names to be used.</param> public MultiFieldDecl(Expression type, Modifiers modifiers, params string[] names) : base(null, type, modifiers) { _fieldDecls = new ChildList <FieldDecl>(this); foreach (string name in names) { Add(new FieldDecl(name, (Expression)type.Clone(), modifiers)); } }
public static void AsTextTypeParameters(CodeWriter writer, ChildList <TypeParameter> typeParameters, RenderFlags flags) { RenderFlags passFlags = (flags & RenderFlags.PassMask); // Render the angle brackets as braces if we're inside a documentation comment writer.Write(flags.HasFlag(RenderFlags.InDocComment) ? ParseTokenAltStart : ParseTokenStart); writer.WriteList(typeParameters, passFlags, typeParameters.Parent); writer.Write(flags.HasFlag(RenderFlags.InDocComment) ? ParseTokenAltEnd : ParseTokenEnd); }
/// <summary> /// Create a <see cref="ChildList{T}"/> with the specified number of null entries. /// </summary> public static ChildList <T> CreateListOfNulls(int nullEntryCount) { ChildList <T> list = new ChildList <T>(nullEntryCount); for (int i = 0; i < nullEntryCount; ++i) { list.Add((T)null); } return(list); }
// NOTE: No parse-point is installed for general documentation comments - instead, the parser calls // the parsing method below directly based upon the token type. Documentation comments with // specific tags do have parse-points installed. // NOTE: Manual parsing of the XML is done instead of using an XML parser - this is for // performance, and to handle malformed XML properly, and also so embedded code references // and fragments can be parsed properly with the main parser. /// <summary> /// Parse a <see cref="DocComment"/>. /// </summary> public static DocComment Parse(Parser parser, CodeObject parent, ParseFlags flags) { Token token = parser.Token; byte prefixSpaceCount = (token.LeadingWhitespace.Length < byte.MaxValue ? (byte)token.LeadingWhitespace.Length : byte.MaxValue); // Get any newlines preceeding the documentation comment int newLines = token.NewLines; parser.NextToken(true); // Move past '///' or '/**' // Start a new Unused list in the parser to catch unrecognized tokens in otherwise valid tags, etc. // This must be done in order to prevent anything already in the unused list from being emitted // within the doc comment. parser.PushUnusedList(); // Remove any leading blank lines from inside the doc comment parser.Token.NewLines = 0; // Parse a DocComment object DocComment docComment = new DocComment(parser, parent) { NewLines = newLines }; // Restore the previous Unused list in the parser - it's the responsibility of the DocComment parsing // logic to flush any unused tokens, such as into the content area of the comment. parser.PopUnusedList(); // Remove the parent DocComment if it only has a single child if (docComment.Content is string) { DocText docText = new DocText((string)docComment.Content) { NewLines = newLines }; docText.SetLineCol(docComment); docComment = docText; } else { ChildList <DocComment> content = (ChildList <DocComment>)docComment.Content; if (content.Count == 1) { DocComment first = content[0]; first.NewLines = newLines; first.SetLineCol(docComment); docComment = first; } } // Store the number of prefixed spaces docComment._prefixSpaceCount = prefixSpaceCount; return(docComment); }
/// <summary> /// Helper method to convert a collection of Attributes to text. /// </summary> public static void AsTextAttributes(CodeWriter writer, ChildList <Attribute> attributes, RenderFlags flags) { if (attributes != null && attributes.Count > 0) { flags &= ~RenderFlags.Description; // Don't pass description flag through foreach (Attribute attrDecl in attributes) { attrDecl.AsText(writer, flags); } } }
/// <summary> /// Get the specified type parameters as a descriptive string. /// </summary> internal static string GetTypeParametersAsString(ChildList <TypeParameter> typeParameters) { string result = TypeParameter.ParseTokenStart; bool isFirst = true; foreach (TypeParameter typeParameter in typeParameters) { result += (isFirst ? "" : ", ") + typeParameter.Name; isFirst = false; } result += TypeParameter.ParseTokenEnd; return(result); }
/// <summary> /// Deep-clone the collection. /// </summary> public static ChildList <T> Clone <T>(ChildList <T> thisChildList, CodeObject parent) where T : CodeObject { if (thisChildList != null) { ChildList <T> clone = new ChildList <T>(thisChildList.Count, parent); foreach (T child in thisChildList) { clone.Add(child != null ? (T)child.Clone() : null); } return(clone); } return(null); }
/// <summary> /// Parse a list of constraint clauses. /// </summary> public static ChildList <ConstraintClause> ParseList(Parser parser, CodeObject parent) { ChildList <ConstraintClause> constraints = null; while (parser.TokenText == ParseToken) { if (constraints == null) { constraints = new ChildList <ConstraintClause>(parent); } constraints.Add(new ConstraintClause(parser, parent)); } return(constraints); }
protected Attribute(Parser parser, CodeObject parent) : base(parser, parent) { parser.NextToken(); // Move past '[' if (parser.PeekNextTokenText() == ParseTokenTarget) { _target = AttributeTargetHelpers.Parse(parser); } // Parse attribute expressions (will parse to a Call if parens are used, otherwise a ConstructorRef) _attributeExpressions = Expression.ParseList(parser, this, ParseTokenEnd); ParseExpectedToken(parser, ParseTokenEnd); // Move past ']' }
/// <summary> /// Normalize content. /// </summary> public void NormalizeContent() { if (_content is ChildList <DocComment> ) { ChildList <DocComment> children = (ChildList <DocComment>)_content; // Replace an empty collection with null if (children.Count == 0) { _content = null; } else { for (int i = children.Count - 1; i > 0; --i) { // Combine adjacent DocText objects into a single object if (children[i] is DocText && children[i - 1] is DocText) { children[i - 1].Add(children[i].Text); children.RemoveAt(i); } } if (children.Count == 1) { CodeObject child = children[0]; // Replace a single DocText with a string if (child is DocText) { _content = ((DocText)child).Text; } else if (child.NewLines > 0) { // Remove any newlines on the first child if they weren't explicitly set if (!child.IsNewLinesSet && child.NewLines > 0) { // Move the newlines to the parent if it hasn't been explicitly set if (!IsNewLinesSet) { SetNewLines(child.NewLines); } child.SetNewLines(0); } } } } } }
/// <summary> /// Create an <see cref="Unrecognized"/> object. /// </summary> public Unrecognized(bool parsingBlock, bool inDocComment, params Expression[] expressions) { // Only count unrecognized "real" code - ignore any inside doc comments if (!inDocComment) { ++Count; } _parsingBlock = parsingBlock; _inDocComment = inDocComment; _expressions = new ChildList <Expression>(this); foreach (Expression expression in expressions) { AddRight(expression); } }