001: /***** BEGIN LICENSE BLOCK *****
002: * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003: *
004: * The contents of this file are subject to the Common Public
005: * License Version 1.0 (the "License"); you may not use this file
006: * except in compliance with the License. You may obtain a copy of
007: * the License at http://www.eclipse.org/legal/cpl-v10.html
008: *
009: * Software distributed under the License is distributed on an "AS
010: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011: * implied. See the License for the specific language governing
012: * rights and limitations under the License.
013: *
014: * Copyright (C) 2001-2002 Jan Arne Petersen <jpetersen@uni-bonn.de>
015: * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
016: * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
017: * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
018: * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
019: * Copyright (C) 2006 Thomas Corbat <tcorbat@hsr.ch>
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * either of the GNU General Public License Version 2 or later (the "GPL"),
023: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
024: * in which case the provisions of the GPL or the LGPL are applicable instead
025: * of those above. If you wish to allow use of your version of this file only
026: * under the terms of either the GPL or the LGPL, and not to allow others to
027: * use your version of this file under the terms of the CPL, indicate your
028: * decision by deleting the provisions above and replace them with the notice
029: * and other provisions required by the GPL or the LGPL. If you do not delete
030: * the provisions above, a recipient may use your version of this file under
031: * the terms of any one of the CPL, the GPL or the LGPL.
032: ***** END LICENSE BLOCK *****/package org.jruby.ast;
033:
034: import java.io.Serializable;
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.Iterator;
038: import java.util.List;
039:
040: import org.jruby.ast.visitor.NodeVisitor;
041: import org.jruby.evaluator.Instruction;
042: import org.jruby.evaluator.InstructionBundle;
043: import org.jruby.evaluator.InstructionContext;
044: import org.jruby.lexer.yacc.ISourcePosition;
045: import org.jruby.lexer.yacc.ISourcePositionHolder;
046: import org.jruby.lexer.yacc.IDESourcePosition;
047:
048: /**
049: *
050: * @author jpetersen
051: */
052: public abstract class Node implements ISourcePositionHolder,
053: InstructionContext, Serializable {
054: static final long serialVersionUID = -5962822607672530224L;
055: // We define an actual list to get around bug in java integration (1387115)
056: static final List EMPTY_LIST = new ArrayList();
057:
058: public final int nodeId;
059:
060: public InstructionBundle instruction;
061:
062: private ISourcePosition position;
063: private ArrayList comments;
064:
065: public Node(ISourcePosition position, int id) {
066: this .position = position;
067: this .nodeId = id;
068: }
069:
070: /**
071: * Location of this node within the source
072: */
073: public ISourcePosition getPosition() {
074: return position;
075: }
076:
077: public void setPosition(ISourcePosition position) {
078: this .position = position;
079: }
080:
081: public abstract Instruction accept(NodeVisitor visitor);
082:
083: public abstract List childNodes();
084:
085: static void addNode(Node node, List list) {
086: if (node != null)
087: list.add(node);
088: }
089:
090: //TODO: Change to variable parameter list method once we have Java 1.5
091: protected static List createList(Node node) {
092: List list = new ArrayList();
093: Node.addNode(node, list);
094: return list;
095: }
096:
097: protected static List createList(Node node1, Node node2) {
098: List list = createList(node1);
099: Node.addNode(node2, list);
100: return list;
101: }
102:
103: protected static List createList(Node node1, Node node2, Node node3) {
104: List list = createList(node1, node2);
105: Node.addNode(node3, list);
106: return list;
107: }
108:
109: protected static List createList(Node node1, Node node2,
110: Node node3, Node node4) {
111: List list = createList(node1, node2, node3);
112: Node.addNode(node4, list);
113: return list;
114: }
115:
116: public String toString() {
117: return getNodeName() + "[]";
118: }
119:
120: protected String getNodeName() {
121: String name = getClass().getName();
122: int i = name.lastIndexOf('.');
123: String nodeType = name.substring(i + 1);
124: return nodeType;
125: }
126:
127: public void addComment(CommentNode comment) {
128: if (comments == null) {
129: comments = new ArrayList();
130: }
131: comments.add(comment);
132: }
133:
134: public void addComments(Collection comments) {
135: if (this .comments == null) {
136: this .comments = new ArrayList();
137: }
138: this .comments.addAll(comments);
139: }
140:
141: public Collection getComments() {
142: if (comments == null) {
143: return EMPTY_LIST;
144: }
145: return comments;
146: }
147:
148: public boolean hasComments() {
149: return comments != null && !comments.isEmpty();
150: }
151:
152: public ISourcePosition getPositionIncludingComments() {
153: if (position == null || !hasComments()) {
154: return position;
155: }
156:
157: String fileName = position.getFile();
158: int startOffset = position.getStartOffset();
159: int endOffset = position.getEndOffset();
160: int startLine = position.getStartLine();
161: int endLine = position.getEndLine();
162:
163: // Since this is only used for IDEs this is safe code, but there is an obvious abstraction issue here.
164: ISourcePosition commentIncludingPos = new IDESourcePosition(
165: fileName, startLine, endLine, startOffset, endOffset);
166:
167: Iterator commentItr = comments.iterator();
168: while (commentItr.hasNext()) {
169: ISourcePosition commentPos = ((CommentNode) commentItr
170: .next()).getPosition();
171: commentIncludingPos = IDESourcePosition.combinePosition(
172: commentIncludingPos, commentPos);
173: }
174:
175: return commentIncludingPos;
176: }
177:
178: }
|