001: package tide.compiler;
002:
003: import snow.Basics;
004: import tide.editor.MainEditorFrame;
005: import javax.swing.text.*;
006: import java.util.*;
007: import snow.texteditor.*;
008: import snow.utils.StringUtils;
009:
010: /** represents a compiler warning or error parsed from compiler process output stream
011: * search lines are also recognized here, with column and length.
012: */
013: public final class CompilerOutputItem {
014: // 0 based (first), -1 if none
015: public int lineStart = -1;
016: // 0 based (first), -1 if none (=> all line will be selected)
017: public int columnStart = -1;
018: // if -1, all line will be selected...
019: public int length = -1;
020:
021: public enum Type {
022: Warning, Error
023: }
024:
025: // for the tide search tool outputs
026: public int itemLength = -1;
027:
028: public Type type = Type.Error;
029: public String message;
030: public String javaName;
031: public String symbolInfo, locationInfo, requiredInfo, foundInfo;
032: public String warningCategory;
033: public String sourceLineWithPointer; // above the "^"
034:
035: // used to know from where next message could be parsed (from endLine+1)
036: public int endLine = -1;
037:
038: private CompilerOutputItem() {
039: }
040:
041: /** parse an item from a clicked line in the document
042: at from line, must contain a source position in correct syntax along with the message
043: following lines, optionally existing, contains symbol:, position:, or other informations
044:
045: @return null if not found or if not of correct syntax
046:
047: first line syntax:
048: tide\sources\SourceFile.java:177: warning: [unchecked] unchecked cast
049: CheckStyle:
050: c:/sources/a.b.c.java:122:3: cbad style (=> column 3)
051: Search
052: tide.sources.ddd.jav:22:8:12 (line, col, len)
053: */
054: public static CompilerOutputItem parseItem(Document doc,
055: int fromLine) {
056: CompilerOutputItem item = new CompilerOutputItem();
057:
058: String line = DocumentUtils.getTextOfLine(doc, fromLine);
059: int pos = line.indexOf(".java:");
060: if (pos == -1)
061: return null;
062:
063: // raw split
064: item.javaName = line.substring(0, pos).trim();
065: item.message = line.substring(pos + 6).trim(); // with line number and optional warning tag.
066:
067: // refine
068: pos = item.javaName.indexOf("> "); // occurs when a gobbler appended for example "JavaDoc> " before
069: if (pos >= 0) {
070: item.javaName = item.javaName.substring(pos + 2);
071: }
072:
073: // JAVADOC special format
074: String srcPath = MainEditorFrame.instance.getActualProject()
075: .getSources_Home().getAbsolutePath();
076: if (item.javaName.startsWith(srcPath)) {
077: item.javaName = item.javaName.substring(srcPath.length());
078: }
079:
080: item.javaName = item.javaName.replace('\\', '.');
081: if (item.javaName.startsWith(".")) {
082: item.javaName = item.javaName.substring(1);
083: }
084:
085: // [July2006]: remove stack traces
086: if (item.javaName.indexOf('(') >= 0)
087: return null;
088:
089: //System.out.println("MESS="+item.message);
090:
091: // at this moment, item.message is one of "123: mess" or 123:4: mess"...
092:
093: // line number
094: pos = item.message.indexOf(':');
095: if (pos > 0) {
096: String lineNb = item.message.substring(0, pos);
097: try {
098: item.lineStart = Integer.parseInt(lineNb) - 1; // messages nbs are 1 based !
099: item.message = item.message.substring(pos + 1).trim();
100: } catch (NumberFormatException ignored) {
101: Basics.ignore(ignored);
102: }
103: }
104:
105: // column number
106: pos = item.message.indexOf(':');
107: if (pos > 0) {
108: String colNb = item.message.substring(0, pos);
109: try {
110: item.columnStart = Integer.parseInt(colNb) - 1; // messages nbs are 1 based !
111: item.message = item.message.substring(pos + 1).trim();
112: } catch (NumberFormatException ignored) {
113: Basics.ignore(ignored);
114: }
115: }
116:
117: // length
118: pos = item.message.indexOf(':');
119: if (pos > 0) {
120: String lenNb = item.message.substring(0, pos);
121: try {
122: item.itemLength = Integer.parseInt(lenNb);
123: item.message = item.message.substring(pos + 1).trim();
124: } catch (NumberFormatException ignored) {
125: Basics.ignore(ignored);
126: }
127: }
128:
129: item.type = Type.Error;
130: int posWarn = item.message.indexOf("warning:");
131: if (posWarn >= 0) {
132: item.message = item.message.substring(posWarn + 8).trim();
133: item.type = Type.Warning;
134: item.warningCategory = StringUtils
135: .extractFromFirstToNext_Excluded(item.message, "[",
136: "]");
137: if (item.warningCategory != null) {
138: // remove
139: item.message = StringUtils.removeBeforeIncluded(
140: item.message, "]");
141: }
142: }
143:
144: // look at next lines (max 10)
145: item.endLine = fromLine;
146: for (int i = fromLine + 1; i < fromLine + 10; i++) {
147: String linei = DocumentUtils.getTextOfLine(doc, i);
148: if (linei == null)
149: break;
150:
151: item.endLine = i;
152: if (linei.trim().equals("")) {
153: item.endLine = i - 1; // we made too much
154: break; // next message reached !
155: } else if (linei.trim().equals("^")) {
156: item.sourceLineWithPointer = DocumentUtils
157: .getTextOfLine(doc, i - 1);
158: item.columnStart = linei.indexOf('^');
159: break; // end reached...
160: } else if (linei.indexOf(".java:") > 0) {
161: item.endLine = i - 1; // we made too much
162: break; // next message reached !
163: } else if (linei.startsWith("symbol")) {
164: item.symbolInfo = StringUtils.removeBeforeIncluded(
165: linei, ":").trim();
166: } else if (linei.startsWith("found")) {
167: item.foundInfo = StringUtils.removeBeforeIncluded(
168: linei, ":").trim();
169: } else if (linei.startsWith("required")) {
170: item.requiredInfo = StringUtils.removeBeforeIncluded(
171: linei, ":").trim();
172: } else if (linei.startsWith("location")) {
173: item.locationInfo = StringUtils.removeBeforeIncluded(
174: linei, ":").trim();
175: }
176: }
177:
178: return item;
179: }
180:
181: @Override
182: public String toString() {
183: return "Compiler output item: "
184: + type
185: + "\n message= "
186: + message
187: + (this .warningCategory != null ? " (cat "
188: + warningCategory + ")" : "")
189: + "\n javaName= "
190: + javaName
191: + "\n position= "
192: + lineStart
193: + ", col="
194: + columnStart
195: //+ (item.absolutePosStart>=0 ? ", abs={"+item.absolutePosStart+", "+item.absolutePosEnd+"}":"")
196: + (this .locationInfo != null ? "\nlocation:"
197: + locationInfo : "")
198: + (this .requiredInfo != null ? "\nrequired:"
199: + requiredInfo : "")
200: + (this .foundInfo != null ? "\nfound:" + foundInfo : "")
201: + (this .symbolInfo != null ? "\nsymbol:" + symbolInfo
202: : "")
203: + (this .sourceLineWithPointer != null ? "\nsrc line:"
204: + sourceLineWithPointer : "");
205: }
206:
207: }
|