Source Code Cross Referenced for CompilerErrorModel.java in  » IDE » DrJava » edu » rice » cs » drjava » model » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.drjava.model.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.drjava.model.compiler;
038:
039:        import java.io.File;
040:        import java.io.IOException;
041:        import javax.swing.text.*;
042:        import java.util.Arrays;
043:        import java.util.List;
044:        import java.util.LinkedList;
045:        import java.util.HashMap;
046:
047:        import edu.rice.cs.util.StringOps;
048:        import edu.rice.cs.util.UnexpectedException;
049:        import edu.rice.cs.drjava.model.DummyGlobalModel;
050:        import edu.rice.cs.drjava.model.FileGroupingState;
051:        import edu.rice.cs.drjava.model.GlobalModel;
052:        import edu.rice.cs.util.OperationCanceledException;
053:        import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
054:        import edu.rice.cs.drjava.model.FileMovedException;
055:
056:        /**
057:         * Contains the CompilerErrors for a particular file after
058:         * a compile has ended.
059:         * @version $Id: CompilerErrorModel.java 4255 2007-08-28 19:17:37Z mgricken $
060:         */
061:        public class CompilerErrorModel {
062:            private static final String newLine = StringOps.EOL;
063:            /** An array of errors to be displayed in the CompilerErrorPanel associated with this model.  After model
064:             *  construction, this array should be sorted in this order:
065:             *   (i) Errors with no file.
066:             *   (ii) Errors for each file in path-alphabetical order.
067:             *   Within each file:
068:             *       errors with no line number
069:             *       errors with line numbers, in order
070:             * In all cases, where all else is equal, warnings are sorted below errors.
071:             */
072:            private final CompilerError[] _errors;
073:
074:            /** An array of file offsets, parallel to the _errors array. NOTE: If there is no position associated with an error,
075:             *  its entry here should be set to null.
076:             */
077:            private final Position[] _positions;
078:
079:            /** The size of _errors and _positions.  This should never change after model construction*/
080:            private final int _numErrors;
081:
082:            /** The number of compile errors. Used for display purposes only.*/
083:            private int _numCompilerErrors;
084:
085:            /** The number of compile errors. Used for display purposes only.*/
086:            private int _numWarnings;
087:
088:            /** Cached result of hasOnlyWarnings.
089:             *  Three-state enum:
090:             *  -1 => result has not been computed
091:             *   0 => false
092:             *   1 => true
093:             */
094:            private int _onlyWarnings = -1;
095:
096:            /** Used internally in building _positions.  The file used as the index *must* be a canonical file, or else
097:             *  errors won't always be associated with the right documents.
098:             */
099:            private final HashMap<File, StartAndEndIndex> _filesToIndexes = new HashMap<File, StartAndEndIndex>();
100:
101:            /** The global model which created/controls this object. */
102:            private final GlobalModel _model;
103:
104:            /** Constructs an empty CompilerErrorModel with no errors and a dummy global model. */
105:            public CompilerErrorModel() {
106:                _model = new DummyGlobalModel() {
107:                    public OpenDefinitionsDocument getDocumentForFile(File file) {
108:                        throw new IllegalStateException("No documents to get!");
109:                    }
110:
111:                    public boolean isAlreadyOpen(File file) {
112:                        return false;
113:                    }
114:
115:                    public List<OpenDefinitionsDocument> getOpenDefinitionsDocuments() {
116:                        return new LinkedList<OpenDefinitionsDocument>();
117:                    }
118:
119:                    public boolean hasModifiedDocuments() {
120:                        return false;
121:                    }
122:
123:                    public boolean hasUntitledDocuments() {
124:                        return false;
125:                    }
126:                };
127:                _errors = new CompilerError[0];
128:                _numErrors = 0;
129:                _numWarnings = 0;
130:                _numCompilerErrors = 0;
131:                _positions = new Position[0];
132:            }
133:
134:            /** Constructs a new CompilerErrorModel with specified global model.  Performed in DefaultGlobalModel construction 
135:             * and after compilation has been performed.
136:             * @param errors the list of CompilerError's (or a subclass).
137:             * @param model is the model to find documents from
138:             */
139:            public CompilerErrorModel(CompilerError[] errors, GlobalModel model) {
140:                _model = model;
141:
142:                // TODO: If we move to NextGen-style generics, ensure _errors is non-null.
143:                _errors = errors;
144:
145:                _numErrors = errors.length;
146:                _positions = new Position[errors.length];
147:
148:                _numWarnings = 0;
149:                _numCompilerErrors = 0;
150:                for (int i = 0; i < errors.length; i++) {
151:                    if (errors[i].isWarning())
152:                        _numWarnings++;
153:                    else
154:                        _numCompilerErrors++;
155:                }
156:
157:                // Sort the errors by file and position
158:                Arrays.sort(_errors);
159:
160:                // Populates _positions.
161:                _calculatePositions();
162:            }
163:
164:            /**
165:             * Accessor for errors maintained here.
166:             * @param idx the index of the error to retrieve
167:             * @return the error at index idx
168:             * @throws NullPointerException if this object was improperly initialized
169:             * @throws ArrayIndexOutOfBoundsException if !(0 <= idx < this.getNumErrors())
170:             */
171:            public CompilerError getError(int idx) {
172:                return _errors[idx];
173:            }
174:
175:            /** Returns the position of the given error in the document representing its file. */
176:            public Position getPosition(CompilerError error) {
177:                int spot = Arrays.binarySearch(_errors, error);
178:                return _positions[spot];
179:            }
180:
181:            /** Returns the number of CompilerErrors. */
182:            public int getNumErrors() {
183:                return _numErrors;
184:            }
185:
186:            /** Returns the number of CompilerErrors that are compiler errors */
187:            public int getNumCompErrors() {
188:                return _numCompilerErrors;
189:            }
190:
191:            /** Returns the number of CompilerErrors that are warnings */
192:            public int getNumWarnings() {
193:                return _numWarnings;
194:            }
195:
196:            /** Prints out this model's errors. */
197:            public String toString() {
198:                final StringBuilder buf = new StringBuilder();
199:                buf.append(this .getClass().toString() + ":\n  ");
200:                for (int i = 0; i < _numErrors; i++) {
201:                    buf.append(_errors[i].toString());
202:                    buf.append("\n  ");
203:                }
204:                return buf.toString();
205:            }
206:
207:            /** This method finds and returns the error that is at the given offset
208:             *  @param odd the OpenDefinitionsDocument where you want to find the error at the caret
209:             *  @param offset the offset into the document
210:             *  @return the CompilerError at the given offset, null if no error corresponds to this location
211:             */
212:            public CompilerError getErrorAtOffset(OpenDefinitionsDocument odd,
213:                    int offset) {
214:                File file;
215:                try {
216:                    file = odd.getFile();
217:                    if (file == null)
218:                        return null;
219:                } catch (FileMovedException e) {
220:                    file = e.getFile();
221:                }
222:
223:                // Use the canonical file if possible
224:                try {
225:                    file = file.getCanonicalFile();
226:                } catch (IOException ioe) {
227:                    // Oh well, we'll look for it as is.
228:                }
229:
230:                StartAndEndIndex saei = _filesToIndexes.get(file);
231:                if (saei == null)
232:                    return null;
233:                int start = saei.getStartPos();
234:                int end = saei.getEndPos();
235:                if (start == end)
236:                    return null;
237:
238:                // check if the dot is on a line with an error.
239:                // Find the first error that is on or after the dot. If this comes
240:                // before the newline after the dot, it's on the same line.
241:                int errorAfter; // index of the first error after the dot
242:                for (errorAfter = start; errorAfter < end; errorAfter++) {
243:                    if (_positions[errorAfter] == null) {
244:                        //This indicates something wrong, but it was happening before so...
245:                        return null;
246:                    }
247:                    if (_positions[errorAfter].getOffset() >= offset)
248:                        break;
249:                }
250:
251:                // index of the first error before the dot
252:                int errorBefore = errorAfter - 1;
253:
254:                // this will be set to what we want to select, or -1 if nothing
255:                int shouldSelect = -1;
256:
257:                if (errorBefore >= start) { // there's an error before the dot
258:                    int errPos = _positions[errorBefore].getOffset();
259:                    try {
260:                        String betweenDotAndErr = odd.getText(errPos, offset
261:                                - errPos);
262:                        if (betweenDotAndErr.indexOf('\n') == -1)
263:                            shouldSelect = errorBefore;
264:                    } catch (BadLocationException e) { /* source document has been edited; fail silently */
265:                    }
266:                }
267:
268:                if ((shouldSelect == -1) && (errorAfter < end)) {// (errorAfter != _positions.length)) {
269:                    // we found an error on/after the dot
270:                    // if there's a newline between dot and error,
271:                    // then it's not on this line
272:                    int errPos = _positions[errorAfter].getOffset();
273:                    try {
274:                        String betweenDotAndErr = odd.getText(offset, errPos
275:                                - offset);
276:                        if (betweenDotAndErr.indexOf('\n') == -1)
277:                            shouldSelect = errorAfter;
278:                    } catch (BadLocationException e) { /* source document has been edited; fail silently */
279:                    }
280:                }
281:
282:                if (shouldSelect == -1)
283:                    return null;
284:                return _errors[shouldSelect];
285:            }
286:
287:            /** This function tells if there are errors with source locations associated with the given file. */
288:            public boolean hasErrorsWithPositions(OpenDefinitionsDocument odd) {
289:                File file = null;
290:                try {
291:                    file = odd.getFile();
292:                    if (file == null)
293:                        return false;
294:                } catch (FileMovedException fme) {
295:                    file = fme.getFile();
296:                }
297:
298:                // Try to use the canonical file
299:                try {
300:                    file = file.getCanonicalFile();
301:                } catch (IOException ioe) { /* Oh well, look for the file as is.*/
302:                }
303:
304:                StartAndEndIndex saei = _filesToIndexes.get(file);
305:                if (saei == null)
306:                    return false;
307:                if (saei.getStartPos() == saei.getEndPos())
308:                    return false;
309:                return true;
310:            }
311:
312:            /** Checks whether all CompilerErrors contained here are actually warnings. This would indicate that there were no
313:             *  "real" errors, so output is valid.
314:             *  @return false if any error contained here is not a warning, true otherwise
315:             */
316:            public boolean hasOnlyWarnings() {
317:                // Check for a cached value.
318:                if (_onlyWarnings == 0)
319:                    return false;
320:                if (_onlyWarnings == 1)
321:                    return true;
322:                else {
323:                    // If there was no cached value, compute it.
324:                    boolean clean = true;
325:                    for (int i = 0; clean && (i < _numErrors); i++) {
326:                        clean = _errors[i].isWarning();
327:                    }
328:                    // Cache the value.
329:                    _onlyWarnings = clean ? 1 : 0;
330:                    return clean;
331:                }
332:            }
333:
334:            /** Create array of positions where each error occurred. Positions are related their corresponding documents. */
335:            private void _calculatePositions() {
336:                try {
337:                    int curError = 0;
338:
339:                    // for (; numProcessed < _numErrors; numProcessed++) {
340:                    while ((curError < _numErrors)) {
341:                        // find the next error with a line number (skipping others)
342:                        curError = nextErrorWithLine(curError);
343:                        if (curError >= _numErrors) {
344:                            break;
345:                        }
346:
347:                        //Now find the file and document we are working on
348:                        File file = _errors[curError].file();
349:                        OpenDefinitionsDocument document;
350:                        try {
351:                            document = _model.getDocumentForFile(file);
352:                        } catch (Exception e) {
353:                            // This is intended to catch IOException or OperationCanceledException
354:                            if ((e instanceof  IOException)
355:                                    || (e instanceof  OperationCanceledException)) {
356:                                // skip positions for these errors if the document couldn't be loaded
357:                                do {
358:                                    curError++;
359:                                } while ((curError < _numErrors)
360:                                        && (_errors[curError].file()
361:                                                .equals(file)));
362:
363:                                //If the document couldn't be loaded, start the loop over at the top
364:                                continue;
365:                            } else
366:                                throw new UnexpectedException(e);
367:                        }
368:                        if (curError >= _numErrors)
369:                            break;
370:
371:                        // curError is the first error in a file, and its document is open.
372:                        final int fileStartIndex = curError;
373:                        final int defsLength = document.getLength();
374:                        final String defsText = document.getText(0, defsLength);
375:                        int curLine = 0;
376:                        int offset = 0; // offset is number of chars from beginning of file
377:
378:                        // offset is always pointing to the first character in the line
379:                        // containing an error (or the last line of the previous file) at the top of this loop
380:                        while ((curError < _numErrors) && // we still have errors to find
381:                                file.equals(_errors[curError].file()) && // the next error is in this file
382:                                (offset <= defsLength)) { // we haven't gone past the end of the file
383:                            // create new positions for all errors on this line          
384:                            boolean didNotAdvance = false;
385:                            if (_errors[curError].lineNumber() != curLine) {
386:                                // if this happens, then we will not advance to the next error in the loop below.
387:                                // that means we have to advance curError when we reach the end of the document
388:                                // or we get stuck in an infinite loop (bug 1679178)
389:                                // this seems to be a problem with incompatible line endings (Windows vs. Unix)
390:                                didNotAdvance = true;
391:                            } else {
392:                                while ((curError < _numErrors)
393:                                        && file
394:                                                .equals(_errors[curError]
395:                                                        .file()) && // we are still in this file
396:                                        (_errors[curError].lineNumber() == curLine)) {
397:                                    _positions[curError] = document
398:                                            .createPosition(offset
399:                                                    + _errors[curError]
400:                                                            .startColumn());
401:                                    curError++;
402:                                }
403:                            }
404:
405:                            // At this point, offset is the starting index of the previous error's line.
406:                            // Update offset to be appropriate for the current error.
407:                            // ... but don't bother looking if it isn't in this file.
408:                            // ... or if we're done with all errors already.
409:                            if (curError < _numErrors) {
410:                                int curErrorLine = _errors[curError]
411:                                        .lineNumber();
412:                                int nextNewline = 0;
413:                                while ((curLine != curErrorLine)
414:                                        && (nextNewline != -1)
415:                                        && (file.equals(_errors[curError]
416:                                                .file()))) {
417:                                    nextNewline = defsText.indexOf(newLine,
418:                                            offset);
419:                                    if (nextNewline == -1)
420:                                        nextNewline = defsText.indexOf("\n",
421:                                                offset);
422:                                    if (nextNewline != -1) {
423:                                        curLine++;
424:                                        offset = nextNewline + 1;
425:                                    } else {
426:                                        // we're at the end of the document
427:                                        if (didNotAdvance) {
428:                                            // we did not advance to the next error above, so unless we want to
429:                                            // get stuck in an infinite loop (bug 1679178), we have to advance now.
430:                                            // otherwise we would never leave the while loop and keep processing
431:                                            // the same error.
432:                                            // this situation probably means that the line number information of the
433:                                            // compiler is different from our line number information;
434:                                            // probably a Windows vs. Unix line ending problem
435:                                            _positions[curError] = null;
436:                                            curError++;
437:                                        }
438:                                    }
439:                                }
440:                            }
441:                        }
442:
443:                        //Remember the indexes in the _errors and _positions arrays that
444:                        // are for the errors in this file
445:                        int fileEndIndex = curError;
446:                        if (fileEndIndex != fileStartIndex) {
447:                            // Try to use the canonical file if possible
448:                            try {
449:                                file = file.getCanonicalFile();
450:                            } catch (IOException ioe) { /* Oh well, store it as is */
451:                            }
452:                            _filesToIndexes.put(file, new StartAndEndIndex(
453:                                    fileStartIndex, fileEndIndex));
454:                        }
455:                    }
456:                } catch (BadLocationException ble) {
457:                    throw new UnexpectedException(ble);
458:                }
459:            }
460:
461:            /** Finds the first error after numProcessed which has a file and line number.
462:             *  @param idx the starting index of the search
463:             *  @return the index of the found error
464:             */
465:            private int nextErrorWithLine(int idx) {
466:                while (idx < _numErrors
467:                        && (_errors[idx].hasNoLocation() || _errors[idx].file() == null))
468:                    idx++;
469:                return idx;
470:            }
471:
472:            /** This class is used only to track where the errors with positions for a file begin and end.  The beginning index 
473:             *  is inclusive, the ending index is exclusive.
474:             */
475:            private static class StartAndEndIndex {
476:                private int startPos;
477:                private int endPos;
478:
479:                public StartAndEndIndex(int startPos, int endPos) {
480:                    this .startPos = startPos;
481:                    this .endPos = endPos;
482:                }
483:
484:                public int getStartPos() {
485:                    return startPos;
486:                }
487:
488:                public int getEndPos() {
489:                    return endPos;
490:                }
491:            }
492:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.