alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.tasklist.javaparser;

import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import org.openide.ErrorManager;
import org.openide.cookies.SourceCookie;
import org.openide.explorer.view.*;
import org.openide.nodes.*;
import org.netbeans.modules.java.*;
import org.openide.filesystems.*;

import org.openide.src.*;

import org.openide.loaders.DataObject;
import org.openide.src.Identifier;
import org.openide.src.Import;
import org.openide.src.SourceElement;
import org.openide.src.SourceException;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

import org.openide.cookies.LineCookie;
import org.openide.loaders.DataObject;
import org.openide.text.Line;
import org.openide.ErrorManager;

import java.util.TreeSet;
import java.lang.reflect.Modifier;
import java.io.IOException;

import org.netbeans.editor.ext.java.*;
import org.netbeans.modules.editor.java.*;
import org.netbeans.modules.java.Parsing;
import org.netbeans.modules.java.ParserMessage;
import org.netbeans.modules.java.parser.*;

import org.netbeans.modules.tasklist.core.ConfPanel;
import org.netbeans.modules.tasklist.core.TLUtils;
import org.netbeans.modules.tasklist.client.*;
import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider;
import org.netbeans.modules.tasklist.providers.SuggestionContext;


/**
 * This class lists the javac errors for the current document/class
 * 

* It suggests following: *

    *
  • add import if unresolved class exists in CCDB *
  • correct case if unresolved class in CCDB *
  • convert unresolved variable into method call if empty parameter list method exists in CCDB *
  • create method for unresolver methods in current source code class *
  • convert length() to size() and vice versa if in CCDB *
  • cast to required type as reported by parser (no compatabilty checked) *
* * @author Tor Norbye */ public class ErrorSuggester extends DocumentSuggestionProvider implements Parsing.Listener { final private static String TYPE = "nb-java-errors"; // NOI18N // XXX as a hack, SuggestionList knows about the above type name // (to make the node expanded by default, whereas other types are collapsed) // so if you change the above, be sure to change it in SuggestionList // as well! public String getType() { return TYPE; } private SuggestionContext env; private Object request = null; // javadoc in super() // public void rescan(SuggestionContext env, Object request) { // this.request = request; // this.env = env; // Parsing.addParsingListener(this); // try { // DataObject dataObject = DataObject.find(env.getFileObject()); // // Cause a reparse, and then the resulting parse // // event will force a scan() // if (dataObject instanceof JavaDataObject) { // //Parsing.requestParse((JavaDataObject)dobj, false); // requestParse((JavaDataObject)dataObject, false); // } // } catch (IOException ex) { // ex.printStackTrace(); // } // } /** Request that a particular JavaDataObject is parsed. */ private static void requestParse(JavaDataObject jdo, boolean now) { // Note: the below (getCookie) creates an environment which // records the original data object associated with this parser, // that's why you don't see the file to be parsed anywhere else // here... JavaParser parser = (JavaParser)jdo.getCookie(JavaParser.class); if (parser == null) { System.out.println("Parser not found!"); return; } final ParseSourceRequest req; req = new ParseSourceRequest((Object)JavaParser.DEEP_PARSER); boolean ignoreClean = true; int priority = now ? JavaParser.PRIORITY_DEMAND : JavaParser.PRIORITY_NORMAL; org.openide.util.Task t = parser.parse(priority, ignoreClean, false, req); } public void notifyStop() { Parsing.removeParsingListener(this); } // The errors associated with the given data object has // changed private void errorsChanged(SuggestionContext env) { List newTasks = scan(env); SuggestionManager manager = SuggestionManager.getDefault(); if ((newTasks == null) && (showingTasks == null)) { return; } manager.register(TYPE, newTasks, showingTasks); showingTasks = newTasks; } /** Scan the given document for suggestions. Typically called * when a document is shown or when a document is edited, but * could also be called for example as part of a directory * scan for suggestions. *

* @param document The document being hidden * @param dataobject The Data Object for the file being opened * */ public List scan(SuggestionContext env) { ArrayList tasks = null; SuggestionManager manager = SuggestionManager.getDefault(); // >experimental JMI // List jmierrors = JMImpl.findErrors(env.getFileObject()); // Iterator ite = jmierrors.iterator(); // while (ite.hasNext()) { // Object next = (Object) ite.next(); // System.err.println("JMI-ERROR " + next); // } // 0)) { Arrays.sort(errors, new Comparator() { public int compare(Object o1, Object o2) { ParserMessage a = (ParserMessage)o1; ParserMessage b = (ParserMessage)o2; return a.getLineNumber() - b.getLineNumber(); } }); int n = errors.length; if (n > 30) { n = 30; } for (int i = 0; i < n; i++) { ParserMessage err = errors[i]; String summary = err.getDescription(); SuggestionAgent s = manager.createSuggestion(TYPE, summary, null, this); // Lazily compute Line from the ParserMessage. It // was removed from the interface because in the // implementation, pushError was getting called // with a null argument, so the ParserMessageImpl // object itself couldn't compute the data object // to find the line. Line line = TLUtils.getLineByNumber(dataObject, err.getLineNumber()); s.setLine(line); if (summary.indexOf("warning: ") != -1) { // Speecial image for icons s.setIcon(Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/warning.gif")); // NOI18N } s.setPriority(SuggestionPriority.HIGH); if (tasks == null) { tasks = new ArrayList(errors.length); } tasks.add(s.getSuggestion()); // Create Error-fix Suggestions handleError(manager, tasks, env.getDocument(), dataObject, summary, line, err.getLineNumber(), err.getColumn()); // TODO: additional checks here... } } } return tasks; } /** Check the given error message to see if we can help resolve * it, and register "solutions" into the given tasks list. * @param manager The suggestion manager to use * @param tasks List of Suggestions. May be empty. This method will * add to it any suggestions that it thinks will help fix the error. * For example, if the error is "No such class: List", it may add * two suggestions: "import java.awt.List" and "import java.util.List" * @param doc The document for the file containing the error. Used by the * SuggestionPerformers to modify the document when the user wants * to apply a fix suggestion. * TODO: get rid of this parameter (such that it's computed/located/ * opened automatically by the SuggestionPerformers when you perform * the fix. * @param dobj The data object for the file containing the error * @param summary The compiler error message as provided by javac * @param lineNumber The line number of the error message * @param column The column provided for the error, if any */ public void handleError(SuggestionManager manager, List tasks, final Document doc, final DataObject dobj, String summary, Line line, int lineNumber, int column) { if (/* manager.isEnabled(IMPORTTYPE) && */ // Yup, the below is a big i18n fiasco. However, // I don't have a choice - I don't have access to // the error type in symbolic form, so I have to resort // to messages. I suppose I could use a message catalog // to solve the case where the compiler error and the // IDE are running in the same locale? // Luckily, this can be fixed with JSR-199 when it's // provided summary.startsWith("cannot resolve symbol")) { // Btw, this is defined as "compiler.err.cant.resolve" // in "compiler.properties" in javac.jar's // org/netbeans/lib/javac/v8/resources package... // I don't see other locales there, so perhaps I don't // have a problem!!! int lix2 = summary.indexOf("location: package"); // NOI18N if (lix2 != -1) { // This is a missing class in an import statement. // That pretty much means you haven't mounted // a directory you should (somehow the code completion // knows about it). Can't really help with that. return; } int ix = summary.indexOf("symbol : class "); if (ix != -1) { // Might have found a symbol that isn't included yet ix += "symbol : class ".length(); int eix = summary.indexOf(' ', ix); if (eix != -1) { String symbol = summary.substring(ix,eix); // TODO: create suggestion for creating a new class // named "symbol" //JCFinder finder = JavaCompletion.getFinder(); // XXX Make sure JCStorage does some kind of caching! //JCFinder finder = JCStorage.getStorage(). // caseSensitive, naturalSort, showDeprecated // getFinder(true, true, true); JCFinder finder = getSensitiveFinder(); List list = finder.findClasses(null, symbol, true); if ((list != null) && (list.size() > 0)) { // Score! Let's propose suggestions for importing these // classes Iterator itr = list.iterator(); while (itr.hasNext()) { final JCClass classname = (JCClass)itr.next(); SuggestionPerformer action = new ImportPerformer(lineNumber, dobj, doc, classname); String fname = dobj.getPrimaryFile().getNameExt(); String sum = NbBundle.getMessage(ErrorSuggester.class, "ImportClassSg", classname, fname); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } } // Also check to see if we have spelling errors // XXX Make sure JCStorage does some kind of caching! //finder = JCStorage.getStorage(). // caseSensitive, naturalSort, showDeprecated // getFinder(false, true, true); finder = getInsensitiveFinder(); //list = findClasses(finder, null, symbol, true); list = finder.findClasses(null, symbol, true); if ((list != null) && (list.size() > 0)) { // Score! Let's propose suggestions for importing these // classes Iterator itr = list.iterator(); while (itr.hasNext()) { final JCClass clz = (JCClass)itr.next(); final String newClass = clz.getName(); if (!newClass.equals(symbol)) { // Yay - it's a casing-error final String oldClass = symbol; String beforeDesc = NbBundle.getMessage(ErrorSuggester.class, "ReplaceClassConfirmation"); // NOI18N String afterDesc = NbBundle.getMessage(ErrorSuggester.class, "ReplaceClassAfter"); // NOI18N SuggestionPerformer action = new ReplaceSymbolPerformer( lineNumber, column, line, dobj, doc, oldClass, newClass, beforeDesc, afterDesc, clz, false); String sum = NbBundle.getMessage(ErrorSuggester.class, "ReplaceClassSg",// NOI18N oldClass, newClass); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } } } } else { //System.out.println("Didn't find end index of the symbol!"); } return; } // See if it's a missing variable - if so, you may have forgotten // to make it a method (add "()" at the end, e.g. // System.out.println(mystring.length); -> mystring.length()) final String symVar = "symbol : variable "; // NOI18N ix = summary.indexOf(symVar); final String locClass = "location: class "; // NOI18N final String locInterface = "location: interface "; // NOI18N int lix = summary.indexOf(locClass); if (lix != -1) { lix += locClass.length(); } else { lix = summary.indexOf(locInterface); if (lix != -1) { lix += locInterface.length(); } } if ((ix != -1) && (lix != -1)) { // Might have found a symbol that isn't included yet ix += symVar.length(); int eix = summary.indexOf(' ', ix); if (eix != -1) { String symbol = summary.substring(ix,eix); String location = summary.substring(lix); // TODO - if I had an AST Tree (will JSR-199 give me one?) // I could find out the type expected of the variable, // and add a suggestion offering to add a field to the // class of that type (should be easily customizable // by the user since s/he may want a more specific type, // e.g. ArrayList instead of List) //JCFinder finder = JavaCompletion.getFinder(); // XXX Make sure JCStorage does some kind of caching! //JCFinder finder = JCStorage.getStorage(). // caseSensitive, naturalSort, showDeprecated // getFinder(true, true, true); JCFinder finder = getSensitiveFinder(); if (Character.isUpperCase(symbol.charAt(0))) { // Probably a static context class reference, e.g. // Arrays.sort() -> "Arrays" is undefined variable List list = finder.findClasses(null, symbol, true); if ((list != null) && (list.size() > 0)) { // Score! Let's propose suggestions for importing these // classes Iterator itr = list.iterator(); while (itr.hasNext()) { final JCClass classname = (JCClass)itr.next(); // TODO Factor this stuff so that it's shared with the Import Class code above SuggestionPerformer action = new ImportPerformer(lineNumber, dobj, doc, classname); String fname = dobj.getPrimaryFile().getNameExt(); String sum = NbBundle.getMessage(ErrorSuggester.class, "ImportClassSg", classname, fname); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } } } else { JCClass clz = finder.getExactClass(location); if (clz == null) { // Most likely because the symbol is in the current // class - which is not compilable (we have an error // after all) so there is no JCClass for it. return; } boolean staticOnly = false; // ? Hack it by looking at ctx? boolean inspectOuterClasses = true; List list = finder.findMethods(clz, symbol, true, staticOnly, inspectOuterClasses); if ((list != null) && (list.size() > 0)) { // Score! Let's propose suggestions for converting // this symbol to a method Iterator itr = list.iterator(); while (itr.hasNext()) { // TODO - ensure that the method found has no // arguments!!! final Object mtd = itr.next(); final String var = symbol; final String varAfter = var + "()"; String beforeDesc = NbBundle.getMessage(ErrorSuggester.class, "ChangeMethodConfirmation"); // NOI18N String afterDesc = NbBundle.getMessage(ErrorSuggester.class, "ChangeMethodAfter"); // NOI18N SuggestionPerformer action = new ReplaceSymbolPerformer( lineNumber, column, line, dobj, doc, var, varAfter, beforeDesc, afterDesc, null, true); String sum = NbBundle.getMessage(ErrorSuggester.class, "MakeMethodSg", var, varAfter); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } } } } else { //System.out.println("Didn't find end index of the symbol!"); } } // See if it's a missing method - if so, you may have used the // wrong case / have used a typo. Look for likely candidates. final String symMet = "symbol : method "; // NOI18N ix = summary.indexOf(symMet); /* lix should still contain the right value after the previous check lix = summary.indexOf(locClass); if (lix != -1) { lix += locClass.length(); } else { lix = summary.indexOf(locInterface); if (lix != -1) { lix += locInterface.length(); } } */ if ((ix != -1) && (lix != -1)) { ix += symMet.length(); int eix = summary.indexOf(' ', ix); if (eix != -1) { String symbol = summary.substring(ix,eix); String location = summary.substring(lix); //JCFinder finder = JavaCompletion.getFinder(); // XXX Make sure JCStorage does some kind of caching! //JCFinder finder = JCStorage.getStorage(). // caseSensitive, naturalSort, showDeprecated // getFinder(false, true, true); JCFinder finder = getInsensitiveFinder(); JCClass clz = finder.getExactClass(location); if (clz == null) { // Most likely because the symbol is in the current // class - which is not compilable (we have an error // after all) so there is no JCClass for it. suggestCreateMethod(symbol, summary, eix, location, tasks, lineNumber, column, dobj, manager); return; } boolean staticOnly = false; // ? Hack it by looking at ctx? boolean inspectOuterClasses = true; // Special case: it's easy to confused about // "size" vs "length" so check for this special case if (symbol.equals("length")) { JCFinder sfinder = getSensitiveFinder(); List list = sfinder.findMethods(clz, "size", false, staticOnly, inspectOuterClasses); if ((list != null) && (list.size() > 0)) { final String method = symbol; final JCMethod mtd = (JCMethod)list.get(0); final String newMethod = mtd.getName(); createMethodReplaceSuggestion( manager, tasks, doc, dobj, line, lineNumber, column, method, newMethod); } } else if (symbol.equals("size")) { JCFinder sfinder = getSensitiveFinder(); List list = sfinder.findMethods(clz, "length", false, staticOnly, inspectOuterClasses); if ((list != null) && (list.size() > 0)) { final String method = symbol; final JCMethod mtd = (JCMethod)list.get(0); final String newMethod = mtd.getName(); createMethodReplaceSuggestion( manager, tasks, doc, dobj, line, lineNumber, column, method, newMethod); } } // NOTE -- local finder! //List list = findMethods(finder, clz, symbol, false, List list = finder.findMethods(clz, symbol, false, staticOnly, inspectOuterClasses); if ((list != null) && (list.size() > 0)) { // Score! Let's propose suggestions for replacing // this symbol with the "correct" method List used = new ArrayList(list.size()); Iterator itr = list.iterator(); while (itr.hasNext()) { final JCMethod mtd = (JCMethod)itr.next(); final String newMethod = mtd.getName(); // Skip identical if (newMethod.equals(symbol)) { continue; } boolean alreadyUsed = false; for (int k = 0; k < used.size(); k++) { // Some methods appear multiple times (because // it's overloaded - but we want only a single // replacement suggestion) if (used.get(k).equals(newMethod)) { alreadyUsed = true; break; } } if (alreadyUsed) { continue; } used.add(newMethod); final String method = symbol; createMethodReplaceSuggestion( manager, tasks, doc, dobj, line, lineNumber, column, method, newMethod); } } else { suggestCreateMethod(symbol, summary, eix, location, tasks, lineNumber, column, dobj, manager); } } } } else if (summary.startsWith("incompatible types") && // NOI18N (column > 0)) { // See if we need to add a cast // // I first though I could recognize = so that I // could change x = y; to x = (Bar)y; // but the mismatch can be elsewhere, e.g. // Integer.parseInt(object); which should be changed // to Integer.parseInt((String)object); // So we really have to rely on the column parameter // here. // Note that this code is a bit ugly because I get some // unexpected column positions; compare the output of javac // on Object x = null; Integer i = x; // and Iterator it; Float f = it.next(); // With future revisions of the parser compiler I should // ensure that this code still works. Luckily we're using // a netbeans-shipped version of the compiler, not an arbitrary // one picked up in the user's environment (some other jdk, // or jikes, etc.) // TODO We probably should see if casting is possible, // (e.g. if I the target cast is a subclass of what // was found) but that's probably expensive. final String foundStr = "found : "; // NOI18N int fix = summary.indexOf(foundStr); final String reqStr = "required: "; // NOI18N int rix = summary.indexOf(reqStr); if ((fix != -1) && (rix != -1)) { fix += foundStr.length(); rix += reqStr.length(); int efix = summary.indexOf('\n', fix); if (efix != -1) { // Offer to insert String found = summary.substring(fix, efix); String req = summary.substring(rix); // Make sure there is only a single = on the line // (and a ;, so we don't get confused about multi // line statements.) // TODO Use org.openide.src to check if the current class // can be cast to the new class. column--; // The position should be zero based! String text = line.getText(); if (column < text.length() && text.charAt(column) == '(') { // Compute position backwards. boolean fd = false; // found valid exit point int i = column; for (; i >= 0; i--) { if (Character.isSpace(text.charAt(i))) { fd = true; break; } else if (text.charAt(i) == '=') { fd = true; break; } else if (text.charAt(i) == ')') { break; } } if (fd) { // Make sure if (i+1 < (column-1)) { column = i+1; } else { // TODO Looks like this was an existing cast. // (e.g. // Object x; // ArrayList list = (List)x; // Here we get an incompatible types error, // but we can't -insert- a cast, we have to // change the existing one. // // Perhaps do a symbol replacement here? We // already have a performer for that. int end = text.indexOf(')', column); if (end != -1) { // Don't call this "method"something, // it's a generic replacer createMethodReplaceSuggestion( manager, tasks, doc, dobj, line, lineNumber, column, text.substring(column+1, end), getClassName(req)); } return; } } else { // Rename here as well? return; // TODO handle with rename instead of bail! } } createCastSuggestion(manager, tasks, doc, dobj, line, column, req); } } } } // Given a fully qualified package name to a class, return just // the class name. Uses case to distinguish packages from inner // classes. private static String getClassName(String full) { int n = full.length()-1; // -1: last char can't be "." // Find first dot whose next character is uppercase for (int i = 0; i < n; i++) { if ((full.charAt(i) == '.') && (Character.isUpperCase(full.charAt(i+1)))) { return full.substring(i+1); } } return full; } /** Suggest to the user to create a method with the given arguments * in the given class */ private void suggestCreateMethod(String symbol, String summary, int eix, String location, List tasks, int lineNumber, int column, DataObject dobj, SuggestionManager manager) { // See if we can find the target location if (location.startsWith("java.") || location.startsWith("javax.")) { // If you're referring to a nonexistent method in java.* // or javax.* you probably don't want to add a method there... return; } // PENDING Do findAll? FileObject f = null; int div = location.lastIndexOf('.'); if (div != -1) { // Have a package String pkg = location.substring(0, div); String file = location.substring(div+1); // PENDING Do findAll? f = Repository.getDefault().find(pkg, file, "java"); } else { // PENDING Do findAll? f = Repository.getDefault().find(".", location, "java"); } if (f == null) { return; } DataObject obj = null; try { obj = DataObject.find(f); } catch (Exception e) { return; } // Look for method arguments, starting at position eix in summary int ix = summary.indexOf('(', eix); String args = ""; if (ix != -1) { eix = summary.indexOf(')', ix); args = summary.substring(ix+1, eix); } if (args.length() == 0) { args = NbBundle.getMessage(ErrorSuggester.class, "NoArgs");//NOI18N } SourceCookie sc = null; sc = (SourceCookie)obj.getCookie(SourceCookie.Editor.class); if (sc == null) { return; } boolean makePublic = (obj.getFolder() != dobj.getFolder()); // same dir? SuggestionPerformer action = new CreateMethodPerformer(obj, symbol, location, args, makePublic); String sum = NbBundle.getMessage(ErrorSuggester.class, "CreateMethod", // NOI18N symbol, location, args); SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(TLUtils.getLineByNumber(dobj, lineNumber)); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } private void createCastSuggestion( SuggestionManager manager, List tasks, final Document doc, final DataObject dobj, Line line, int column, String reqType) { String beforeDesc = NbBundle.getMessage(ErrorSuggester.class, "CastConfirmation", reqType); // NOI18N String reqClass = getClassName(reqType); SuggestionPerformer action = new CastPerformer(column, line, dobj, doc, reqType, reqClass, beforeDesc); String sum = NbBundle.getMessage(ErrorSuggester.class, "AddCast", reqClass); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } private void createMethodReplaceSuggestion( SuggestionManager manager, List tasks, final Document doc, final DataObject dobj, Line line, int lineNumber, int column, String method, String newMethod) { String beforeDesc = NbBundle.getMessage(ErrorSuggester.class, "ReplaceMethodConfirmation"); // NOI18N String afterDesc = NbBundle.getMessage(ErrorSuggester.class, "ReplaceMethodAfter"); // NOI18N SuggestionPerformer action = new ReplaceSymbolPerformer(lineNumber, column, line, dobj, doc, method, newMethod, beforeDesc, afterDesc, null, false); String sum = NbBundle.getMessage(ErrorSuggester.class, "ReplaceMethodSg", method, newMethod); // NOI18N SuggestionAgent s = manager.createSuggestion(TYPE, sum, action, this); s.setLine(line); Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/javaparser/import-sg.gif"); // NOI18N s.setIcon(taskIcon); s.setPriority(SuggestionPriority.HIGH); tasks.add(s.getSuggestion()); } JCFinder getInsensitiveFinder() { if (finderNoCase == null) { finderNoCase = JCStorage.getStorage(). // XXX What do I do for naturalSort? Sorting is not // important so do the most performante one! // caseSensitive, naturalSort, showDeprecated getFinder(false, true, true); } return finderNoCase; } static JCFinder getSensitiveFinder() { // XXX Perhaps I can just do return JavaCompletion.getFinder(); /* However - does that show deprecated methods? Is that even important? (Probably yes! We're trying to fix a compile error and the user may have referred to that deprecated method Ah yes, it seems to show deprecated! if (finderCase == null) { finderCase = JCStorage.getStorage(). // caseSensitive, naturalSort, showDeprecated getFinder(true, true, true); } return finderCase; */ } JCFinder finderNoCase = null; JCFinder finderCase = null; private ParserMessage[] getMessages(SuggestionContext env) { // XXX todo: store messages for all data objects here if (env == this.env) { return messages; } else { return null; } } private ParserMessage[] messages = null; public void objectParsed(Parsing.Event evt) { // fix for #37768 & #40638 if (env == null || (env.getFileObject().isValid() == false)) return; DataObject dataObject = null; try { dataObject = DataObject.find(env.getFileObject()); } catch (IOException ex) { ErrorManager.getDefault().notify(ex); } if (evt.getJavaDataObject() == dataObject) { messages = evt.getMessages(); errorsChanged(env); } else { //System.out.println("Received parsing info for " + evt.getJavaDataObject() + " ... discarding."); // I could stash away the errors here... but that ain't // good. // This has two disadvantages: // (1) I don't know when parsing begins - so I'll have to // add myself as a listener immediately // (2) I don't know when documents are closed - so I don't // know when to flush out errors from the cache. // Solution: Could register interest in layer such that // Parsing knows whether or not it should collect info. } } /** The list of tasks we're currently showing in the tasklist */ private List showingTasks = null; }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.