Enhanced C#
Language of your choice: library documentation
Properties | Public Member Functions | Protected Member Functions | Static Protected Member Functions | List of all members
Loyc.Syntax.AbstractTriviaInjector< Trivia > Class Template Referenceabstract

Encapsulates an algorithm that consumes trivia (comments and newlines) from a list and adds it as trivia attributes into LNodes. More...


Source file:

Remarks

Encapsulates an algorithm that consumes trivia (comments and newlines) from a list and adds it as trivia attributes into LNodes.

Call Run to invoke the algorithm. One must also write a derived class that knows how to interpret the trivia and associate it with a specific LNode, or use the standard derived class StandardTriviaInjector.

The algorithm is designed to postprocess output from a parser that works in a typical way. The lexer for your language needs to follow the following rules:

Typically one will wrap the lexer in Lexing.TriviaSaver, which saves trivia while filtering out whitespace so that the parser doesen't see it.

Your language's parser needs to follow the following rules:

This example shows how comments are associated with nodes: [NOTE: the space in "* /" is a workaround for a serious bug in Doxygen, the html doc generator]

// Comment attached to block
{
  // Comment attached to Foo() call
  Foo(
    // Comment attached to «argument1 + 1». Note that the comma is 
    // generally invisible to the injector since it is not part of the LNode 
    // tree, so the 1st and 2nd comments will both be attached to the sum-
    // expression as a whole.
    argument1 + 1 /*1st comment* /, // 2nd comment
    // Comment attached to «argument2 + 2»
    argument2 + 2); // Comment attached to Foo() call
  Area = 3.14159265/*PI* / * /*radius* /r**2;
  // Comment attached to «Area =» statement, preceded by newline trivia?
  // Comment attached to Bar()
   // Comment attached to BarAttr attribute
  Bar();
  // Comment attached to Bar() because there are no statements afterward
}

When there is a single newline between two nodes, Run will associate it with the second one. When there is a blank line between two nodes (two newlines), the first newline (and any before) is associated with the first node and the second newline (and any following) is associated with the second.

Properties

IListSource< Trivia > SortedTrivia [get, set]
 List of trivia to be injected by Run. Must be sorted. More...
 
int NextIndex [get, set]
 Index of next trivia to be injected. More...
 

Public Member Functions

 AbstractTriviaInjector (IListSource< Trivia > sortedTrivia)
 Initializes the SortedTrivia property. More...
 
IEnumerator< LNodeRun (IEnumerator< LNode > nodes)
 Attaches trivia to the input nodes provided. More...
 

Protected Member Functions

abstract VList< LNodeAttachTriviaTo (ref LNode node, IListSource< Trivia > trivia, TriviaLocation loc, LNode parent, int indexInParent)
 Derived class should associate the given list of trivia with the specified node. Leading trivia will be attached to a given node before trailing trivia. More...
 
virtual void MarkOneLiner (ref LNode node)
 This method is called when a node has no newlines or comments within it (although the node may still have a leading or trailing comment). It informs the derived class that AbstractTriviaInjector<Trivia> will not traverse into the node. More...
 
abstract SourceRange GetRange (Trivia trivia)
 Gets the SourceRange for an element of trivia. More...
 
abstract bool IsNewline (Trivia trivia)
 Returns true if the trivia represents a newline, false otherwise. More...
 
virtual LNode GetEmptyResultSet ()
 A method called to create a virtual node to apply trivia to an empty source file. More...
 
virtual LNode DoneAttaching (LNode node, LNode parent, int indexInParent)
 This method is called after a node has been processed and any applicable trivia was attached. More...
 
IEnumerator< Pair< LNode, int > > RunCore (IEnumerator< Pair< LNode, int >> nodes, LNode parent)
 Core trivia associaton algorithm. More...
 

Static Protected Member Functions

static IEnumerator< Pair< T, int > > WithIndexes< T > (IEnumerator< T > e)
 

Constructor & Destructor Documentation

Loyc.Syntax.AbstractTriviaInjector< Trivia >.AbstractTriviaInjector ( IListSource< Trivia >  sortedTrivia)
inline

Initializes the SortedTrivia property.

Member Function Documentation

abstract VList<LNode> Loyc.Syntax.AbstractTriviaInjector< Trivia >.AttachTriviaTo ( ref LNode  node,
IListSource< Trivia >  trivia,
TriviaLocation  loc,
LNode  parent,
int  indexInParent 
)
protectedpure virtual

Derived class should associate the given list of trivia with the specified node. Leading trivia will be attached to a given node before trailing trivia.

Parameters
nodeThe node.
triviaTrivia to be associated with node.
locLocation of the trivia. For a given node, the base class calls this method at most once for each value of TriviaLocation.
parent(Original version of) parent of node.
indexInParentIndex of node within parent.
Returns
The same node with trivia attributes added. If loc indicates trailing trivia, the derived class can say "I don't want trivia to be associated with this node" by returning null; the base class will, if possible, associate it with the next node instead, but this doesn't work for the last child in a sequence; in that case this method is called again with the same trivia and loc is set to TriviaLocation.TrailingExtra.

This method may STILL called for a given node when there is no trivia associated with that node, IF the node is at the top level or its sibling nodes in the same parent have associated trivia.

virtual LNode Loyc.Syntax.AbstractTriviaInjector< Trivia >.DoneAttaching ( LNode  node,
LNode  parent,
int  indexInParent 
)
inlineprotectedvirtual

This method is called after a node has been processed and any applicable trivia was attached.

Parameters
nodeNode (after trivia attached)
parentParent of node (old version, before changes to children are applied)
indexInParentIndex of node within parent.
Returns
Should return node or an altered version of node.

This method gives the derived class one final chance to rearrange or alter the interpretation of the attached trivia. Note that this method may be called on some nodes to which trivia was not attached, when siblings of the same parent had trivia attached.

Reimplemented in Loyc.Ecs.Parser.EcsTriviaInjector.

virtual LNode Loyc.Syntax.AbstractTriviaInjector< Trivia >.GetEmptyResultSet ( )
inlineprotectedvirtual

A method called to create a virtual node to apply trivia to an empty source file.

Default implementation attaches all trivia to a "missing" node (zero-length identifier). If this method returns null then the result is discarded.

abstract SourceRange Loyc.Syntax.AbstractTriviaInjector< Trivia >.GetRange ( Trivia  trivia)
protectedpure virtual

Gets the SourceRange for an element of trivia.

abstract bool Loyc.Syntax.AbstractTriviaInjector< Trivia >.IsNewline ( Trivia  trivia)
protectedpure virtual

Returns true if the trivia represents a newline, false otherwise.

virtual void Loyc.Syntax.AbstractTriviaInjector< Trivia >.MarkOneLiner ( ref LNode  node)
inlineprotectedvirtual

This method is called when a node has no newlines or comments within it (although the node may still have a leading or trailing comment). It informs the derived class that AbstractTriviaInjector<Trivia> will not traverse into the node.

The default implementation sets the NodeStyle.OneLiner style flag.

IEnumerator<LNode> Loyc.Syntax.AbstractTriviaInjector< Trivia >.Run ( IEnumerator< LNode nodes)
inline

Attaches trivia to the input nodes provided.

Parameters
nodesList of input nodes. This method calls nodes.MoveNext() before calling nodes.Current.

Trailing trivia after all nodes is attached to the final node. If nodes is empty then GetEmptyResultSet is called to create a dummy node and attach all trivia to it.

IEnumerator<Pair<LNode, int> > Loyc.Syntax.AbstractTriviaInjector< Trivia >.RunCore ( IEnumerator< Pair< LNode, int >>  nodes,
LNode  parent 
)
inlineprotected

Core trivia associaton algorithm.

NOTE: the enumerator may DRIVE lexing and actually cause the trivia list (SortedTrivia) to increase in size. For this reason, this algorithm is careful to call nodes.MoveNext() BEFORE getting the current trivia. I'm not sure if this precaution is sufficient to preserve trivia in all "streaming" cases, but it seems to work in at least most cases.

Property Documentation

int Loyc.Syntax.AbstractTriviaInjector< Trivia >.NextIndex
getsetprotected

Index of next trivia to be injected.

IListSource<Trivia> Loyc.Syntax.AbstractTriviaInjector< Trivia >.SortedTrivia
getset

List of trivia to be injected by Run. Must be sorted.