git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7817 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
cdd882ae23
commit
7eccfdec36
@ -0,0 +1,197 @@ |
||||
package com.jme3.gde.codecheck.hints; |
||||
|
||||
import com.sun.source.tree.MethodTree; |
||||
import com.sun.source.tree.StatementTree; |
||||
import com.sun.source.tree.Tree; |
||||
import com.sun.source.tree.Tree.Kind; |
||||
import com.sun.source.util.SourcePositions; |
||||
import com.sun.source.util.TreePath; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.EnumSet; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import javax.lang.model.element.Element; |
||||
import javax.swing.text.Document; |
||||
import javax.swing.text.JTextComponent; |
||||
import org.netbeans.api.editor.EditorRegistry; |
||||
import org.netbeans.api.java.source.CompilationInfo; |
||||
import org.netbeans.modules.java.hints.spi.AbstractHint; |
||||
import org.netbeans.spi.editor.hints.ChangeInfo; |
||||
import org.netbeans.spi.editor.hints.EnhancedFix; |
||||
import org.netbeans.spi.editor.hints.ErrorDescription; |
||||
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory; |
||||
import org.netbeans.spi.editor.hints.Fix; |
||||
import org.openide.awt.StatusDisplayer; |
||||
|
||||
public class TempVarsHint extends AbstractHint { |
||||
|
||||
//This hint does not enable the IDE to fix the problem:
|
||||
private static final List<Fix> NO_FIXES = Collections.<Fix>emptyList(); |
||||
//This hint applies to method invocations:
|
||||
private static final Set<Tree.Kind> TREE_KINDS = |
||||
EnumSet.<Tree.Kind>of(Tree.Kind.METHOD); |
||||
private List<varsPosition> vars = new ArrayList<varsPosition>(); |
||||
|
||||
public TempVarsHint() { |
||||
super(true, true, AbstractHint.HintSeverity.WARNING); |
||||
} |
||||
|
||||
//Specify the kind of code that the hint applies to, in this case,
|
||||
//the hint applies to method invocations:
|
||||
@Override |
||||
public Set<Kind> getTreeKinds() { |
||||
return TREE_KINDS; |
||||
} |
||||
|
||||
@Override |
||||
public List<ErrorDescription> run(CompilationInfo info, TreePath treePath) { |
||||
|
||||
MethodTree mt = (MethodTree) treePath.getLeaf(); |
||||
vars.clear(); |
||||
if (mt.getBody() != null) { |
||||
for (StatementTree t : mt.getBody().getStatements()) { |
||||
|
||||
|
||||
if (t.getKind().equals(Tree.Kind.VARIABLE)) { |
||||
Element el = info.getTrees().getElement(info.getTrees().getPath(info.getCompilationUnit(), t)); |
||||
String name = t.toString(); |
||||
|
||||
//This is where it all happens: if the method invocation is 'showMessageDialog',
|
||||
//then the hint infrastructure kicks into action:
|
||||
if (name.indexOf("TempVars.get()") >= 0) { |
||||
|
||||
SourcePositions sp = info.getTrees().getSourcePositions(); |
||||
int start = (int) sp.getStartPosition(info.getCompilationUnit(), t); |
||||
int end = (int) sp.getEndPosition(info.getCompilationUnit(), t); |
||||
vars.add(new varsPosition(el.getSimpleName().toString(), start, end)); |
||||
// System.err.println("TempVars.get() at " + start + " " + end+" for variable "+el.getSimpleName().toString());
|
||||
} |
||||
|
||||
} |
||||
if (t.getKind().equals(Tree.Kind.EXPRESSION_STATEMENT) && !vars.isEmpty()) { |
||||
Element el = info.getTrees().getElement(treePath); |
||||
String name = t.toString(); |
||||
|
||||
|
||||
if (name.indexOf(".release()") >= 0) { |
||||
|
||||
for (Iterator<varsPosition> it = vars.iterator(); it.hasNext();) { |
||||
varsPosition curVar = it.next(); |
||||
//This is where it all happens: if the method invocation is 'showMessageDialog',
|
||||
//then the hint infrastructure kicks into action:
|
||||
if (name.indexOf(curVar.varName + ".release()") >= 0) { |
||||
//prepare selection for removing
|
||||
it.remove(); |
||||
|
||||
// SourcePositions sp = info.getTrees().getSourcePositions();
|
||||
// int start = (int) sp.getStartPosition(info.getCompilationUnit(), t);
|
||||
// int end = (int) sp.getEndPosition(info.getCompilationUnit(), t);
|
||||
// System.err.println(curVar.varName + ".release() at " + start + " " + end);
|
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
} |
||||
if (!vars.isEmpty()) { |
||||
List<ErrorDescription> list = new ArrayList<ErrorDescription>(); |
||||
|
||||
JTextComponent editor = EditorRegistry.lastFocusedComponent(); |
||||
Document doc = editor.getDocument(); |
||||
List<Fix> fixes = new ArrayList<Fix>(); |
||||
SourcePositions sp = info.getTrees().getSourcePositions(); |
||||
int methodEnd = (int) (sp.getEndPosition(info.getCompilationUnit(), mt) - 1); |
||||
|
||||
for (varsPosition curVar : vars) { |
||||
String bodyText = " "+curVar.varName + ".release();\n "; |
||||
fixes.clear(); |
||||
fixes.add(new MessagesFix(doc, methodEnd, bodyText)); |
||||
|
||||
list.add(ErrorDescriptionFactory.createErrorDescription( |
||||
getSeverity().toEditorSeverity(), |
||||
getDisplayName(), |
||||
fixes, |
||||
info.getFileObject(), |
||||
curVar.start, curVar.end)); |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
return null; |
||||
|
||||
} |
||||
|
||||
//This is called if/when the hint processing is cancelled:
|
||||
@Override |
||||
public void cancel() { |
||||
} |
||||
|
||||
//Message that the user sees in the left sidebar:
|
||||
@Override |
||||
public String getDisplayName() { |
||||
return "TempVars might not be released"; |
||||
} |
||||
|
||||
//Name of the hint in the Options window:
|
||||
@Override |
||||
public String getId() { |
||||
return "TempVars release check"; |
||||
} |
||||
|
||||
//Description of the hint in the Options window:
|
||||
@Override |
||||
public String getDescription() { |
||||
return "Checks for calls TempVars.get() and search for correspondinng release() call"; |
||||
} |
||||
|
||||
class MessagesFix implements EnhancedFix { |
||||
|
||||
Document doc = null; |
||||
int start = 0; |
||||
String bodyText = null; |
||||
|
||||
public MessagesFix(Document doc, int start, String bodyText) { |
||||
this.doc = doc; |
||||
this.start = start; |
||||
this.bodyText = bodyText; |
||||
} |
||||
|
||||
@Override |
||||
public CharSequence getSortText() { |
||||
return "charsequence"; |
||||
} |
||||
|
||||
@Override |
||||
public String getText() { |
||||
return "Add a release() call at the end of the method"; |
||||
} |
||||
|
||||
@Override |
||||
public ChangeInfo implement() throws Exception { |
||||
//Adding the release call
|
||||
doc.insertString(start, bodyText, null); |
||||
//Display message to user in status bar:
|
||||
StatusDisplayer.getDefault().setStatusText("Added: " + bodyText); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
class varsPosition { |
||||
|
||||
String varName; |
||||
int start; |
||||
int end; |
||||
|
||||
public varsPosition(String varName, int start, int end) { |
||||
this.varName = varName; |
||||
this.end = end; |
||||
this.start = start; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue