package bluej.parser.nodes;

import bluej.debugger.gentype.GenTypeClass;
import bluej.editor.moe.MoeSyntaxDocument;
import bluej.editor.moe.Token;
import bluej.parser.ExpressionTypeInfo;
import bluej.parser.entity.JavaEntity;
import bluej.parser.nodes.NodeTree.NodeAndPosition;
import threadchecker.OnThread;
import threadchecker.Tag;

import java.util.Iterator;


| A "parsed node" represents a node in a limited parse tree. The tree is limited because |* it contains only a subset of elements that might normally be found in a full parse tree. * A ParsedNode tree does however contain information to precisely map nodes to source code | document positions.<p> | | Also included is basic infrastructure for incremental parsing. | | @author Davin McCall | public abstract class ParsedNode extends RBTreeNode<ParsedNode>{ public static final int NODETYPE_NONE = 0; public static final int NODETYPE_TYPEDEF = 1; public static final int NODETYPE_METHODDEF = 2; public static final int NODETYPE_ITERATION = 3; public static final int NODETYPE_SELECTION = 4; public static final int NODETYPE_FIELD = 5; public static final int NODETYPE_EXPRESSION = 6; public static final int NODETYPE_COMMENT = 7;
| The NodeTree containing the child nodes of this node | private NodeTree<ParsedNode> nodeTree;
| The parent ParsedNode which contains us | private ParsedNode parentNode; private boolean hasAttachedComment;
| Specifies whether this node is complete, in that its end is properly marked with an | appropriate token. | protected boolean complete; private boolean isInner = false; public ParsedNode() { nodeTree = new NodeTree<ParsedNode>(); } ParsedNode(ParsedNode parentNode) { this(); this.parentNode = parentNode; } public Iterator> getChildren(int offset) { return nodeTree.iterator(offset); }
| Get the type of this node. One of: | <ul> | <li>NODETYPE_NONE - unspecified | <li>NODETYPE_TYPEDEF - a type definition (class, interface etc) | <li>NODETYPE_METHODDEF - a method defintion | <li>NODETYPE_ITERATION - an iteration construct (for loop etc) | <li>NODETYPE_SELECTION - a selection construct (if/else etc) | <li>NODETYPE_FIELD - a field or variable declaration | <li>NODETYPE_EXPRESSION - an expression | <li>NODETYPE_COMMENT - a code comment | </ul> | public int getNodeType() { return NODETYPE_NONE; }
| Specify whether this node is complete - that is, it is ended by an appropriate token. | public void setComplete(boolean complete) { this.complete = complete; }
| Check whether this node is known to be complete. | public boolean isComplete() { return complete; }
| Get the name of the entity this node represents. For methods, returns the method name. | May return null. | public String getName() { return null; } public boolean equals(Object obj) { return obj == this; }
| If text is inserted immediately before this node, should it be made part of this | node? For instance in a method inner body, this would be true, seeing as anything | after the '{} (which is part of the outer body) must by definition be part of the | inner body. | public boolean growsForward() { return false; }
| Returns true if this node marks its own end, that is, the token signifying | the end of this node is contained within this node itself, rather than in | the parent node. | protected abstract boolean marksOwnEnd();
| Insert a new child node (without affecting position of other children). | public void insertNode(ParsedNode child, int position, int size) { getNodeTree().insertNode(child, position, size); } public void childChangedName(ParsedNode child, String oldName) { }
| Find the child node (if any) overlapping (including starting or ending at) the given position. | | @param position The position of the child node to find | @param startpos The position of this node | @return the "leftmost" child which overlaps the position |*/ public final NodeAndPosition<ParsedNode> findNodeAt(int position, int startpos) { return nodeTree.findNode(position, startpos); } | |/** | Find the child node (if any) at or after the given position | @param position The position of the child node to find | @param startpos The position of this node | public final NodeAndPosition findNodeAtOrAfter(int position, int startpos) { return nodeTree.findNodeAtOrAfter(position, startpos); }
| Set the size of this node. Following nodes shift position according to the change in | size; this should normally be used when inserting or removing text from the node. | @param newSize The new node size | public void resize(int newSize) { getContainingNodeTree().resize(newSize); }
| Set the size of this node, without moving following nodes. It is the caller's | responsibility to ensure that setting the new size does not cause this node | to overlap following nodes. | @param newSize The new size of this node. | public void setSize(int newSize) { getContainingNodeTree().setSize(newSize); }
| Get the offset of this node from its parent node. | public int getOffsetFromParent() { if (getContainingNodeTree() == null) { return 0; } return getContainingNodeTree().getPosition(); }
| Remove this node from the parent, without disturbing the position of any sibling nodes. | Probably, you don't want to call this directly; call removeChild() on the parent instead. | public void remove() { getContainingNodeTree().remove(); }
| Is this a "container" scope for highlighting purposes |* @return */ public boolean isContainer() { return false; } /** * Is this an "inner" scope for highlighting purposes */ public boolean isInner() { return isInner; } /** * Set whether this is an inner scope for highlighting purposes public void setInner(boolean inner) { isInner = inner; }
| Get the size of this node. | public int getSize() { return getContainingNodeTree().getNodeSize(); }
| Constants for status of various methods defined below | protected final static int ALL_OK = 0; protected final static int NODE_GREW = 1; protected final static int NODE_SHRUNK = 2; protected final static int REMOVE_NODE = 3; | Insert the given text. | | <p>The result should be one of ALL_OK, NODE_GREW, NODE_SHRUNK, or REMOVE_NODE. | The latter indicates that the caller should remove the node. Except in the | case of ALL_OK, the parent node must generally be re-parsed. | | <p>Note, it is expected that the node grows by the amount of text inserted - | the return should be ALL_OK rather than NODE_GREW if that is the case. | | @param document The document | @param nodePos The position of "this" node (relative to the document). |* @param insPos The position of the insert (relative to the document). * @param length The length of the insert * @param listener The listener for node structural changes public abstract int textInserted(MoeSyntaxDocument document, int nodePos, int insPos, int length, NodeStructureListener listener);
| The specified portion of text within the node has been removed.<p> | | <p>The result should be one of ALL_OK, NODE_GREW, NODE_SHRUNK, or REMOVE_NODE. | The latter indicates that the caller should remove the node. Except in the | case of ALL_OK, the parent node must generally be re-parsed. | | <p>It is expected that the node shrink by the amount of text removed - the | return should be ALL_OK rather than NODE_SHRUNK if that is the case. | | @param document The document | @param nodePos The position of "this" node (relative to the document). |* @param insPos The position of the removal (relative to the document). * @param length The length of the removal * @param listener The listener for node structural changes public abstract int textRemoved(MoeSyntaxDocument document, int nodePos, int delPos, int length, NodeStructureListener listener);
| This node should be re-parsed from the specified point. The node position | and offset are relative to the document beginning.<p> | | The result should be one of ALL_OK, NODE_GREW, NODE_SHRUNK, or REMOVE_NODE. | The latter indicates that the caller should remove the node. Except in the | case of ALL_OK, the parent node must generally also be re-parsed.<p> | | This method should always mark which range it parsed in the document. | protected int reparseNode(MoeSyntaxDocument document, int nodePos, int offset, int maxParse, NodeStructureListener listener) { return ALL_OK; }
| Perform a re-parse of the document at a given point. The parse may be partial; a certain amount of | parsing will be performed and further re-parses will be queued as necessary against the document. | | @param document The document | @param nodePos The position of this node | @param offset The position within the document of the re-parse | @param maxParse The (advisory) maximum amount of document to re-parse in one hit | @param listener The structure listener to be notified of structural changes | public void reparse(MoeSyntaxDocument document, int nodePos, int offset, int maxParse, NodeStructureListener listener) { int size = getSize(); int r = reparseNode(document, nodePos, offset, maxParse, listener); if (r == REMOVE_NODE) { ParsedNode parent = getParentNode(); parent.removeChild(new NodeAndPosition<ParsedNode>(this, nodePos, getSize()), listener); document.scheduleReparse(nodePos + size - 1, 0); } else if (r == NODE_GREW || r == NODE_SHRUNK) { int nsize = getSize(); ParsedNode parent = getParentNode(); if (parent != null) { int ppos = nodePos - getOffsetFromParent(); parent.childResized(document, ppos, new NodeAndPosition<ParsedNode>(this, nodePos, nsize)); } document.scheduleReparse(nodePos + nsize, Math.max(size - nsize, 0)); } }
| Get a sequence of "tokens" which indicate the colour and position/size of various tokens |* in a line of source code text. * @param pos The position of the text to tokenize (document relative). Must be on a * line or token boundary. | @param length The length of the text to tokenize. Must be on a line or token boundary. | @param nodePos The position of the node | @param document The source document | @return A linked list of Token objects | public abstract Token getMarkTokensFor(int pos, int length, int nodePos, MoeSyntaxDocument document); protected ParsedNode getParentNode() { return parentNode; } protected NodeTree getNodeTree() { return nodeTree; }
| This node is shortened, it no longer needs all the text assigned to it. | protected void nodeShortened(int newLength) { }
| This node has become incomplete (needs to be extended). | protected void nodeIncomplete() { }
| GrowChild() is called by a child node when, during incremental parsing, it determines | that it needs to grow in size. The response must be to increase the size of the child | and return true, or (if increasing size is really not possible) to return false, or to | return false and assume responsibility for re-parsing.<p> | | It is the responsibility of this method to notify the listener of the child's change | in size, if it occurs. | @OnThread(Tag.FXPlatform) protected boolean growChild(MoeSyntaxDocument document, NodeAndPosition<ParsedNode> child, NodeStructureListener listener) { return false; }
| Called after a child node changed size. This is just a notification | and should not cause a reparse to be performed or scheduled, as that | should be done elsewhere. | | @param document The document which parse structure is represented | @param nodePos The absolute position of this node | @param child The child node which has changed size | public void childResized(MoeSyntaxDocument document, int nodePos, NodeAndPosition<ParsedNode> child) { }
| Get code completion suggestions at a particular point. May return null. | @OnThread(Tag.FXPlatform) public ExpressionTypeInfo getExpressionType(int pos, MoeSyntaxDocument document) { return getExpressionType(pos, 0, null, document); }
| Get code completion suggestions at a particular point. May return null. | | @param pos The position to suggest completions for | @param nodePos The position of this node | @param defaultType The type to return if there is no explicit type at the given location | @param document The source document | @OnThread(Tag.FXPlatform) protected ExpressionTypeInfo getExpressionType(int pos, int nodePos, JavaEntity defaultType, MoeSyntaxDocument document) { NodeAndPosition<ParsedNode> child = getNodeTree().findNode(pos, nodePos); if (child != null) { return child.getNode().getExpressionType(pos, child.getPosition(), defaultType, document); } GenTypeClass atype = (defaultType != null) ? defaultType.getType().asClass() : null; if (atype == null) { return null; } boolean isStaticCtxt = (defaultType.resolveAsType() != null); return new ExpressionTypeInfo(atype, atype, null, isStaticCtxt, true); }
| Remove a child node, and notify the NodeStructureListener that the child and | its descendants have been removed. Won't disturb the position of subsequent | children. The "child" NodeAndPosition parameter specifies the absolute location |* of the child node, not its position relative to "this" node. */ protected final void removeChild(NodeAndPosition<ParsedNode> child, NodeStructureListener listener) { child.getNode().remove(); childRemoved(child, listener); } | |protected void childRemoved(NodeAndPosition<ParsedNode> child, NodeStructureListener listener) | |{ | |listener.nodeRemoved(child); | |removeChildren(child, listener); | |} | |/** | Notify the NodeStructureListener that all descendants of a particular node | are removed, due to the node itself having been removed. (Note this does not actually | remove the children from the parent node). | protected static void removeChildren(NodeAndPosition<ParsedNode> node, NodeStructureListener listener) { Iterator<NodeAndPosition<ParsedNode>> i = node.getNode().getChildren(node.getPosition()); while (i.hasNext()){ NodeAndPosition<ParsedNode> nap = i.next(); listener.nodeRemoved(nap); removeChildren(nap, listener); } }
| Check whether a documentary comment is attached to this node. | public boolean isCommentAttached() { return hasAttachedComment; }
| Specify whether or not this node has a documentary comment attached to it. | public void setCommentAttached(boolean commentAttached) { hasAttachedComment = commentAttached; } }

.   ParsedNode
.   getChildren
.   getNodeType
.   setComplete
.   isComplete
.   getName
.   equals
.   growsForward
.   marksOwnEnd
.   insertNode
.   childChangedName
.   findNodeAtOrAfter
.   resize
.   setSize
.   getOffsetFromParent
.   remove
.   setInner
.   getSize
.   textInserted
.   textRemoved
.   reparseNode
.   reparse
.   getMarkTokensFor
.   getParentNode
.   getNodeTree
.   nodeShortened
.   nodeIncomplete
.   growChild
.   childResized
.   getExpressionType
.   getExpressionType
.   removeChildren
.   isCommentAttached
.   setCommentAttached




384 neLoCode + 120 LoComm