001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2004-2006 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.tree;
020:
021: import java.util.ArrayList;
022: import java.util.List;
023:
024: import xtc.util.Utilities;
025:
026: /**
027: * A source code comment.
028: *
029: * @author Robert Grimm
030: * @version $Revision: 1.11 $
031: */
032: public class Comment extends Annotation {
033:
034: /** The kind of comment. */
035: public static enum Kind {
036: /** A single line. */
037: SINGLE_LINE,
038: /** Multiple lines. */
039: MULTIPLE_LINES,
040: /** Documentation. */
041: DOCUMENTATION
042: }
043:
044: /** The kind. */
045: public Kind kind;
046:
047: /** The actual text, one line per list entry. */
048: public List<String> text;
049:
050: /**
051: * Create a new comment.
052: *
053: * @param kind The kind.
054: * @param text The text.
055: */
056: public Comment(Kind kind, List<String> text) {
057: this (kind, text, null);
058: }
059:
060: /**
061: * Create a new comment.
062: *
063: * @param kind The kind.
064: * @param text The text.
065: * @param node The node.
066: */
067: public Comment(Kind kind, List<String> text, Node node) {
068: super (node);
069: this .kind = kind;
070: this .text = text;
071: }
072:
073: public int hashCode() {
074: return text.hashCode();
075: }
076:
077: public boolean equals(Object o) {
078: if (this == o)
079: return true;
080: if (!(o instanceof Comment))
081: return false;
082: Comment other = (Comment) o;
083: if (kind != other.kind)
084: return false;
085: if (!text.equals(other.text))
086: return false;
087: if (null == node)
088: return (null == other.node);
089: return node.equals(other.node);
090: }
091:
092: /**
093: * Create a new code documentation comment. If the specified text
094: * is <code>null</code>, it is passed through.
095: *
096: * @param s The text of the comment, including start and end markers.
097: * @return The comment.
098: */
099: public static Comment documentation(String s) {
100: // Make sure we have something to work with.
101: if (null == s) {
102: return null;
103: } else if (4 > s.length()) {
104: throw new IllegalArgumentException(
105: "Invalid documentation comment");
106: }
107:
108: // Split the text.
109: s = s.substring(3, s.length() - 2);
110: String[] ss = Utilities.COMMENT_NEWLINE.split(s);
111:
112: // Trim the first and last line.
113: if (0 < ss.length) {
114: ss[0] = ss[0].trim();
115: if (1 != ss.length) {
116: ss[ss.length - 1] = ss[ss.length - 1].trim();
117: }
118: }
119:
120: // Find empty lines at beginning and end.
121: int start = ss.length;
122: int end = ss.length - 1;
123:
124: for (int i = 0; i < ss.length; i++) {
125: if (!"".equals(ss[i])) {
126: start = i;
127: break;
128: }
129: }
130:
131: for (int i = ss.length - 1; i >= 0; i--) {
132: if (!"".equals(ss[i])) {
133: end = i;
134: break;
135: }
136: }
137:
138: // Create a new list without any leading or trailing empty lines.
139: List<String> l = new ArrayList<String>(end - start + 1);
140: for (int i = start; i <= end; i++) {
141: l.add(ss[i]);
142: }
143:
144: // Done.
145: return new Comment(Kind.DOCUMENTATION, l);
146: }
147:
148: }
|