From 7eccfdec362da9ab909423b996e4dae191c48e72 Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Mon, 4 Jul 2011 20:49:44 +0000 Subject: [PATCH] SDK - Added code check for TempVars release git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7817 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../gde/codecheck/hints/TempVarsHint.java | 197 ++++++++++++++++++ .../src/com/jme3/gde/codecheck/layer.xml | 1 + 2 files changed, 198 insertions(+) create mode 100644 sdk/jme3-code-check/src/com/jme3/gde/codecheck/hints/TempVarsHint.java diff --git a/sdk/jme3-code-check/src/com/jme3/gde/codecheck/hints/TempVarsHint.java b/sdk/jme3-code-check/src/com/jme3/gde/codecheck/hints/TempVarsHint.java new file mode 100644 index 000000000..a91868bb7 --- /dev/null +++ b/sdk/jme3-code-check/src/com/jme3/gde/codecheck/hints/TempVarsHint.java @@ -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 NO_FIXES = Collections.emptyList(); + //This hint applies to method invocations: + private static final Set TREE_KINDS = + EnumSet.of(Tree.Kind.METHOD); + private List vars = new ArrayList(); + + 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 getTreeKinds() { + return TREE_KINDS; + } + + @Override + public List 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 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 list = new ArrayList(); + + JTextComponent editor = EditorRegistry.lastFocusedComponent(); + Document doc = editor.getDocument(); + List fixes = new ArrayList(); + 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; + } + } +} diff --git a/sdk/jme3-code-check/src/com/jme3/gde/codecheck/layer.xml b/sdk/jme3-code-check/src/com/jme3/gde/codecheck/layer.xml index 25335f453..a297161f3 100644 --- a/sdk/jme3-code-check/src/com/jme3/gde/codecheck/layer.xml +++ b/sdk/jme3-code-check/src/com/jme3/gde/codecheck/layer.xml @@ -8,6 +8,7 @@ +