001: package tide.compiler;
002:
003: import tide.outputtabs.OutputTextPanel;
004: import tide.project.*;
005: import tide.sources.*;
006: import tide.editor.*;
007: import snow.utils.storage.*;
008: import snow.utils.*;
009: import snow.texteditor.*;
010: import snow.datatransfer.*;
011: import javax.swing.*;
012: import java.awt.*;
013: import java.awt.event.*;
014: import javax.swing.border.*;
015: import javax.swing.text.*;
016: import java.util.*;
017: import java.io.*;
018: import java.text.*;
019: import java.util.regex.*;
020:
021: /** Also used for tools and search results !
022: * is also able to recognize stacktraces...
023: */
024: public class CompilerOutputPanel extends OutputTextPanel //JPanel
025: {
026: public static final Pattern lineNumberFormat1 = Pattern
027: .compile("\\:(\\d+)\\:"); // compiler output (number in group 1)
028: public static final Pattern lineNumberFormat2 = Pattern
029: .compile("\\.java\\:(\\d+)\\)"); // stacktrace (number in group 1)
030:
031: public CompilerOutputPanel() {
032: super (false);
033: }
034:
035: /** Installs copy paste ops very useful to paste stacktraces
036: from client exceptions for example...
037: */
038: @Override
039: public void showPopup(MouseEvent me) {
040: JPopupMenu popup = createPopupBase(me);
041: popup.show(pane, me.getX(), me.getY());
042: }
043:
044: /** The compiler produce warnings and errors that allow to localize the corresponding source line.
045: */
046: @Override
047: public void lineClicked(MouseEvent me) {
048: int pt = pane.viewToModel(me.getPoint());
049: Element lineElt = doc.getParagraphElement(pt);
050: String clickedLine = doc.getTextFromTo(
051: lineElt.getStartOffset(), lineElt.getEndOffset());
052: int clickedLineNumber = DocumentUtils.getLineNumber(doc, pt);
053:
054: // New method, working with compiler outputs + search outputs
055: CompilerOutputItem ci = CompilerOutputItem.parseItem(doc,
056: clickedLineNumber);
057: if (ci != null) {
058: //System.out.println("coplic: "+ci);
059:
060: FileItem sf = MainEditorFrame.instance.getFileItem(
061: ci.javaName, "");
062: if (sf != null && sf.hasTextRepresentation()) {
063: MainEditorFrame.instance.setSourceOrItemToEditOrView(
064: sf, true);
065:
066: setHighlightedElementOnly(lineElt);
067: MainEditorFrame.instance.editorPanel.selectItem(ci);
068:
069: return;
070: }
071: }
072:
073: // System.out.println("CompClicked not comp syntax, try2: "+clickedLine);
074: if (tryToRecognizeASourceFile_compilerSyntax(clickedLine,
075: clickedLineNumber)) {
076: setHighlightedElementOnly(lineElt);
077: return;
078: }
079:
080: // System.out.println("CompClicked not comp syntax, try3: "+clickedLine);
081: if (OutputPanels
082: .recognizeStackTraceLine_AndSelectInEditorIfFound(clickedLine) != null) {
083: setHighlightedElementOnly(lineElt);
084: return;
085: }
086:
087: // System.out.println("CompClicked not comp syntax, try4: "+clickedLine);
088: if (OutputPanels
089: .recognizeLineWithAbsoluteSourceName_AndSelectInEditorIfFound(clickedLine) != null) {
090: setHighlightedElementOnly(lineElt);
091: return;
092: }
093:
094: // System.out.println("CompClicked not comp syntax, try5: "+clickedLine);
095: if (OutputPanels
096: .recognizeSimpleSyntaxLine_AndSelectInEditorIfFound(clickedLine) != null) {
097: setHighlightedElementOnly(lineElt);
098: return;
099: }
100:
101: }
102:
103: /** Compiler syntax: tide\sources\SourceFile.java:177: warning: [unchecked] unchecked cast
104: * JavaDoc: JavaDoc> C:\sources\other\Script\src\javaparser\JavaLexer.java:6: package antlr does not exist
105: @return false if failed to recognize such a line
106:
107: REMARK: the new mechanism with CompilerOutputItem is better !
108: this however remains because it can parse javadocs and search result lines
109: */
110: private boolean tryToRecognizeASourceFile_compilerSyntax(
111: String clickedLine, int clickedLineNumber) {
112: int pos = clickedLine.indexOf(".java:");
113: if (pos == -1)
114: return false;
115:
116: // maybe we have a source to show as in at aaa.c.main(c.java:15)
117: // or aaa.d.main(d.java:15)
118: String javaName = clickedLine.substring(0, pos);
119: pos = javaName.indexOf("> "); // occurs when a gobbler appended for example "JavaDoc> " before
120: if (pos >= 0) {
121: javaName = javaName.substring(pos + 2);
122: }
123:
124: final String srcPath = MainEditorFrame.instance
125: .getActualProject().getSources_Home().getAbsolutePath();
126: if (javaName.startsWith(srcPath)) {
127: javaName = javaName.substring(srcPath.length());
128: }
129:
130: if (javaName.indexOf('/') >= 0) {
131: //linux ! [Oct2007]
132: javaName = javaName.replace('/', '.');
133: }
134:
135: if (javaName.indexOf('\\') >= 0) {
136: javaName = javaName.replace('\\', '.');
137: }
138:
139: if (javaName.startsWith("."))
140: javaName = javaName.substring(1);
141:
142: // get first matching aaa.c.main ==> aaa.c
143: //SourceFile sf = MainEditorFrame.instance.sourcesTreePanel.getTreeModel().getSourceFileContaining(javaName);
144: FileItem sf = MainEditorFrame.instance
145: .getFileItem(javaName, "");
146: if (sf == null || !sf.hasTextRepresentation()) {
147: //System.out.println("not found2 : "+javaName);
148: return false;
149: }
150:
151: MainEditorFrame.instance.setSourceOrItemToEditOrView(sf, true);
152:
153: final int srcline = readLineNumber(clickedLine);
154: int srccol = readColumnNumber(clickedLineNumber);
155: MainEditorFrame.instance.editorPanel.selectLinePart(
156: srcline - 1, srccol); // index start with zero in the document, 1 in the comments
157:
158: return true;
159: }
160:
161: /** @return 1 in case of an error or if no line could be read
162: */
163: private static int readLineNumber(String str) {
164: Matcher m = lineNumberFormat1.matcher(str);
165: if (m.find()) {
166: String n = str.substring(m.start() + 1, m.end() - 1);
167: try {
168: return Integer.parseInt(n);
169: } catch (NumberFormatException ignored) {
170: }
171: }
172:
173: m = lineNumberFormat2.matcher(str);
174: if (m.find()) {
175: System.out.println("found !");
176: try {
177: String n = str.substring(m.start(1), m.end(1));
178: System.out.println("n=" + n);
179: return Integer.parseInt(n);
180: } catch (NumberFormatException ignored) {
181: }
182: }
183:
184: return 1;
185: }
186:
187: /** The compiler oftens tells where the error column is, placing a single "^" on a line after the error.
188: @return -1 if not found.
189: */
190: private int readColumnNumber(int lineNumberOfErrorMessage) {
191: for (int i = lineNumberOfErrorMessage + 2; i < lineNumberOfErrorMessage + 6; i++) // TODO: stop if next warning or error appears...
192: {
193: int col = readColumnNumber(DocumentUtils.getTextOfLine(doc,
194: i));
195: if (col > 0)
196: return col;
197: }
198: return -1;
199: }
200:
201: /** The compiler oftens tells where the error column is, placing a single "^" on a line after the error.
202: @return -1 if not found.
203: */
204: private int readColumnNumber(String line) {
205: if (line == null)
206: return -1;
207: if (line.trim().equals("^")) // bug found by FB: was '^'
208: {
209: return line.indexOf('^') + 1;
210: }
211: return -1;
212: }
213:
214: public static void main(String[] a) {
215: System.out.println("" + readLineNumber("hello(a.java:223)"));
216: Pattern p = Pattern.compile("\\:\\d+\\:");
217: String str = "JavaDoc> C:\\sources\\other\\Script\\src\\javaparser\\JavaLexer.java:6: package antlr does not exist";
218: Matcher m = p.matcher(str);
219: if (m.find()) {
220: System.out.println(str
221: .substring(m.start() + 1, m.end() - 1));
222: }
223: }
224:
225: }
|