diff --git a/pdex/experimental/.classpath b/pdex/experimental/.classpath deleted file mode 100644 index 5bb5a9eb3..000000000 --- a/pdex/experimental/.classpath +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pdex/experimental/.externalToolBuilders/Auto_Builder.launch b/pdex/experimental/.externalToolBuilders/Auto_Builder.launch deleted file mode 100644 index dc7825b02..000000000 --- a/pdex/experimental/.externalToolBuilders/Auto_Builder.launch +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/pdex/experimental/.gitignore b/pdex/experimental/.gitignore deleted file mode 100644 index ba077a403..000000000 --- a/pdex/experimental/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bin diff --git a/pdex/experimental/.project b/pdex/experimental/.project deleted file mode 100644 index 85716855e..000000000 --- a/pdex/experimental/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - processing-experimental - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.ui.externaltools.ExternalToolBuilder - auto,full,incremental, - - - LaunchConfigHandle - <project>/.externalToolBuilders/Auto_Builder.launch - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/pdex/experimental/.settings/org.eclipse.jdt.core.prefs b/pdex/experimental/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 8000cd6ca..000000000 --- a/pdex/experimental/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/pdex/experimental/Todo, GSoC 2013.txt b/pdex/experimental/Todo, GSoC 2013.txt deleted file mode 100644 index 754eb4b3a..000000000 --- a/pdex/experimental/Todo, GSoC 2013.txt +++ /dev/null @@ -1,65 +0,0 @@ -TODO List for Experimental Mode Plus- GSOC 2013 - -This would also be a break down of my thought process and ideas as I tackle various tasks. Also lines are fairly long. Make sure you turn on word wrap. ;) - -Manindra Moharana (me@mkmoharana.com) - -* : Todo, x : Done, ? : Undecided Todo, ! : Critical, + : Minor Todo - -Code Completion -============== -The big stuff: -x! Code competition for local code is working with recursive look up. -x! Code completion with library code, non-nested seems to be broken, fix it. Fixed. -x Completion for external classes - ArrayList, HashMap, etc. -*! Recursive lookup for compiled(library) code! -*! Library CC for nested would be tricky. Need to jump from local->compiled code while searching recursively. Recursive find's current implementation is based on ASTNode return type. Afaik, no way to instantiate orphaned -ASTNode objects(or did I miss it?). ASTNode objects have to be created only from the main ast instance. But I need to find a way to switch to compiled instances from local class instance. -*! May be I should just implement recursive find for compiled code first, see how it goes and hopefully it would give me some ideas about how to integrating the two. -x! Should I implement wrapper for ASTNode? - possibly needed for code completion with compiled and non-compiled code. Done. -* Trie implementation would be lower priority, "premature optimisation is pure evil". Get all features of CC working good enough and then plan this. -*+ Differentiating between multiple statements on the same line. How to? - -Finer details -* Obj a1; a1.-> completion doesn't work before it is instantiated. Look into that. -* printStuff(int,float,String) - completion endings have to be appropriate. Right now it's just printStuff(,,). Cursor positioning also needs to be taken care of. Argument list as tooltip if possible? -* Sorted list of completion candidates - fields, then methods. It's unsorted presently. -*! p5 enhanced stuff in java, how does it fit in with everything else, and edge cases. Possibly add support for them. -* Reflection API - getMethods vs getDeclaredMethods. -* Need to add offset correction to ASTGenerator and its lookup methods. Or leave it for later? - -Offset Mapping -============== -First major hurdle is offset mapping -*! pde<->java code offset : precise conversion needed -x for the above, I've decide to first implement a sketch outline like feature, which would highlight an AST element precisely in the pde code. This would ensure I've got the mapping working properly. And may lead to a future feature. -* This is precise upto a certain line. Once on a line, pde stuff have to be taken into consideration. -x Edge case - multiple statements in a single line -x PDE specific enhancements will also have to be tackled like int(), # literals. The length of the node returned needs to be modified to make up for extra chars added like PApplet.parseFloat, etc. Also the 2nd or futher pde enhancements in the same line means even the beginning offset would need adjustment. Meh. -* The above is almost working. There are some offset issues when multiple pde statements are in the same line, but I guess it's good enough for now to proceed ahead. Will keep a close watch for potential bugs. - -Refactoring -=========== -Refactoring would work only when code is compiler error free. I plan to do a find replace type op on the compile ready code. -1. First identify the declaration of the variable in the AST. We'll then make a list of all its occurrences. -2. DFS through the AST, for each (SimpleName)instance of the word in code, find if the matched word is the same one whose declaration we found. -x Edge Case: For renaming a TypeDeclaration, the declaration of SimpleName instance of the TD and it's constructor(s) aren't added to the list generated by DFS. So for renaming TD, will have to manually add the TD SimpleName and it's constructors' SimpleNames to the a list of declaration nodes that can be positively matched against. -x Renaming any constructor is equivalent to renaming the TD -3. Find corresponding PDE offsets of the SimpleNames, rename in each line. -x Edge Case: Need to take displaced offsets on a line, due to pde enhancements, into consideration. -4. All the changes in code would be made in a separate copy of the code(?). After all the renaming is done, allow it only if the new code compiles. Basically an undo should be possible in case of conflicts. -* Undo misbehaves here, handle carefully. -* Handle saving. If sketch closed after renaming w/o saving find bugs. -* Refactoring ui -* Add support for word select on right click and rename, mouse co-ordinates need to obtained carefully - -Quick Navigation -================ -x Ctrl + Click on an element to scroll to its definition in code -x Local Vars -x Local Methods -x Local Classes -x Recursive lookup, a.b().c() -x Now highlihgting the declaration name, rather than the whole declaration. -*+ A silly bug where the name of the first field declaration isn't highlighted correctly. Seems to be happening if there's a javadoc or multiline comment near about the top. - diff --git a/pdex/experimental/build.xml b/pdex/experimental/build.xml deleted file mode 100644 index 309946ae0..000000000 --- a/pdex/experimental/build.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pdex/experimental/mode/.gitignore b/pdex/experimental/mode/.gitignore deleted file mode 100644 index 9acf0e7e9..000000000 --- a/pdex/experimental/mode/.gitignore +++ /dev/null @@ -1 +0,0 @@ -experimental.jar diff --git a/pdex/experimental/mode/readme.txt b/pdex/experimental/mode/readme.txt deleted file mode 100644 index 2152b63de..000000000 --- a/pdex/experimental/mode/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -Packages from Eclipse 4.2.1: -http://download.eclipse.org/eclipse/downloads/ - -The jdi.jar and jdimodel.jar files are unpacked -from the org.eclipse.jdt.debug JAR file. diff --git a/pdex/experimental/src/processing/mode/experimental/ASTGenerator.java b/pdex/experimental/src/processing/mode/experimental/ASTGenerator.java deleted file mode 100644 index b4ebb3413..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ASTGenerator.java +++ /dev/null @@ -1,2329 +0,0 @@ -package processing.mode.experimental; - -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.GridLayout; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Stack; -import java.util.TreeMap; - -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JEditorPane; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.JTree; -import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; -import javax.swing.UIManager; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.table.DefaultTableModel; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; - -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTParser; -import org.eclipse.jdt.core.dom.Block; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.Expression; -import org.eclipse.jdt.core.dom.ExpressionStatement; -import org.eclipse.jdt.core.dom.FieldAccess; -import org.eclipse.jdt.core.dom.FieldDeclaration; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.Name; -import org.eclipse.jdt.core.dom.NodeFinder; -import org.eclipse.jdt.core.dom.QualifiedName; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.SimpleType; -import org.eclipse.jdt.core.dom.SingleVariableDeclaration; -import org.eclipse.jdt.core.dom.StringLiteral; -import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; -import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclarationExpression; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; -import org.eclipse.jdt.core.dom.VariableDeclarationStatement; -import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; - -import processing.app.Base; -import processing.app.SketchCode; - -import com.google.classpath.ClassPath; -import com.google.classpath.ClassPathFactory; -import com.google.classpath.RegExpResourceFilter; -import com.ibm.icu.util.StringTokenizer; -import com.sun.org.apache.bcel.internal.generic.GETSTATIC; -import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Occurs; - -public class ASTGenerator { - - protected ErrorCheckerService errorCheckerService; - - protected DebugEditor editor; - - public DefaultMutableTreeNode codeTree = new DefaultMutableTreeNode(); - - private DefaultMutableTreeNode currentParent = null; - - /** - * AST Window - */ - private JFrame frame2; - - private JFrame frameAutoComp; - - /** - * Swing component wrapper for AST, used for internal testing - */ - private JTree jtree; - - /** - * JTree used for testing refactoring operations - */ - private JTree renameTree; - - private CompilationUnit compilationUnit; - - private JTable tableAuto; - - private JEditorPane javadocPane; - - private JScrollPane scrollPane; - - private JFrame renameWindow; - - private JButton renameButton; - - private JButton listOccurrence; - - private JTextField renameTextField; - - public ASTGenerator(ErrorCheckerService ecs) { - this.errorCheckerService = ecs; - this.editor = ecs.getEditor(); - frame2 = new JFrame(); - - jtree = new JTree(); - frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame2.setBounds(new Rectangle(680, 100, 460, 620)); - JScrollPane sp = new JScrollPane(); - sp.setViewportView(jtree); - frame2.add(sp); - - renameButton = new JButton("Rename"); - listOccurrence = new JButton("Find All"); - renameWindow = new JFrame(); - renameWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - renameWindow.setBounds(new Rectangle(680, 50, 150, 150)); - renameWindow.setLayout(new GridLayout(3, 1)); - renameWindow.add(renameButton); - renameWindow.add(listOccurrence); - renameTextField = new JTextField(); - renameTextField.setPreferredSize(new Dimension(150, 60)); - renameWindow.add(renameTextField); - renameWindow.setVisible(true); - - JFrame frame4 = new JFrame(); - frame4.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame4.setBounds(new Rectangle(1100, 50, 350, 500)); - - JScrollPane sp2 = new JScrollPane(); - renameTree = new JTree(); - sp2.setViewportView(renameTree); - frame4.add(sp2); - frame4.setVisible(true); - -// frameAutoComp = new JFrame(); -// frameAutoComp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); -// frameAutoComp.setBounds(new Rectangle(1280, 100, 460, 620)); -// tableAuto = new JTable(); -// JScrollPane sp2 = new JScrollPane(); -// sp2.setViewportView(tableAuto); -// frameAutoComp.add(sp2); - -// jdocWindow = new JFrame(); -// jdocWindow.setTitle("P5 InstaHelp"); -// //jdocWindow.setUndecorated(true); -// jdocWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); -// javadocPane = new JEditorPane(); -// javadocPane.setContentType("text/html"); -// javadocPane.setEditable(false); -// scrollPane = new JScrollPane(); -// scrollPane.setViewportView(javadocPane); -// jdocWindow.add(scrollPane); -// jdocMap = new TreeMap(); -//// loadJars(); - - //addCompletionPopupListner(); - addListeners(); - } - - private DefaultMutableTreeNode buildAST(String source, CompilationUnit cu) { - if (cu == null) { - ASTParser parser = ASTParser.newParser(AST.JLS4); - parser.setSource(source.toCharArray()); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - - Map options = JavaCore.getOptions(); - - JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); - options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); - parser.setCompilerOptions(options); - compilationUnit = (CompilationUnit) parser.createAST(null); - } else { - compilationUnit = cu; - System.out.println("Other cu"); - } -// OutlineVisitor visitor = new OutlineVisitor(); -// compilationUnit.accept(visitor); - codeTree = new DefaultMutableTreeNode( - getNodeAsString((ASTNode) compilationUnit - .types().get(0))); - visitRecur((ASTNode) compilationUnit.types().get(0), codeTree); - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - if (codeTree != null) { - if (jtree.hasFocus() || frame2.hasFocus()) - return; - jtree.setModel(new DefaultTreeModel(codeTree)); - ((DefaultTreeModel) jtree.getModel()).reload(); - if (!frame2.isVisible()) { - frame2.setVisible(true); - } -// if (!frameAutoComp.isVisible()) { -// -// frameAutoComp.setVisible(true); -// -// } -// if (!jdocWindow.isVisible()) { -// long t = System.currentTimeMillis(); -// loadJars(); -// loadJavaDoc(); -// System.out.println("Time taken: " -// + (System.currentTimeMillis() - t)); -// jdocWindow.setBounds(new Rectangle(errorCheckerService.getEditor() -// .getX() + errorCheckerService.getEditor().getWidth(), -// errorCheckerService.getEditor() -// .getY(), 450, 600)); -// jdocWindow.setVisible(true); -// } - jtree.validate(); - } - } - }; - worker.execute(); -// System.err.println("++>" + System.getProperty("java.class.path")); -// System.out.println(System.getProperty("java.class.path")); -// System.out.println("-------------------------------"); - return codeTree; - } - - private ClassPathFactory factory; - - private ClassPath classPath; - - private JFrame jdocWindow; - - /** - * Loads up .jar files and classes defined in it for completion lookup - */ - protected void loadJars() { -// SwingWorker worker = new SwingWorker() { -// protected void done(){ -// } -// protected Object doInBackground() throws Exception { -// return null; -// } -// }; -// worker.execute(); - - Thread t = new Thread(new Runnable() { - - public void run() { - try { - factory = new ClassPathFactory(); - - StringBuffer tehPath = new StringBuffer(System - .getProperty("java.class.path")); - tehPath.append(File.pathSeparatorChar - + System.getProperty("java.home") + "/lib/rt.jar" - + File.pathSeparatorChar); - if (errorCheckerService.classpathJars != null) { - for (URL jarPath : errorCheckerService.classpathJars) { - //System.out.println(jarPath.getPath()); - tehPath.append(jarPath.getPath() + File.pathSeparatorChar); - } - } - -// String paths[] = tehPath.toString().split(File.separatorChar +""); -// StringTokenizer st = new StringTokenizer(tehPath.toString(), -// File.pathSeparatorChar + ""); -// while (st.hasMoreElements()) { -// String sstr = (String) st.nextElement(); -// System.out.println(sstr); -// } - - classPath = factory.createFromPath(tehPath.toString()); -// for (String packageName : classPath.listPackages("")) { -// System.out.println(packageName); -// } - RegExpResourceFilter regExpResourceFilter = new RegExpResourceFilter( - ".*", - "ArrayList.class"); - String[] resources = classPath.findResources("", regExpResourceFilter); - for (String className : resources) { - System.out.println("-> " + className); - } - System.out.println("jars loaded."); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - t.start(); - } - - private TreeMap jdocMap; - - private void loadJavaDoc() { - - // presently loading only p5 reference for PApplet - Thread t = new Thread(new Runnable() { - - @Override - public void run() { - JavadocHelper.loadJavaDoc(jdocMap, editor.mode().getReferenceFolder()); - } - }); - t.start(); - - } - - public DefaultMutableTreeNode buildAST(CompilationUnit cu) { - return buildAST(errorCheckerService.sourceCode, cu); - } - - public String[] checkForTypes2(ASTNode node) { - - List vdfs = null; - switch (node.getNodeType()) { - case ASTNode.TYPE_DECLARATION: - return new String[] { ((TypeDeclaration) node).getName().toString() }; - - case ASTNode.METHOD_DECLARATION: - String[] ret1 = new String[] { ((MethodDeclaration) node).getName() - .toString() }; - return ret1; - - case ASTNode.SINGLE_VARIABLE_DECLARATION: - return new String[] { ((SingleVariableDeclaration) node).getName() - .toString() }; - - case ASTNode.FIELD_DECLARATION: - vdfs = ((FieldDeclaration) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_STATEMENT: - vdfs = ((VariableDeclarationStatement) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_EXPRESSION: - vdfs = ((VariableDeclarationExpression) node).fragments(); - break; - default: - break; - } - - if (vdfs != null) { - String ret[] = new String[vdfs.size()]; - int i = 0; - for (VariableDeclarationFragment vdf : vdfs) { - ret[i++] = vdf.getName().toString(); - } - return ret; - } - - return null; - } - - public static CompletionCandidate[] checkForTypes(ASTNode node) { - - List vdfs = null; - switch (node.getNodeType()) { - case ASTNode.TYPE_DECLARATION: - return new CompletionCandidate[] { new CompletionCandidate( - getNodeAsString2(node), - ((TypeDeclaration) node) - .getName() - .toString()) }; - - case ASTNode.METHOD_DECLARATION: - MethodDeclaration md = (MethodDeclaration) node; - System.out.println(getNodeAsString(md)); - List params = (List) md - .getStructuralProperty(MethodDeclaration.PARAMETERS_PROPERTY); - CompletionCandidate[] cand = new CompletionCandidate[params.size() + 1]; - cand[0] = new CompletionCandidate(md); - for (int i = 0; i < params.size(); i++) { - cand[i + 1] = new CompletionCandidate(params.get(i).toString(), "", "", - CompletionCandidate.LOCAL_VAR); - } - return cand; - - case ASTNode.SINGLE_VARIABLE_DECLARATION: - return new CompletionCandidate[] { new CompletionCandidate( - getNodeAsString2(node), - "", - "", - CompletionCandidate.LOCAL_VAR) }; - - case ASTNode.FIELD_DECLARATION: - vdfs = ((FieldDeclaration) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_STATEMENT: - vdfs = ((VariableDeclarationStatement) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_EXPRESSION: - vdfs = ((VariableDeclarationExpression) node).fragments(); - break; - default: - break; - } - - if (vdfs != null) { - CompletionCandidate ret[] = new CompletionCandidate[vdfs.size()]; - int i = 0; - for (VariableDeclarationFragment vdf : vdfs) { - ret[i++] = new CompletionCandidate(getNodeAsString2(vdf), "", "", - CompletionCandidate.LOCAL_VAR); - } - return ret; - } - - return null; - } - - @SuppressWarnings("unchecked") - public ArrayList getNameIfType(ASTNode astnode) { - - ArrayList names = new ArrayList(); - List sprops = astnode - .structuralPropertiesForType(); - for (StructuralPropertyDescriptor sprop : sprops) { - ASTNode cnode = null; - if (!sprop.isChildListProperty()) { - if (astnode.getStructuralProperty(sprop) instanceof ASTNode) { - cnode = (ASTNode) astnode.getStructuralProperty(sprop); - //if(cnode) - } - } else { - // Childlist prop - List nodelist = (List) astnode - .getStructuralProperty(sprop); - for (ASTNode clnode : nodelist) { - - } - } - } - - return names; - } - - /** - * Find the parent of the expression in a().b, this would give me the return - * type of a(), so that we can find all children of a() begininng with b - * - * @param nearestNode - * @param expression - * @return - */ - public static ASTNode resolveExpression(ASTNode nearestNode, - ASTNode expression) { -// ASTNode anode = null; - System.out.println("Resolving " + getNodeAsString(expression)); - if (expression instanceof SimpleName) { - return findDeclaration2(((SimpleName) expression), nearestNode); - } else if (expression instanceof MethodInvocation) { - return findDeclaration2(((MethodInvocation) expression).getName(), - nearestNode); - } else if (expression instanceof FieldAccess) { - System.out.println("2. Field access " - + getNodeAsString(((FieldAccess) expression).getExpression())); - return resolveExpression(nearestNode, - ((FieldAccess) expression).getExpression()); - //return findDeclaration2(((FieldAccess) expression).getExpression(), nearestNode); - } else if (expression instanceof QualifiedName) { - System.out.println("1. Resolving " - + ((QualifiedName) expression).getQualifier() + " ||| " - + ((QualifiedName) expression).getName()); - return findDeclaration2(((QualifiedName) expression).getQualifier(), - nearestNode); - } - - return null; - } - - /** - * For a().abc.a123 this would return a123 - * - * @param expression - * @return - */ - public static ASTNode resolveChildExpression(ASTNode expression) { -// ASTNode anode = null; - if (expression instanceof SimpleName) { - return expression; - } else if (expression instanceof FieldAccess) { - return ((FieldAccess) expression).getName(); - } else if (expression instanceof QualifiedName) { - return ((QualifiedName) expression).getName(); - } - System.out.println(" resolveChildExpression returning NULL for " - + getNodeAsString(expression)); - return null; - } - - public static TypeDeclaration getDefiningNode(ASTNode node) { - ASTNode parent = node.getParent(); - while (!(parent instanceof TypeDeclaration)) { - parent = parent.getParent(); - if (parent instanceof CompilationUnit) - return null; - } - return (TypeDeclaration) parent; - } - - public void updatePredictions(final String word, final int line) { - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - - String word2 = word; - - //After typing 'arg.' all members of arg type are to be listed. This one is a flag for it - boolean noCompare = false; - if (word2.endsWith(".")) { - // return all matches - word2 = word2.substring(0, word.length() - 1); - noCompare = true; - } - - int lineNumber = line; - // Adjust line number for tabbed sketches - if (errorCheckerService != null) { - editor = errorCheckerService.getEditor(); - int codeIndex = editor.getSketch().getCodeIndex(editor - .getCurrentTab()); - if (codeIndex > 0) - for (int i = 0; i < codeIndex; i++) { - SketchCode sc = editor.getSketch().getCode(i); - int len = Base.countLines(sc.getProgram()) + 1; - lineNumber += len; - } - - } - - // Now parse the expression into an ASTNode object - ASTNode nearestNode = null; - ASTParser parser = ASTParser.newParser(AST.JLS4); - parser.setKind(ASTParser.K_EXPRESSION); - parser.setSource(word2.toCharArray()); - ASTNode testnode = parser.createAST(null); - - // Find closest ASTNode of the document to this word - System.err.print("Typed: " + word2 + "|"); - nearestNode = findClosestNode(lineNumber, (ASTNode) compilationUnit.types() - .get(0)); - if (nearestNode == null) - //Make sure nearestNode is not NULL if couldn't find a closeset node - nearestNode = (ASTNode) compilationUnit.types().get(0); - System.err.println(lineNumber + " Nearest ASTNode to PRED " - + getNodeAsString(nearestNode)); - - ArrayList candidates = new ArrayList(); - - // Determine the expression typed - - if (testnode instanceof SimpleName && !noCompare) { - System.err - .println("One word expression " + getNodeAsString(testnode)); - //==> Simple one word exprssion - so is just an identifier - - // Bottom up traversal of the AST to look for possible definitions at - // higher levels. - nearestNode = nearestNode.getParent(); - while (nearestNode != null) { - // If the current class has a super class, look inside it for - // definitions. - if (nearestNode instanceof TypeDeclaration) { - TypeDeclaration td = (TypeDeclaration) nearestNode; - if (td - .getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY) != null) { - SimpleType st = (SimpleType) td - .getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY); - System.out.println("Superclass " + st.getName()); - for (CompletionCandidate can : getMembersForType(st.getName() - .toString(), word2, noCompare, false)) { - candidates.add(can); - } - //findDeclaration(st.getName()) - - } - } - List sprops = nearestNode - .structuralPropertiesForType(); - for (StructuralPropertyDescriptor sprop : sprops) { - ASTNode cnode = null; - if (!sprop.isChildListProperty()) { - if (nearestNode.getStructuralProperty(sprop) instanceof ASTNode) { - cnode = (ASTNode) nearestNode.getStructuralProperty(sprop); - CompletionCandidate[] types = checkForTypes(cnode); - if (types != null) { - for (int i = 0; i < types.length; i++) { - if (types[i].getElementName().startsWith(word2)) - candidates.add(types[i]); - } - } - } - } else { - // Childlist prop - List nodelist = (List) nearestNode - .getStructuralProperty(sprop); - for (ASTNode clnode : nodelist) { - CompletionCandidate[] types = checkForTypes(clnode); - if (types != null) { - for (int i = 0; i < types.length; i++) { - if (types[i].getElementName().startsWith(word2)) - candidates.add(types[i]); - } - } - } - } - } - nearestNode = nearestNode.getParent(); - } - if(candidates.isEmpty()){ - // We're seeing a simple name that's not defined locally or in - // the parent class. So most probably a pre-defined type. - System.out.println("Empty can. " + word2); - RegExpResourceFilter regExpResourceFilter; - regExpResourceFilter = new RegExpResourceFilter(".*", word2 + "[a-zA-Z_0-9]*.class"); - String[] resources = classPath.findResources("", regExpResourceFilter); - for (String matchedClass : resources) { - matchedClass = matchedClass.substring(0, - matchedClass.length() - 6); - matchedClass = matchedClass.replace('/', '.'); - int d = matchedClass.lastIndexOf('.'); - matchedClass = matchedClass.substring(d + 1); - candidates.add(new CompletionCandidate(matchedClass)); - //System.out.println("-> " + className); - } - } - - } else { - - // ==> Complex expression of type blah.blah2().doIt,etc - // Have to resolve it by carefully traversing AST of testNode - System.err.println("Complex expression " + getNodeAsString(testnode)); - - ASTNode det = resolveExpression(nearestNode, testnode); - // Find the parent of the expression - // in a().b, this would give me the return type of a(), so that we can - // find all children of a() begininng with b - System.err.println("DET " + getNodeAsString(det)); - if (det != null) { - TypeDeclaration td = null; - SimpleType stp = null; - if (det instanceof MethodDeclaration) { - if (((MethodDeclaration) det).getReturnType2() instanceof SimpleType) { - stp = (SimpleType) (((MethodDeclaration) det).getReturnType2()); - td = (TypeDeclaration) findDeclaration(stp.getName()); - } - } else if (det instanceof FieldDeclaration) { - if (((FieldDeclaration) det).getType() instanceof SimpleType) { - stp = (SimpleType) (((FieldDeclaration) det).getType()); - td = (TypeDeclaration) findDeclaration(stp.getName()); - } - } else if (det instanceof VariableDeclarationStatement) { - stp = (SimpleType) (((VariableDeclarationStatement) det) - .getType()); - td = (TypeDeclaration) findDeclaration(stp.getName()); - } - System.out.println("ST is " + stp.getName()); - // Now td contains the type returned by a() - System.err.println(getNodeAsString(det) + " defined in " - + getNodeAsString(td)); - ASTNode child = resolveChildExpression(testnode); - if (td != null) { - - System.out.println("Completion candidate: " - + getNodeAsString(child)); - for (int i = 0; i < td.getFields().length; i++) { - List vdfs = td.getFields()[i] - .fragments(); - for (VariableDeclarationFragment vdf : vdfs) { - if (noCompare) { - candidates - .add(new CompletionCandidate(getNodeAsString2(vdf))); - } else if (vdf.getName().toString() - .startsWith(child.toString())) - candidates - .add(new CompletionCandidate(getNodeAsString2(vdf))); - } - - } - for (int i = 0; i < td.getMethods().length; i++) { - if (noCompare) { - candidates - .add(new CompletionCandidate(getNodeAsString2(td - .getMethods()[i]), td.getName().toString(), "", - CompletionCandidate.METHOD)); - } else if (td.getMethods()[i].getName().toString() - .startsWith(child.toString())) - candidates - .add(new CompletionCandidate(getNodeAsString2(td - .getMethods()[i]), td.getName().toString(), "", - CompletionCandidate.METHOD)); - } - } else { - if (stp != null) { - candidates = getMembersForType(stp.getName().toString(), - child.toString(), noCompare, - false); - } - } - - } else if (word.length() - word2.length() == 1) { - System.out.println(word + " w2 " + word2); -// int dC = 0; -// for (int i = 0; i < word.length(); i++) { -// if(word.charAt(i) == '.') -// dC++; -// } -// if(dC == 1 && word.charAt(word.length() - 1) == '.'){ - System.out.println("All members of " + word2); - candidates = getMembersForType(word2, "", true, true); -// } - } else { - System.out.println("Some members of " + word2); - int x = word2.indexOf('.'); - if (x != -1) { - candidates = getMembersForType(word2.substring(0, x), - word2.substring(x + 1), false, - true); - } - } - - } - - Collections.sort(candidates); - CompletionCandidate[][] candi = new CompletionCandidate[candidates - .size()][1]; - - for (int i = 0; i < candi.length; i++) { - candi[i][0] = candidates.get(i); - } - System.out.println("K = " + candidates.size()); - DefaultTableModel tm = new DefaultTableModel( - candi, - new String[] { "Suggestions" }); - tableAuto.setModel(tm); - tableAuto.validate(); - tableAuto.repaint(); - //String[] items = - CompletionCandidate[] candi2 = candidates - .toArray(new CompletionCandidate[candidates.size()]); - if (candidates.size() > 0) - errorCheckerService.getEditor().textArea().showSuggestion(candi2); - } - }; - - worker.execute(); - - } - - /** - * Loads classes from .jar files in sketch classpath - * - * @param typeName - * @param child - * @param noCompare - * @return - */ - public ArrayList getMembersForType(String typeName, - String child, - boolean noCompare, - boolean staticOnly) { - ArrayList candidates = new ArrayList(); - RegExpResourceFilter regExpResourceFilter; - regExpResourceFilter = new RegExpResourceFilter(".*", typeName + ".class"); - String[] resources = classPath.findResources("", regExpResourceFilter); - for (String className : resources) { - System.out.println("-> " + className); - } - if (resources.length > 0) { //TODO: Multiple matched classes? What about 'em? - String matchedClass = resources[0]; - matchedClass = matchedClass.substring(0, matchedClass.length() - 6); - matchedClass = matchedClass.replace('/', '.'); - System.out.println("In GMFT(), Matched class: " + matchedClass); - System.out.println("Looking for match " + child.toString()); - try { - Class probableClass = Class.forName(matchedClass, false, - errorCheckerService.classLoader); - - for (Method method : probableClass.getMethods()) { - if (!Modifier.isStatic(method.getModifiers()) && staticOnly) - continue; - StringBuffer label = new StringBuffer(method.getName() + "("); - for (int i = 0; i < method.getParameterTypes().length; i++) { - label.append(method.getParameterTypes()[i].getSimpleName()); - if (i < method.getParameterTypes().length - 1) - label.append(","); - } - - label.append(")"); - if (noCompare) - candidates.add(new CompletionCandidate(method)); - else if (label.toString().startsWith(child.toString())) - candidates.add(new CompletionCandidate(method)); - } - for (Field field : probableClass.getFields()) { - if (!Modifier.isStatic(field.getModifiers()) && staticOnly) - continue; - if (noCompare) - candidates.add(new CompletionCandidate(field)); - else if (field.getName().startsWith(child.toString())) - candidates.add(new CompletionCandidate(field)); - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); - System.out.println("Couldn't load " + matchedClass); - } - } - //updateJavaDoc(methodmatch) - - return candidates; - } - - public void updateJavaDoc(final CompletionCandidate candidate) { - String methodmatch = candidate.toString(); - if (methodmatch.indexOf('(') != -1) { - methodmatch = methodmatch.substring(0, methodmatch.indexOf('(')); - } - - //System.out.println("jdoc match " + methodmatch); - for (final String key : jdocMap.keySet()) { - if (key.startsWith(methodmatch) && key.length() > 3) { - System.out.println("Matched jdoc " + key); - - //visitRecur((ASTNode) compilationUnit.types().get(0), codeTree); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - - System.out.println("Class: " + candidate.getDefiningClass()); - if (candidate.getDefiningClass().equals("processing.core.PApplet")) { - javadocPane.setText(jdocMap.get(key)); - //jdocWindow.setVisible(true); - //editor.textArea().requestFocus() - } else - javadocPane.setText(""); - javadocPane.setCaretPosition(0); - } - }); - break; - } - } - //jdocWindow.setVisible(false); - - } - - @SuppressWarnings("unchecked") - private static ASTNode findClosestParentNode(int lineNumber, ASTNode node) { - Iterator it = node - .structuralPropertiesForType().iterator(); - //System.err.println("Props of " + node.getClass().getName()); - while (it.hasNext()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it - .next(); - - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (node.getStructuralProperty(prop) != null) { -// System.out -// .println(node.getStructuralProperty(prop) + " -> " + (prop)); - if (node.getStructuralProperty(prop) instanceof ASTNode) { - ASTNode cnode = (ASTNode) node.getStructuralProperty(prop); -// System.out.println("Looking at " + getNodeAsString(cnode)); - int cLineNum = ((CompilationUnit) cnode.getRoot()) - .getLineNumber(cnode.getStartPosition() + cnode.getLength()); - if (getLineNumber(cnode) <= lineNumber && lineNumber <= cLineNum) { - return findClosestParentNode(lineNumber, cnode); - } - } - } - } - - else if (prop.isChildListProperty()) { - List nodelist = (List) node - .getStructuralProperty(prop); - for (ASTNode cnode : nodelist) { - int cLineNum = ((CompilationUnit) cnode.getRoot()) - .getLineNumber(cnode.getStartPosition() + cnode.getLength()); -// System.out.println("Looking at " + getNodeAsString(cnode)); - if (getLineNumber(cnode) <= lineNumber && lineNumber <= cLineNum) { - return findClosestParentNode(lineNumber, cnode); - } - } - } - } - return node; - } - - @SuppressWarnings("unchecked") - private static ASTNode findClosestNode(int lineNumber, ASTNode node) { - ASTNode parent = findClosestParentNode(lineNumber, node); - if (parent == null) - return null; - if (getLineNumber(parent) == lineNumber) - return parent; - List nodes = null; - if (parent instanceof TypeDeclaration) { - nodes = (List) ((TypeDeclaration) parent) - .getStructuralProperty(TypeDeclaration.BODY_DECLARATIONS_PROPERTY); - } else if (parent instanceof Block) { - nodes = (List) ((Block) parent) - .getStructuralProperty(Block.STATEMENTS_PROPERTY); - } else { - System.err.println("THIS CONDITION SHOULD NOT OCCUR - findClosestNode " - + getNodeAsString(parent)); - return null; - } - - if (nodes.size() > 0) { - ASTNode retNode = nodes.get(0); - for (ASTNode cNode : nodes) { - if (getLineNumber(cNode) <= lineNumber) - retNode = cNode; - else - break; - } - - return retNode; - } - return null; - } - -// static DefaultMutableTreeNode findNodeBS(DefaultMutableTreeNode tree, -// int lineNumber, String name, -// int elementOffset) { -// if (tree.getUserObject() == null) -// return null; -// -// ASTNodeWrapper node = ((ASTNodeWrapper) tree.getUserObject()); -// -// if (node.getLineNumber() == lineNumber) { -// System.out.println("Located line " + lineNumber + " , " + tree); -// if (name == null) -// return tree; -// else -// return findOnLine(tree, lineNumber, name, elementOffset, node.getNode() -// .getStartPosition()); -// } -// -// int low = 0, high = tree.getChildCount() - 1, mid = (high + low) / 2; -// DefaultMutableTreeNode tnode = null; -// while (low <= high) { -// mid = (high + low) / 2; -// tnode = (DefaultMutableTreeNode) tree.getChildAt(mid); -// node = ((ASTNodeWrapper) tnode.getUserObject()); -// if (node.getLineNumber() == lineNumber) { -// System.out.println("Located line " + lineNumber + " , " + tnode); -// if (name == null) -// return tnode; -// else -// return findOnLine(tnode, lineNumber, name, elementOffset, node -// .getNode().getStartPosition()); -// } else if (lineNumber < node.getLineNumber()) { -// high = mid - 1; -// } else { -// if (high - mid <= 1) { -// if (lineNumber > ((ASTNodeWrapper) ((DefaultMutableTreeNode) tree -// .getChildAt(high)).getUserObject()).getLineNumber()) //high l no. -// low = mid + 1; -// else -// -// high = mid - 1; -// } -// low = mid + 1; -// } -// -// } -// -// if (!tnode.isLeaf()) -// return findNodeBS(tnode, lineNumber, name, elementOffset); -// else -// return tnode; -// -// //System.out.println("visiting: " + getNodeAsString(node.getNode()) + " on line "+node.getLineNumber()); -// if (node.getLineNumber() == lineNumber) { -// System.err.println("Located line: " + node.toString()); -// if (name == null) // name ==null, finds any node equal to line -// // number -// { -// System.out.println("Closest node at line: " + lineNumber); -// return tree; -// } else -// return findOnLine(tree, lineNumber, name, elementOffset, node.getNode() -// .getStartPosition()); -// -// } else if (!tree.isLeaf()) { -// for (int i = 0; i < tree.getChildCount(); i++) { -// .getChildAt(i), -// lineNumber, name, elementOffset); -// if (node2 != null) -// return node2; -// } -// } -// -// return null; -// } - - public DefaultMutableTreeNode getAST() { - return codeTree; - } - - public String getLabelForASTNode(int lineNumber, String name, int offset) { - retLabelString = ""; - getASTNodeAt(lineNumber, name, offset, false); - return retLabelString; - } - - public void scrollToDeclaration(int lineNumber, String name, int offset) { - getASTNodeAt(lineNumber, name, offset, true); - } - - String retLabelString; - - /** - * - * @param lineNumber - * @param name - * @param offset - line start nonwhitespace offset - * @param scrollOnly - * @return - */ - public ASTNodeWrapper getASTNodeAt(int lineNumber, String name, int offset, - boolean scrollOnly) { - - System.out.println("----getASTNodeAt----"); - if (errorCheckerService != null) { - editor = errorCheckerService.getEditor(); - int codeIndex = editor.getSketch().getCodeIndex(editor.getCurrentTab()); - if (codeIndex > 0) { - for (int i = 0; i < codeIndex; i++) { - SketchCode sc = editor.getSketch().getCode(i); - int len = Base.countLines(sc.getProgram()) + 1; - lineNumber += len; - } - } - - } - System.out.println("FLON: " + lineNumber); - ASTNode lineNode = findLineOfNode(compilationUnit, lineNumber, offset, name); - - System.out.println("+> " + lineNode); - ASTNode decl = null; - String nameOfNode = null; // The node name which is to be scrolled to - if (lineNode != null) { - - // Some delicate offset handling follows. - ASTNodeWrapper lineNodeWrap = new ASTNodeWrapper(lineNode); - int altOff = offset; - int ret[][] = lineNodeWrap.getOffsetMapping(errorCheckerService); - if(ret != null){ - altOff = 0; - int javaCodeMap[] = ret[0], pdeCodeMap[] = ret[1]; - - for (; altOff < javaCodeMap.length; altOff++) { - if (javaCodeMap[altOff] == pdeCodeMap[offset]) { - break; - } - } - } - System.out.println("FLON2: " + lineNumber + " LN spos " - + lineNode.getStartPosition() + " off " + offset + " alt off" + altOff); - /* - * Now I need to see if multiple statements exist with this same line number - * If that's the case, I need to ensure the offset is right. - */ - ASTNode parLineNode = lineNode.getParent(); - - Iterator it = parLineNode - .structuralPropertiesForType().iterator(); - boolean flag = true; - int offAdjust = 0; - while (it.hasNext() && flag) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it - .next(); - if (prop.isChildListProperty()) { - List nodelist = (List) parLineNode - .getStructuralProperty(prop); - for (ASTNode cnode : nodelist) { - if (getLineNumber(cnode) == lineNumber) { - if (cnode.getStartPosition() <= lineNode.getStartPosition() - + altOff - && cnode.getStartPosition() + cnode.getLength() > lineNode - .getStartPosition() + altOff) { - System.out.println(cnode); - offAdjust = cnode.getStartPosition() - lineNode.getStartPosition(); - lineNode = cnode; - altOff -= offAdjust; - flag = false; - break; - } - - } - } - } - } - System.out.println("FLON3 "+lineNode.getStartPosition() + " off " + offset + " alt off" + altOff); - ASTNode simpName = pinpointOnLine(lineNode, altOff, - lineNode.getStartPosition(), name); - System.out.println("+++> " + simpName); - if (simpName instanceof SimpleName) { - nameOfNode = simpName.toString(); - System.out.println(getNodeAsString(simpName)); - decl = findDeclaration((SimpleName) simpName); - if (decl != null) { - System.err.println("DECLA: " + decl.getClass().getName()); - retLabelString = getNodeAsString(decl); - } else - System.err.println("null"); - - System.out.println(getNodeAsString(decl)); - } - } - - if (decl != null && scrollOnly) { - /* - * For scrolling, we highlight just the name of the node, - * i.e., a SimpleName instance. But the declared node always - * points to the declared node itself, like TypeDecl, MethodDecl, etc. - * This is important since it contains all the properties. - */ - ASTNode simpName2 = getNodeName(decl,nameOfNode); - System.err.println("FINAL String decl: " + getNodeAsString(decl)); - System.err.println("FINAL String label: " + getNodeAsString(simpName2)); - errorCheckerService.highlightNode(simpName2); - } - - return new ASTNodeWrapper(decl); - } - - /** - * Given a declaration type astnode, returns the SimpleName peroperty - * of that node. - * @param node - * @param name - The name we're looking for. - * @return SimpleName - */ - private static ASTNode getNodeName(ASTNode node, String name){ - List vdfs = null; - switch (node.getNodeType()) { - case ASTNode.TYPE_DECLARATION: - return ((TypeDeclaration) node).getName(); - case ASTNode.METHOD_DECLARATION: - return ((MethodDeclaration) node).getName(); - case ASTNode.SINGLE_VARIABLE_DECLARATION: - return ((SingleVariableDeclaration) node).getName(); - case ASTNode.FIELD_DECLARATION: - vdfs = ((FieldDeclaration) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_STATEMENT: - vdfs = ((VariableDeclarationStatement) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_EXPRESSION: - vdfs = ((VariableDeclarationExpression) node).fragments(); - break; - default: - break; - } - - if (vdfs != null) { - for (VariableDeclarationFragment vdf : vdfs) { - if (vdf.getName().toString().equals(name)) { - return vdf.getName(); - } - } - - } - return null; - } - - /** - * Fetches line number of the node in its CompilationUnit. - * @param node - * @return - */ - private static int getLineNumber(ASTNode node) { - return ((CompilationUnit) node.getRoot()).getLineNumber(node - .getStartPosition()); - } - - public static void main(String[] args) { - traversal2(); - } - - public static void traversal2() { - ASTParser parser = ASTParser.newParser(AST.JLS4); - String source = readFile("/media/quarkninja/Work/TestStuff/low.java"); -// String source = "package decl; \npublic class ABC{\n int ret(){\n}\n}"; - parser.setSource(source.toCharArray()); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - - Map options = JavaCore.getOptions(); - - JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); - options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); - parser.setCompilerOptions(options); - - CompilationUnit cu = (CompilationUnit) parser.createAST(null); - System.out.println(CompilationUnit.propertyDescriptors(AST.JLS4).size()); - - DefaultMutableTreeNode astTree = new DefaultMutableTreeNode( - "CompilationUnit"); - System.err.println("Errors: " + cu.getProblems().length); - visitRecur(cu, astTree); - System.out.println(astTree.getChildCount()); - - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - JFrame frame2 = new JFrame(); - JTree jtree = new JTree(astTree); - frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame2.setBounds(new Rectangle(100, 100, 460, 620)); - JScrollPane sp = new JScrollPane(); - sp.setViewportView(jtree); - frame2.add(sp); - frame2.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - - ASTNode found = NodeFinder.perform(cu, 468, 5); - if (found != null) { - System.out.println(found); - } - } - - private void addListeners(){ - jtree.addTreeSelectionListener(new TreeSelectionListener() { - - @Override - public void valueChanged(TreeSelectionEvent e) { - System.out.println(e); - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - if(jtree - .getLastSelectedPathComponent() == null){ - return; - } - DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) jtree - .getLastSelectedPathComponent(); - if(tnode.getUserObject() == null){ - return; - } - - if (tnode.getUserObject() instanceof ASTNodeWrapper) { - ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject(); - errorCheckerService.highlightNode(awrap); - } - } - }; - worker.execute(); - } - }); - - renameButton.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - if (editor.ta.getSelectedText() == null) - return; - if(renameTextField.getText().length() == 0) - return; - String newName = renameTextField.getText(); - DefaultMutableTreeNode defCU = findAllOccurrences(); - renameTree.setModel(new DefaultTreeModel(defCU)); - ((DefaultTreeModel) renameTree.getModel()).reload(); - int lineOffsetDisplacementConst = newName.length() - - editor.ta.getSelectedText().length(); - HashMap lineOffsetDisplacement = new HashMap(); - - for (int i = defCU.getChildCount() - 1; i >= 0; i--) { - ASTNodeWrapper awrap = (ASTNodeWrapper) ((DefaultMutableTreeNode) (defCU - .getChildAt(i))).getUserObject(); - int pdeoffsets[] = awrap.getPDECodeOffsets(errorCheckerService); - int javaoffsets[] = awrap.getJavaCodeOffsets(errorCheckerService); - - // correction for pde enhancements related displacement on a line - int off = 0; - if(lineOffsetDisplacement.get(javaoffsets[0]) != null){ - off = lineOffsetDisplacement.get(javaoffsets[0]); - - lineOffsetDisplacement.put(javaoffsets[0], - lineOffsetDisplacementConst + off); - } - else{ - lineOffsetDisplacement.put(javaoffsets[0], - lineOffsetDisplacementConst); - } - - ErrorCheckerService.scrollToErrorLine(editor, pdeoffsets[0], - pdeoffsets[1], - javaoffsets[1] + off, - javaoffsets[2]); - editor.ta.setSelectedText(newName); - } - for (Integer lineNum : lineOffsetDisplacement.keySet()) { - System.out.println(lineNum + "line, disp" - + lineOffsetDisplacement.get(lineNum)); - } - editor.getSketch().setModified(true); - } - }; - worker.execute(); - } - }); - // TODO: Diable this listner at deployment - listOccurrence.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - if (editor.ta.getSelectedText() == null) - return; - DefaultMutableTreeNode defCU = findAllOccurrences(); - renameTree.setModel(new DefaultTreeModel(defCU)); - ((DefaultTreeModel) renameTree.getModel()).reload(); - } - }; - worker.execute(); - } - }); - - renameTree.addTreeSelectionListener(new TreeSelectionListener() { - - @Override - public void valueChanged(TreeSelectionEvent e) { - System.out.println(e); - SwingWorker worker = new SwingWorker() { - - @Override - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - if(renameTree - .getLastSelectedPathComponent() == null){ - return; - } - DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) renameTree - .getLastSelectedPathComponent(); - if(tnode.getUserObject() == null){ - return; - } - - if (tnode.getUserObject() instanceof ASTNodeWrapper) { - ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject(); - errorCheckerService.highlightNode(awrap); - } - } - }; - worker.execute(); - } - }); - } - - private DefaultMutableTreeNode findAllOccurrences(){ - String selText = editor.ta.getSelectedText(); - int line = editor.ta.getSelectionStartLine(); - System.out.println(editor.ta.getSelectedText() - + "<- offsets " - + (line) - + ", " - + (editor.ta.getSelectionStart() - editor.ta - .getLineStartOffset(line)) - + ", " - + (editor.ta.getSelectionStop() - editor.ta - .getLineStartOffset(line))); - int offwhitespace = editor.ta - .getLineStartNonWhiteSpaceOffset(line); - ASTNodeWrapper wnode = getASTNodeAt(line - + errorCheckerService.mainClassOffset, - selText, - editor.ta.getSelectionStart() - - offwhitespace, false); - System.err.println("Gonna find all occurrences of " - + getNodeAsString(wnode.getNode())); - - //If wnode is a constructor, find the TD instead. - if (wnode.getNodeType() == ASTNode.METHOD_DECLARATION) { - MethodDeclaration md = (MethodDeclaration) wnode.getNode(); - ASTNode node = md.getParent(); - while (node != null) { - if (node instanceof TypeDeclaration) { - // System.out.println("Parent class " + getNodeAsString(node)); - break; - } - node = node.getParent(); - } - if(node != null && node instanceof TypeDeclaration){ - TypeDeclaration td = (TypeDeclaration) node; - if(td.getName().toString().equals(md.getName().toString())){ - System.err.println("Renaming constructor of " + getNodeAsString(td)); - wnode = new ASTNodeWrapper(td); - } - } - } - - DefaultMutableTreeNode defCU = new DefaultMutableTreeNode(wnode); - dfsNameOnly(defCU, wnode.getNode(), selText); - System.out.println(wnode); - return defCU; - } - - @SuppressWarnings({ "unchecked" }) - /** - * Generates AST Swing component - * @param node - * @param tnode - */ - public static void visitRecur(ASTNode node, DefaultMutableTreeNode tnode) { - Iterator it = node - .structuralPropertiesForType().iterator(); - //System.err.println("Props of " + node.getClass().getName()); - DefaultMutableTreeNode ctnode = null; - while (it.hasNext()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it - .next(); - - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (node.getStructuralProperty(prop) != null) { -// System.out -// .println(node.getStructuralProperty(prop) + " -> " + (prop)); - if (node.getStructuralProperty(prop) instanceof ASTNode) { - ASTNode cnode = (ASTNode) node.getStructuralProperty(prop); - if (isAddableASTNode(cnode)) { - ctnode = new DefaultMutableTreeNode( - new ASTNodeWrapper((ASTNode) node - .getStructuralProperty(prop))); - tnode.add(ctnode); - visitRecur(cnode, ctnode); - } - } else { - tnode.add(new DefaultMutableTreeNode(node - .getStructuralProperty(prop))); - } - } - } - - else if (prop.isChildListProperty()) { - List nodelist = (List) node - .getStructuralProperty(prop); - for (ASTNode cnode : nodelist) { - if (isAddableASTNode(cnode)) { - ctnode = new DefaultMutableTreeNode(new ASTNodeWrapper(cnode)); - tnode.add(ctnode); - visitRecur(cnode, ctnode); - } else - visitRecur(cnode, tnode); - } - } - } - } - - public void dfsNameOnly(DefaultMutableTreeNode tnode,ASTNode decl, String name) { - Stack temp = new Stack(); - temp.push(codeTree); - - while(!temp.isEmpty()){ - DefaultMutableTreeNode cnode = (DefaultMutableTreeNode) temp.pop(); - for (int i = 0; i < cnode.getChildCount(); i++) { - temp.push(cnode.getChildAt(i)); - } - - if(!(cnode.getUserObject() instanceof ASTNodeWrapper)) - continue; - ASTNodeWrapper awnode = (ASTNodeWrapper) cnode.getUserObject(); -// System.out.println("Visiting: " + getNodeAsString(awnode.getNode())); - if(isInstanceOfType(awnode.getNode(), decl, name)){ - tnode.add(new DefaultMutableTreeNode(awnode)); - } - - } - } - - private boolean isInstanceOfType(ASTNode node,ASTNode decl, String name){ - if(node instanceof SimpleName){ - SimpleName sn = (SimpleName) node; - - if (sn.toString().equals(name)) { - ArrayList nodesToBeMatched = new ArrayList(); - nodesToBeMatched.add(decl); - if(decl instanceof TypeDeclaration){ - System.out.println("decl is a TD"); - TypeDeclaration td = (TypeDeclaration)decl; - MethodDeclaration[] mlist = td.getMethods(); - for (MethodDeclaration md : mlist) { - if(md.getName().toString().equals(name)){ - nodesToBeMatched.add(md); - } - } - } - System.out.println("Visiting: " + getNodeAsString(node)); - ASTNode decl2 = findDeclaration(sn); - System.err.println("It's decl: " + getNodeAsString(decl2)); - System.out.println("But we need: "+getNodeAsString(decl)); - for (ASTNode astNode : nodesToBeMatched) { - if(astNode.equals(decl2)){ - return true; - } - } - } - } - return false; - } - - public void handleRefactor(){ - if (!renameWindow.isVisible()) - renameWindow.setVisible(true); - renameWindow.toFront(); - } - - - public static void printRecur(ASTNode node) { - Iterator it = node - .structuralPropertiesForType().iterator(); - //System.err.println("Props of " + node.getClass().getName()); - while (it.hasNext()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it - .next(); - - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (node.getStructuralProperty(prop) != null) { -// System.out -// .println(node.getStructuralProperty(prop) + " -> " + (prop)); - if (node.getStructuralProperty(prop) instanceof ASTNode) { - ASTNode cnode = (ASTNode) node.getStructuralProperty(prop); - System.out.println(getNodeAsString(cnode)); - printRecur(cnode); - } - } - } - - else if (prop.isChildListProperty()) { - List nodelist = (List) node - .getStructuralProperty(prop); - for (ASTNode cnode : nodelist) { - System.out.println(getNodeAsString(cnode)); - printRecur(cnode); - } - } - } - } - - @SuppressWarnings("unchecked") - private static ASTNode findLineOfNode(ASTNode node, int lineNumber, - int offset, String name) { - - CompilationUnit root = (CompilationUnit) node.getRoot(); -// System.out.println("Inside "+getNodeAsString(node) + " | " + root.getLineNumber(node.getStartPosition())); - if (root.getLineNumber(node.getStartPosition()) == lineNumber) { - System.err - .println(3 + getNodeAsString(node) + " len " + node.getLength()); - return node; -// if (offset < node.getLength()) -// return node; -// else { -// System.err.println(-11); -// return null; -// } - } - for (Object oprop : node.structuralPropertiesForType()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) oprop; - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (node.getStructuralProperty(prop) != null) { - if (node.getStructuralProperty(prop) instanceof ASTNode) { - ASTNode retNode = findLineOfNode((ASTNode) node - .getStructuralProperty(prop), - lineNumber, offset, name); - if (retNode != null) { -// System.err.println(11 + getNodeAsString(retNode)); - return retNode; - } - } - } - } else if (prop.isChildListProperty()) { - List nodelist = (List) node - .getStructuralProperty(prop); - for (ASTNode retNode : nodelist) { - - ASTNode rr = findLineOfNode(retNode, lineNumber, offset, name); - if (rr != null) { -// System.err.println(12 + getNodeAsString(rr)); - return rr; - } - } - } - } -// System.err.println("-1"); - return null; - } - - /** - * - * @param node - * @param offset - * - from textarea painter - * @param lineStartOffset - * - obtained from findLineOfNode - * @param name - * @param root - * @return - */ - @SuppressWarnings("unchecked") - public static ASTNode pinpointOnLine(ASTNode node, int offset, - int lineStartOffset, String name) { - - if (node instanceof SimpleName) { - SimpleName sn = (SimpleName) node; - System.out.println(offset+ "off,pol " + getNodeAsString(sn)); - if ((lineStartOffset + offset) >= sn.getStartPosition() - && (lineStartOffset + offset) <= sn.getStartPosition() - + sn.getLength()) { - if (sn.toString().equals(name)) { - return sn; - } - else { - return null; - } - } else { - return null; - } - } - for (Object oprop : node.structuralPropertiesForType()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) oprop; - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (node.getStructuralProperty(prop) != null) { - if (node.getStructuralProperty(prop) instanceof ASTNode) { - ASTNode retNode = pinpointOnLine((ASTNode) node - .getStructuralProperty(prop), - offset, lineStartOffset, name); - if (retNode != null) { -// System.err.println(11 + getNodeAsString(retNode)); - return retNode; - } - } - } - } else if (prop.isChildListProperty()) { - List nodelist = (List) node - .getStructuralProperty(prop); - for (ASTNode retNode : nodelist) { - - ASTNode rr = pinpointOnLine(retNode, offset, lineStartOffset, name); - if (rr != null) { -// System.err.println(12 + getNodeAsString(rr)); - return rr; - } - } - } - } -// System.err.println("-1"); - return null; - } - - @SuppressWarnings("unchecked") - private static ASTNode findDeclaration(Name findMe) { - ASTNode declaringClass = null; - ASTNode parent = findMe.getParent(); - ASTNode ret = null; - ArrayList constrains = new ArrayList(); - if (parent.getNodeType() == ASTNode.METHOD_INVOCATION) { - Expression exp = (Expression) ((MethodInvocation) parent) - .getStructuralProperty(MethodInvocation.EXPRESSION_PROPERTY); - //TODO: Note the imbalance of constrains.add(ASTNode.METHOD_DECLARATION); - // Possibly a bug here. Investigate later. - if (((MethodInvocation) parent).getName().toString() - .equals(findMe.toString())) { - constrains.add(ASTNode.METHOD_DECLARATION); - - if (exp != null) { - constrains.add(ASTNode.TYPE_DECLARATION); - System.out.println("MI EXP: " + exp.toString() + " of type " - + exp.getClass().getName() + " parent: " + exp.getParent()); - if (exp instanceof MethodInvocation) { - SimpleType stp = extracTypeInfo(findDeclaration(((MethodInvocation) exp) - .getName())); - if (stp == null) - return null; - declaringClass = findDeclaration(stp.getName()); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } else if (exp instanceof FieldAccess) { - SimpleType stp = extracTypeInfo(findDeclaration(((FieldAccess) exp) - .getName())); - if (stp == null) - return null; - declaringClass = findDeclaration((stp.getName())); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } - if (exp instanceof SimpleName) { - SimpleType stp = extracTypeInfo(findDeclaration(((SimpleName) exp))); - if (stp == null) - return null; - declaringClass = findDeclaration(stp.getName()); - System.out.println("MI.SN " + getNodeAsString(declaringClass)); - constrains.add(ASTNode.METHOD_DECLARATION); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } - - } - } else { - parent = parent.getParent(); // Move one up the ast. V V IMP!! - } - } else if (parent.getNodeType() == ASTNode.FIELD_ACCESS) { - FieldAccess fa = (FieldAccess) parent; - Expression exp = fa.getExpression(); - if (fa.getName().toString().equals(findMe.toString())) { - constrains.add(ASTNode.FIELD_DECLARATION); - - if (exp != null) { - constrains.add(ASTNode.TYPE_DECLARATION); - System.out.println("FA EXP: " + exp.toString() + " of type " - + exp.getClass().getName() + " parent: " + exp.getParent()); - if (exp instanceof MethodInvocation) { - SimpleType stp = extracTypeInfo(findDeclaration(((MethodInvocation) exp) - .getName())); - if (stp == null) - return null; - declaringClass = findDeclaration(stp.getName()); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } else if (exp instanceof FieldAccess) { - SimpleType stp = extracTypeInfo(findDeclaration(((FieldAccess) exp) - .getName())); - if (stp == null) - return null; - declaringClass = findDeclaration((stp.getName())); - constrains.add(ASTNode.TYPE_DECLARATION); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } - if (exp instanceof SimpleName) { - SimpleType stp = extracTypeInfo(findDeclaration(((SimpleName) exp))); - if (stp == null) - return null; - declaringClass = findDeclaration(stp.getName()); - System.out.println("FA.SN " + getNodeAsString(declaringClass)); - constrains.add(ASTNode.METHOD_DECLARATION); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } - } - - } else { - parent = parent.getParent(); // Move one up the ast. V V IMP!! - } - } else if (parent.getNodeType() == ASTNode.QUALIFIED_NAME) { - - QualifiedName qn = (QualifiedName) parent; - if (!findMe.toString().equals(qn.getQualifier().toString())) { - - SimpleType stp = extracTypeInfo(findDeclaration((qn.getQualifier()))); - declaringClass = findDeclaration(stp.getName()); - System.out.println(qn.getQualifier() + "->" + qn.getName()); - System.out.println("QN decl class: " + getNodeAsString(declaringClass)); - constrains.clear(); - constrains.add(ASTNode.TYPE_DECLARATION); - constrains.add(ASTNode.FIELD_DECLARATION); - return definedIn(declaringClass, qn.getName().toString(), constrains, - null); - } - } else if (parent.getNodeType() == ASTNode.SIMPLE_TYPE) { - constrains.add(ASTNode.TYPE_DECLARATION); - if (parent.getParent().getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) - constrains.add(ASTNode.CLASS_INSTANCE_CREATION); - } else if(parent.getNodeType() == ASTNode.TYPE_DECLARATION){ - // The condition where we look up the name of a class decl - TypeDeclaration td = (TypeDeclaration) parent; - if(findMe.equals(td.getName())) - { - return parent; - } - } - else if (parent instanceof Expression) { -// constrains.add(ASTNode.TYPE_DECLARATION); -// constrains.add(ASTNode.METHOD_DECLARATION); -// constrains.add(ASTNode.FIELD_DECLARATION); - } - while (parent != null) { - System.out.println("findDeclaration1 -> " + getNodeAsString(parent)); - for (Object oprop : parent.structuralPropertiesForType()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) oprop; - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (parent.getStructuralProperty(prop) instanceof ASTNode) { -// System.out.println(prop + " C/S Prop of -> " -// + getNodeAsString(parent)); - ret = definedIn((ASTNode) parent.getStructuralProperty(prop), - findMe.toString(), constrains, declaringClass); - if (ret != null) - return ret; - } - } else if (prop.isChildListProperty()) { -// System.out.println((prop) + " ChildList props of " -// + getNodeAsString(parent)); - List nodelist = (List) parent - .getStructuralProperty(prop); - for (ASTNode retNode : nodelist) { - ret = definedIn(retNode, findMe.toString(), constrains, - declaringClass); - if (ret != null) - return ret; - } - } - } - parent = parent.getParent(); - } - return null; - } - - private static ASTNode findDeclaration2(Name findMe, ASTNode alternateParent) { - ASTNode declaringClass = null; - ASTNode parent = findMe.getParent(); - ASTNode ret = null; - ArrayList constrains = new ArrayList(); - if (parent.getNodeType() == ASTNode.METHOD_INVOCATION) { - Expression exp = (Expression) ((MethodInvocation) parent) - .getStructuralProperty(MethodInvocation.EXPRESSION_PROPERTY); - //TODO: Note the imbalance of constrains.add(ASTNode.METHOD_DECLARATION); - // Possibly a bug here. Investigate later. - if (((MethodInvocation) parent).getName().toString() - .equals(findMe.toString())) { - constrains.add(ASTNode.METHOD_DECLARATION); - - if (exp != null) { - constrains.add(ASTNode.TYPE_DECLARATION); - System.out.println("MI EXP: " + exp.toString() + " of type " - + exp.getClass().getName() + " parent: " + exp.getParent()); - if (exp instanceof MethodInvocation) { - SimpleType stp = extracTypeInfo(findDeclaration2(((MethodInvocation) exp) - .getName(), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2(stp.getName(), alternateParent); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } else if (exp instanceof FieldAccess) { - SimpleType stp = extracTypeInfo(findDeclaration2(((FieldAccess) exp) - .getName(), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2((stp.getName()), alternateParent); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } - if (exp instanceof SimpleName) { - SimpleType stp = extracTypeInfo(findDeclaration2(((SimpleName) exp), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2(stp.getName(), alternateParent); - System.out.println("MI.SN " + getNodeAsString(declaringClass)); - constrains.add(ASTNode.METHOD_DECLARATION); - return definedIn(declaringClass, ((MethodInvocation) parent) - .getName().toString(), constrains, declaringClass); - } - - } - } else { - parent = parent.getParent(); // Move one up the ast. V V IMP!! - alternateParent = alternateParent.getParent(); - } - } else if (parent.getNodeType() == ASTNode.FIELD_ACCESS) { - FieldAccess fa = (FieldAccess) parent; - Expression exp = fa.getExpression(); - if (fa.getName().toString().equals(findMe.toString())) { - constrains.add(ASTNode.FIELD_DECLARATION); - - if (exp != null) { - constrains.add(ASTNode.TYPE_DECLARATION); - System.out.println("FA EXP: " + exp.toString() + " of type " - + exp.getClass().getName() + " parent: " + exp.getParent()); - if (exp instanceof MethodInvocation) { - SimpleType stp = extracTypeInfo(findDeclaration2(((MethodInvocation) exp) - .getName(), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2(stp.getName(), alternateParent); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } else if (exp instanceof FieldAccess) { - SimpleType stp = extracTypeInfo(findDeclaration2(((FieldAccess) exp) - .getName(), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2((stp.getName()), alternateParent); - constrains.add(ASTNode.TYPE_DECLARATION); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } - if (exp instanceof SimpleName) { - SimpleType stp = extracTypeInfo(findDeclaration2(((SimpleName) exp), - alternateParent)); - if (stp == null) - return null; - declaringClass = findDeclaration2(stp.getName(), alternateParent); - System.out.println("FA.SN " + getNodeAsString(declaringClass)); - constrains.add(ASTNode.METHOD_DECLARATION); - return definedIn(declaringClass, fa.getName().toString(), - constrains, declaringClass); - } - } - - } else { - parent = parent.getParent(); // Move one up the ast. V V IMP!! - alternateParent = alternateParent.getParent(); - } - } else if (parent.getNodeType() == ASTNode.QUALIFIED_NAME) { - - QualifiedName qn = (QualifiedName) parent; - if (!findMe.toString().equals(qn.getQualifier().toString())) { - - SimpleType stp = extracTypeInfo(findDeclaration2((qn.getQualifier()), - alternateParent)); - declaringClass = findDeclaration2(stp.getName(), alternateParent); - System.out.println(qn.getQualifier() + "->" + qn.getName()); - System.out.println("QN decl class: " + getNodeAsString(declaringClass)); - constrains.clear(); - constrains.add(ASTNode.TYPE_DECLARATION); - constrains.add(ASTNode.FIELD_DECLARATION); - return definedIn(declaringClass, qn.getName().toString(), constrains, - null); - } - } else if (parent.getNodeType() == ASTNode.SIMPLE_TYPE) { - constrains.add(ASTNode.TYPE_DECLARATION); - if (parent.getParent().getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) - constrains.add(ASTNode.CLASS_INSTANCE_CREATION); - } else if (parent instanceof Expression) { -// constrains.add(ASTNode.TYPE_DECLARATION); -// constrains.add(ASTNode.METHOD_DECLARATION); -// constrains.add(ASTNode.FIELD_DECLARATION); - } // TODO: in findDec, we also have a case where parent of type TD is handled. - // Figure out if needed here as well. - System.out.println("Alternate parent: " + getNodeAsString(alternateParent)); - while (alternateParent != null) { -// System.out.println("findDeclaration2 -> " -// + getNodeAsString(alternateParent)); - for (Object oprop : alternateParent.structuralPropertiesForType()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) oprop; - if (prop.isChildProperty() || prop.isSimpleProperty()) { - if (alternateParent.getStructuralProperty(prop) instanceof ASTNode) { -// System.out.println(prop + " C/S Prop of -> " -// + getNodeAsString(alternateParent)); - ret = definedIn((ASTNode) alternateParent - .getStructuralProperty(prop), - findMe.toString(), constrains, declaringClass); - if (ret != null) - return ret; - } - } else if (prop.isChildListProperty()) { -// System.out.println((prop) + " ChildList props of " -// + getNodeAsString(alternateParent)); - List nodelist = (List) alternateParent - .getStructuralProperty(prop); - for (ASTNode retNode : nodelist) { - ret = definedIn(retNode, findMe.toString(), constrains, - declaringClass); - if (ret != null) - return ret; - } - } - } - alternateParent = alternateParent.getParent(); - } - return null; - } - - /** - * Find the SimpleType from FD, SVD, VDS, etc - * - * @param node - * @return - */ - private static SimpleType extracTypeInfo(ASTNode node) { - if (node == null) - return null; - switch (node.getNodeType()) { - case ASTNode.METHOD_DECLARATION: - return (SimpleType) ((MethodDeclaration) node) - .getStructuralProperty(MethodDeclaration.RETURN_TYPE2_PROPERTY); - case ASTNode.FIELD_DECLARATION: - return (SimpleType) ((FieldDeclaration) node) - .getStructuralProperty(FieldDeclaration.TYPE_PROPERTY); - case ASTNode.VARIABLE_DECLARATION_EXPRESSION: - return (SimpleType) ((VariableDeclarationExpression) node) - .getStructuralProperty(VariableDeclarationExpression.TYPE_PROPERTY); - case ASTNode.VARIABLE_DECLARATION_STATEMENT: - return (SimpleType) ((VariableDeclarationStatement) node) - .getStructuralProperty(VariableDeclarationStatement.TYPE_PROPERTY); - case ASTNode.SINGLE_VARIABLE_DECLARATION: - return (SimpleType) ((SingleVariableDeclaration) node) - .getStructuralProperty(SingleVariableDeclaration.TYPE_PROPERTY); - } - return null; - } - - @SuppressWarnings("unchecked") - private static ASTNode definedIn(ASTNode node, String name, - ArrayList constrains, - ASTNode declaringClass) { - if (node == null) - return null; - if (constrains != null) { -// System.out.println("Looking at " + getNodeAsString(node) + " for " + name -// + " in definedIn"); - if (!constrains.contains(node.getNodeType()) && constrains.size() > 0) { -// System.err.print("definedIn -1 " + " But constrain was "); -// for (Integer integer : constrains) { -// System.out.print(ASTNode.nodeClassForType(integer) + ","); -// } -// System.out.println(); - return null; - } - } - - List vdfList = null; - switch (node.getNodeType()) { - - case ASTNode.TYPE_DECLARATION: - System.err.println(getNodeAsString(node)); - TypeDeclaration td = (TypeDeclaration) node; - if (td.getName().toString().equals(name)) { - if (constrains.contains(ASTNode.CLASS_INSTANCE_CREATION)) { - // look for constructor; - MethodDeclaration[] methods = td.getMethods(); - for (MethodDeclaration md : methods) { - if (md.getName().toString().equals(name)) { - System.out.println("Found a constructor."); - return md; - } - } - } else { - // it's just the TD we're lookin for - return node; - } - } else { - if (constrains.contains(ASTNode.FIELD_DECLARATION)) { - // look for fields - FieldDeclaration[] fields = td.getFields(); - for (FieldDeclaration fd : fields) { - List fragments = fd.fragments(); - for (VariableDeclarationFragment vdf : fragments) { - if (vdf.getName().toString().equals(name)) - return fd; - } - } - } else if (constrains.contains(ASTNode.METHOD_DECLARATION)) { - // look for methods - MethodDeclaration[] methods = td.getMethods(); - for (MethodDeclaration md : methods) { - if (md.getName().toString().equals(name)) { - return md; - } - } - } - } - break; - case ASTNode.METHOD_DECLARATION: - System.err.println(getNodeAsString(node)); - if (((MethodDeclaration) node).getName().toString().equals(name)) - return node; - break; - case ASTNode.SINGLE_VARIABLE_DECLARATION: - System.err.println(getNodeAsString(node)); - if (((SingleVariableDeclaration) node).getName().toString().equals(name)) - return node; - break; - case ASTNode.FIELD_DECLARATION: - System.err.println("FD" + node); - vdfList = ((FieldDeclaration) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_EXPRESSION: - System.err.println("VDE" + node); - vdfList = ((VariableDeclarationExpression) node).fragments(); - break; - case ASTNode.VARIABLE_DECLARATION_STATEMENT: - System.err.println("VDS" + node); - vdfList = ((VariableDeclarationStatement) node).fragments(); - break; - - default: - - } - if (vdfList != null) { - for (VariableDeclarationFragment vdf : vdfList) { - if (vdf.getName().toString().equals(name)) - return node; - } - } - return null; - } - - public static boolean isAddableASTNode(ASTNode node) { - switch (node.getNodeType()) { -// case ASTNode.STRING_LITERAL: -// case ASTNode.NUMBER_LITERAL: -// case ASTNode.BOOLEAN_LITERAL: -// case ASTNode.NULL_LITERAL: -// return false; - default: - return true; - } - } - - /** - * For any line or expression, finds the line start offset(java code). - * @param node - * @return - */ - public int getASTNodeLineStartOffset(ASTNode node){ - int nodeLineNo = getLineNumber(node); - while(node.getParent() != null){ - if (getLineNumber(node.getParent()) == nodeLineNo) { - node = node.getParent(); - } else { - break; - } - } - return node.getStartPosition(); - } - - /** - * For any node, finds various offsets (java code). - * - * @param node - * @return int[]{line number, line number start offset, node start offset, - * node length} - */ - public int[] getASTNodeAllOffsets(ASTNode node){ - int nodeLineNo = getLineNumber(node), nodeOffset = node.getStartPosition(), nodeLength = node - .getLength(); - while(node.getParent() != null){ - if (getLineNumber(node.getParent()) == nodeLineNo) { - node = node.getParent(); - } else { - break; - } - } - return new int[]{nodeLineNo, node.getStartPosition(), nodeOffset,nodeLength}; - } - - - - static private String getNodeAsString(ASTNode node) { - if (node == null) - return "NULL"; - String className = node.getClass().getName(); - int index = className.lastIndexOf("."); - if (index > 0) - className = className.substring(index + 1); - - // if(node instanceof BodyDeclaration) - // return className; - - String value = className; - - if (node instanceof TypeDeclaration) - value = ((TypeDeclaration) node).getName().toString() + " | " + className; - else if (node instanceof MethodDeclaration) - value = ((MethodDeclaration) node).getName().toString() + " | " - + className; - else if (node instanceof MethodInvocation) - value = ((MethodInvocation) node).getName().toString() + " | " - + className; - else if (node instanceof FieldDeclaration) - value = ((FieldDeclaration) node).toString() + " FldDecl| "; - else if (node instanceof SingleVariableDeclaration) - value = ((SingleVariableDeclaration) node).getName() + " - " - + ((SingleVariableDeclaration) node).getType() + " | SVD "; - else if (node instanceof ExpressionStatement) - value = node.toString() + className; - else if (node instanceof SimpleName) - value = ((SimpleName) node).getFullyQualifiedName() + " | " + className; - else if (node instanceof QualifiedName) - value = node.toString() + " | " + className; - else if (className.startsWith("Variable")) - value = node.toString() + " | " + className; - else if (className.endsWith("Type")) - value = node.toString() + " |" + className; - value += " [" + node.getStartPosition() + "," - + (node.getStartPosition() + node.getLength()) + "]"; - value += " Line: " - + ((CompilationUnit) node.getRoot()).getLineNumber(node - .getStartPosition()); - return value; - } - - /** - * CompletionPanel name - * - * @param node - * @return - */ - static private String getNodeAsString2(ASTNode node) { - if (node == null) - return "NULL"; - String className = node.getClass().getName(); - int index = className.lastIndexOf("."); - if (index > 0) - className = className.substring(index + 1); - - // if(node instanceof BodyDeclaration) - // return className; - - String value = className; - - if (node instanceof TypeDeclaration) - value = ((TypeDeclaration) node).getName().toString(); - else if (node instanceof MethodDeclaration) - value = ((MethodDeclaration) node).getName().toString(); - else if (node instanceof MethodInvocation) - value = ((MethodInvocation) node).getName().toString() + " | " - + className; - else if (node instanceof FieldDeclaration) - value = ((FieldDeclaration) node).toString(); - else if (node instanceof SingleVariableDeclaration) - value = ((SingleVariableDeclaration) node).getName().toString(); - else if (node instanceof ExpressionStatement) - value = node.toString() + className; - else if (node instanceof SimpleName) - value = ((SimpleName) node).getFullyQualifiedName() + " | " + className; - else if (node instanceof QualifiedName) - value = node.toString(); - else if (node instanceof VariableDeclarationFragment) - value = ((VariableDeclarationFragment) node).getName().toString(); - else if (className.startsWith("Variable")) - value = node.toString(); - else if (node instanceof VariableDeclarationStatement) - value = ((VariableDeclarationStatement) node).toString(); - else if (className.endsWith("Type")) - value = node.toString(); -// value += " [" + node.getStartPosition() + "," -// + (node.getStartPosition() + node.getLength()) + "]"; -// value += " Line: " -// + ((CompilationUnit) node.getRoot()).getLineNumber(node -// .getStartPosition()); - return value; - } - - public void jdocWindowVisible(boolean visible) { - jdocWindow.setVisible(visible); - } - - public static String readFile(String path) { - BufferedReader reader = null; - try { - reader = new BufferedReader( - new InputStreamReader( - new FileInputStream( - new File( - path)))); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - try { - StringBuilder ret = new StringBuilder(); - // ret.append("package " + className + ";\n"); - String line; - while ((line = reader.readLine()) != null) { - ret.append(line); - ret.append("\n"); - } - return ret.toString(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return null; - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/ASTNodeWrapper.java b/pdex/experimental/src/processing/mode/experimental/ASTNodeWrapper.java deleted file mode 100644 index 359d3d4e2..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ASTNodeWrapper.java +++ /dev/null @@ -1,425 +0,0 @@ -package processing.mode.experimental; - -import java.util.Iterator; -import java.util.List; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ExpressionStatement; -import org.eclipse.jdt.core.dom.FieldDeclaration; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.QualifiedName; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.SingleVariableDeclaration; -import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; -import org.eclipse.jdt.core.dom.TypeDeclaration; - -public class ASTNodeWrapper { - private ASTNode Node; - - private String label; - - private int lineNumber; - - //private int apiLevel; - - /* - * TODO: Every ASTNode object in ASTGenerator.codetree is stored as a - * ASTNodeWrapper instance. So how resource heavy would it be to store a - * pointer to ECS in every instance of ASTNodeWrapper? Currently I will rather - * pass an ECS pointer in the argument when I need to access a method which - * requires a method defined in ECS, i.e, only on demand. - * Bad design choice for ECS methods? IDK, yet. - */ - - public ASTNodeWrapper(ASTNode node) { - if (node == null){ - return; - } - this.Node = node; - label = getNodeAsString(node); - if (label == null) - label = node.toString(); - lineNumber = getLineNumber(node); - label += " | Line " + lineNumber; - //apiLevel = 0; - } - - /** - * For this node, finds various offsets (java code). - * Note that line start offset for this node is int[2] - int[1] - * @return int[]{line number, line number start offset, node start offset, - * node length} - */ - public int[] getJavaCodeOffsets(ErrorCheckerService ecs) { - int nodeOffset = Node.getStartPosition(), nodeLength = Node - .getLength(); - ASTNode thisNode = Node; - while (thisNode.getParent() != null) { - if (getLineNumber(thisNode.getParent()) == lineNumber) { - thisNode = thisNode.getParent(); - } else { - break; - } - } - /* - * There's an edge case here - multiple statements in a single line. - * After identifying the statement with the line number, I'll have to - * look at previous tree nodes in the same level for same line number. - * The correct line start offset would be the line start offset of - * the first node with this line number. - * - * Using linear search for now. P.S: Eclipse AST iterators are messy. - * TODO: binary search might improve speed by 0.001%? - */ - - int altStartPos = thisNode.getStartPosition(); - thisNode = thisNode.getParent(); - - Iterator it = thisNode - .structuralPropertiesForType().iterator(); - boolean flag = true; - while (it.hasNext()) { - StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it - .next(); - if (prop.isChildListProperty()) { - List nodelist = (List) thisNode - .getStructuralProperty(prop); - for (ASTNode cnode : nodelist) { - if (getLineNumber(cnode) == lineNumber) { - if (flag) { - altStartPos = cnode.getStartPosition(); - // System.out.println("multi..."); - - flag = false; - } else { - if(cnode == Node){ - // loop only till the current node. - break; - } - // We've located the first node in the line. - // Now normalize offsets till Node - //altStartPos += normalizeOffsets(cnode); - - } - - } - } - } - } - System.out.println("Altspos " + altStartPos); - int pdeoffsets[] = getPDECodeOffsets(ecs); - String pdeCode = ecs.getPDECodeAtLine(pdeoffsets[0],pdeoffsets[1] - 1).trim(); - int vals[] = createOffsetMapping(pdeCode,nodeOffset - altStartPos,nodeLength); - if (vals != null) - return new int[] { - lineNumber, nodeOffset + vals[0] - altStartPos, vals[1] }; - else - return new int[] { lineNumber, nodeOffset - altStartPos, nodeLength }; - } - - - /** - * - * @param source - * @param inpOffset - * @param nodeLen - * @return int[0] - difference in start offset, int[1] - node length - */ - private int[] createOffsetMapping(String source, int inpOffset, int nodeLen) { - - int ret[][] = getOffsetMapping(source); - if(ret == null){ - // no offset mapping needed - return null; - } - int javaCodeMap[] = ret[0]; - int pdeCodeMap[] = ret[1]; - int pi = 1, pj = 1; - pj = 0; - pi = 0; - int count = 1; - // first find the java code index - pj = inpOffset; - - int startIndex = javaCodeMap[pj]; - - // find beginning - while (pdeCodeMap[pi] != startIndex && pi < pdeCodeMap.length) - pi++; - int startoffDif = pi - pj; - int stopindex = javaCodeMap[pj + nodeLen - 1]; - System.out.println(startIndex + "SI,St" + stopindex + "sod " + startoffDif); - - // count till stopindex - while (pdeCodeMap[pi] < stopindex && pi < pdeCodeMap.length) { - pi++; - count++; - } - -// System.out.println("PDE maps from " + pdeeCodeMap[pi]); - - System.out.println("pde len " + count); - return new int[] { startoffDif, count }; - } - - /** - * Generates offset mapping between java and pde code - * - * @param source - * @return int[0] - java code offsets, int[1] = pde code offsets - */ - public int[][] getOffsetMapping(String source){ - - /* - * This is some tricky shiz. So detailed explanation follows: - * - * The main issue here is that pde enhancements like color vars, # literals - * and int() type casting deviate from standard java. But I need to exact - * index matching for pde and java versions of snippets.For ex: - * "color col = #ffaadd;" <-PDE version - * "int col = 0xffffaadd;" <-Converted to Java - * - * For exact index mapping, I need to know at which indices either is - * deviating from the other and by what amount. Turns out, it isn't quite - * easy.(1) First I take the pde version of the code as an argument(pde - * version fetched from the editor directly). I then find all instances - * which need to be converted to pure java, marking those indices and the - * index correction needed. (2) Now all java conversions are applied after - * marking the offsets. This ensures that the index order isn't disturbed by - * one at a time conversions as done in preprocessCode() in ECS. Took me - * sometime to figure out this was a bug. (3) Next I create a tables(two - * separate arrays) which allows me to look it up for matching any index - * between pde or java version of the snippet. This also lets me find out - * any difference in length between both versions. - * - * Keep in mind though, dark magic was involved in creating the final lookup - * table. - * - * TODO: This is a work in progress. There may be more bugs here in hiding. - */ - - System.out.println("Src:" + source); - String sourceAlt = new String(source); - TreeMap offsetmap = new TreeMap(); - - // Find all #[web color] - // Should be 6 digits only. - final String webColorRegexp = "#{1}[A-F|a-f|0-9]{6}\\W"; - Pattern webPattern = Pattern.compile(webColorRegexp); - Matcher webMatcher = webPattern.matcher(sourceAlt); - while (webMatcher.find()) { - // System.out.println("Found at: " + webMatcher.start()); - // System.out.println("-> " + found); - offsetmap.put(webMatcher.end() - 1, 3); - } - - // Find all color data types - final String colorTypeRegex = "color(?![a-zA-Z0-9_])(?=\\[*)(?!(\\s*\\())"; - Pattern colorPattern = Pattern.compile(colorTypeRegex); - Matcher colorMatcher = colorPattern.matcher(sourceAlt); - while (colorMatcher.find()) { -// System.out.print("Start index: " + colorMatcher.start()); -// System.out.println(" End index: " + colorMatcher.end() + " "); -// System.out.println("-->" + colorMatcher.group() + "<--"); - offsetmap.put(colorMatcher.end() - 1, -2); - } - - // Find all int(), char() - String dataTypeFunc[] = { "int", "char", "float", "boolean", "byte" }; - - for (String dataType : dataTypeFunc) { - String dataTypeRegexp = "\\b" + dataType + "\\s*\\("; - Pattern pattern = Pattern.compile(dataTypeRegexp); - Matcher matcher = pattern.matcher(sourceAlt); - - while (matcher.find()) { -// System.out.print("Start index: " + matcher.start()); -// System.out.println(" End index: " + matcher.end() + " "); -// System.out.println("-->" + matcher.group() + "<--"); - offsetmap.put(matcher.end() - 1, ("PApplet.parse").length()); - } - matcher.reset(); - sourceAlt = matcher.replaceAll("PApplet.parse" - + Character.toUpperCase(dataType.charAt(0)) + dataType.substring(1) - + "("); - - } - if(offsetmap.isEmpty()){ - System.out.println("No offset matching needed."); - return null; - } - // replace with 0xff[webcolor] and others - webMatcher = webPattern.matcher(sourceAlt); - while (webMatcher.find()) { - // System.out.println("Found at: " + webMatcher.start()); - String found = sourceAlt.substring(webMatcher.start(), webMatcher.end()); - // System.out.println("-> " + found); - sourceAlt = webMatcher.replaceFirst("0xff" + found.substring(1)); - webMatcher = webPattern.matcher(sourceAlt); - } - - colorMatcher = colorPattern.matcher(sourceAlt); - sourceAlt = colorMatcher.replaceAll("int"); - - System.out.println(sourceAlt); - - // Create code map. Beware! Dark magic ahead. - int javaCodeMap[] = new int[source.length() * 2]; - int pdeCodeMap[] = new int[source.length() * 2]; - int pi = 1, pj = 1; - int keySum = 0; - for (Integer key : offsetmap.keySet()) { - for (; pi < key +keySum; pi++) { - javaCodeMap[pi] = javaCodeMap[pi - 1] + 1; - } - for (; pj < key; pj++) { - pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1; - } - - System.out.println(key + ":" + offsetmap.get(key)); - - int kval = offsetmap.get(key); - if (kval > 0) { - // repeat java offsets - pi--; - pj--; - for (int i = 0; i < kval; i++, pi++, pj++) { - javaCodeMap[pi] = javaCodeMap[pi - 1]; - pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1; - } - } else { - // repeat pde offsets - pi--; - pj--; - for (int i = 0; i < -kval; i++, pi++, pj++) { - javaCodeMap[pi] = javaCodeMap[pi - 1] + 1; - pdeCodeMap[pj] = pdeCodeMap[pj - 1]; - } - } - - // after each adjustment, the key values need to keep - // up with changed offset - keySum += kval; - } - - javaCodeMap[pi] = javaCodeMap[pi - 1] + 1; - pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1; - - while (pi < sourceAlt.length()) { - javaCodeMap[pi] = javaCodeMap[pi - 1] + 1; - pi++; - } - while (pj < source.length()) { - pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1; - pj++; - } - - // deubg o/p - for (int i = 0; i < pdeCodeMap.length; i++) { - if (pdeCodeMap[i] > 0 || javaCodeMap[i] > 0 || i == 0) { - if (i < source.length()) - System.out.print(source.charAt(i)); - System.out.print(pdeCodeMap[i] + " - " + javaCodeMap[i]); - if (i < sourceAlt.length()) - System.out.print(sourceAlt.charAt(i)); - System.out.print(" <-[" + i + "]"); - System.out.println(); - } - } - System.out.println(); - - return new int[][]{javaCodeMap,pdeCodeMap}; - } - - public int[][] getOffsetMapping(ErrorCheckerService ecs){ - int pdeoffsets[] = getPDECodeOffsets(ecs); - String pdeCode = ecs.getPDECodeAtLine(pdeoffsets[0],pdeoffsets[1] - 1).trim(); - return getOffsetMapping(pdeCode); - } - - /** - * - * @param ecs - * - ErrorCheckerService instance - * @return int[0] - tab number, int[1] - line number in the int[0] tab, int[2] - * - line start offset, int[3] - offset from line start int[2] and - * int[3] are on TODO - */ - public int[] getPDECodeOffsets(ErrorCheckerService ecs) { - return ecs.JavaToPdeOffsets(lineNumber + 1, Node.getStartPosition()); - } - - public String toString() { - return label; - } - - public ASTNode getNode() { - return Node; - } - - public String getLabel() { - return label; - } - - public int getNodeType() { - return Node.getNodeType(); - } - - public int getLineNumber() { - return lineNumber; - } - - private static int getLineNumber(ASTNode node) { - return ((CompilationUnit) node.getRoot()).getLineNumber(node - .getStartPosition()); - } - - static private String getNodeAsString(ASTNode node) { - if (node == null) - return "NULL"; - String className = node.getClass().getName(); - int index = className.lastIndexOf("."); - if (index > 0) - className = className.substring(index + 1); - - // if(node instanceof BodyDeclaration) - // return className; - - String value = className; - - if (node instanceof TypeDeclaration) - value = ((TypeDeclaration) node).getName().toString() + " | " + className; - else if (node instanceof MethodDeclaration) - value = ((MethodDeclaration) node).getName().toString() + " | " - + className; - else if (node instanceof MethodInvocation) - value = ((MethodInvocation) node).getName().toString() + " | " - + className; - else if (node instanceof FieldDeclaration) - value = ((FieldDeclaration) node).toString() + " FldDecl| "; - else if (node instanceof SingleVariableDeclaration) - value = ((SingleVariableDeclaration) node).getName() + " - " - + ((SingleVariableDeclaration) node).getType() + " | SVD "; - else if (node instanceof ExpressionStatement) - value = node.toString() + className; - else if (node instanceof SimpleName) - value = ((SimpleName) node).getFullyQualifiedName() + " | " + className; - else if (node instanceof QualifiedName) - value = node.toString() + " | " + className; - else if (className.startsWith("Variable")) - value = node.toString() + " | " + className; - else if (className.endsWith("Type")) - value = node.toString() + " |" + className; - value += " [" + node.getStartPosition() + "," - + (node.getStartPosition() + node.getLength()) + "]"; - value += " Line: " - + ((CompilationUnit) node.getRoot()).getLineNumber(node - .getStartPosition()); - return value; - } -} \ No newline at end of file diff --git a/pdex/experimental/src/processing/mode/experimental/ArrayFieldNode.java b/pdex/experimental/src/processing/mode/experimental/ArrayFieldNode.java deleted file mode 100755 index 04b3fb111..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ArrayFieldNode.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.ArrayReference; -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Specialized {@link VariableNode} for representing single fields in an array. - * Overrides {@link #setValue} to properly change the value of the encapsulated - * array field. - * - * @author Martin Leopold - */ -public class ArrayFieldNode extends VariableNode { - - protected ArrayReference array; - protected int index; - - /** - * Construct an {@link ArrayFieldNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param array a reference to the array - * @param index the index inside the array - */ - public ArrayFieldNode(String name, String type, Value value, ArrayReference array, int index) { - super(name, type, value); - this.array = array; - this.index = index; - } - - @Override - public void setValue(Value value) { - try { - array.setValue(index, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(ArrayFieldNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(ArrayFieldNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/ClassLoadListener.java b/pdex/experimental/src/processing/mode/experimental/ClassLoadListener.java deleted file mode 100755 index 64bd5516b..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ClassLoadListener.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.ReferenceType; - -/** - * Listener to be notified when a class is loaded in the debugger. Used by - * {@link LineBreakpoint}s to activate themselves as soon as the respective - * class is loaded. - * - * @author Martin Leopold - */ -public interface ClassLoadListener { - - /** - * Event handler called when a class is loaded. - * - * @param theClass the class - */ - public void classLoaded(ReferenceType theClass); -} diff --git a/pdex/experimental/src/processing/mode/experimental/Compiler.java b/pdex/experimental/src/processing/mode/experimental/Compiler.java deleted file mode 100755 index 1a85c6a29..000000000 --- a/pdex/experimental/src/processing/mode/experimental/Compiler.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.io.*; -import java.lang.reflect.Method; -import processing.app.Base; -import processing.app.SketchException; -import processing.core.PApplet; - -/** - * Copied from processing.mode.java.Compiler, just added -g switch to generate - * debugging info. - * - * @author Martin Leopold - */ -public class Compiler extends processing.mode.java.Compiler { - /** - * Compile with ECJ. See http://j.mp/8paifz for documentation. - * - * @return true if successful. - * @throws RunnerException Only if there's a problem. Only then. - */ -// public boolean compile(Sketch sketch, -// File srcFolder, -// File binFolder, -// String primaryClassName, -// String sketchClassPath, -// String bootClassPath) throws RunnerException { - static public boolean compile(DebugBuild build) throws SketchException { - - // This will be filled in if anyone gets angry - SketchException exception = null; - boolean success = false; - - String baseCommand[] = new String[] { - "-g", - "-Xemacs", - //"-noExit", // not necessary for ecj - "-source", "1.6", - "-target", "1.6", - "-classpath", build.getClassPath(), - "-nowarn", // we're not currently interested in warnings (works in ecj) - "-d", build.getBinFolder().getAbsolutePath() // output the classes in the buildPath - }; - //PApplet.println(baseCommand); - - // make list of code files that need to be compiled -// String[] sourceFiles = new String[sketch.getCodeCount()]; -// int sourceCount = 0; -// sourceFiles[sourceCount++] = -// new File(buildPath, primaryClassName + ".java").getAbsolutePath(); -// -// for (SketchCode code : sketch.getCode()) { -// if (code.isExtension("java")) { -// String path = new File(buildPath, code.getFileName()).getAbsolutePath(); -// sourceFiles[sourceCount++] = path; -// } -// } - String[] sourceFiles = Base.listFiles(build.getSrcFolder(), false, ".java"); - -// String[] command = new String[baseCommand.length + sourceFiles.length]; -// System.arraycopy(baseCommand, 0, command, 0, baseCommand.length); -// // append each of the files to the command string -// System.arraycopy(sourceFiles, 0, command, baseCommand.length, sourceCount); - String[] command = PApplet.concat(baseCommand, sourceFiles); - - //PApplet.println(command); - - try { - // Load errors into a local StringBuffer - final StringBuffer errorBuffer = new StringBuffer(); - - // Create single method dummy writer class to slurp errors from ecj - Writer internalWriter = new Writer() { - public void write(char[] buf, int off, int len) { - errorBuffer.append(buf, off, len); - } - - public void flush() { } - - public void close() { } - }; - // Wrap as a PrintWriter since that's what compile() wants - PrintWriter writer = new PrintWriter(internalWriter); - - //result = com.sun.tools.javac.Main.compile(command, writer); - - PrintWriter outWriter = new PrintWriter(System.out); - - // Version that's not dynamically loaded - //CompilationProgress progress = null; - //success = BatchCompiler.compile(command, outWriter, writer, progress); - - // Version that *is* dynamically loaded. First gets the mode class loader - // so that it can grab the compiler JAR files from it. - ClassLoader loader = build.getMode().getJavaModeClassLoader(); - //ClassLoader loader = build.getMode().getClassLoader(); - try { - Class batchClass = - Class.forName("org.eclipse.jdt.core.compiler.batch.BatchCompiler", false, loader); - Class progressClass = - Class.forName("org.eclipse.jdt.core.compiler.CompilationProgress", false, loader); - Class[] compileArgs = - new Class[] { String[].class, PrintWriter.class, PrintWriter.class, progressClass }; - Method compileMethod = batchClass.getMethod("compile", compileArgs); - success = (Boolean) - compileMethod.invoke(null, new Object[] { command, outWriter, writer, null }); - } catch (Exception e) { - e.printStackTrace(); - throw new SketchException("Unknown error inside the compiler."); - } - - // Close out the stream for good measure - writer.flush(); - writer.close(); - - BufferedReader reader = - new BufferedReader(new StringReader(errorBuffer.toString())); - //System.err.println(errorBuffer.toString()); - - String line = null; - while ((line = reader.readLine()) != null) { - //System.out.println("got line " + line); // debug - - // get first line, which contains file name, line number, - // and at least the first line of the error message - String errorFormat = "([\\w\\d_]+.java):(\\d+):\\s*(.*):\\s*(.*)\\s*"; - String[] pieces = PApplet.match(line, errorFormat); - //PApplet.println(pieces); - - // if it's something unexpected, die and print the mess to the console - if (pieces == null) { - exception = new SketchException("Cannot parse error text: " + line); - exception.hideStackTrace(); - // Send out the rest of the error message to the console. - System.err.println(line); - while ((line = reader.readLine()) != null) { - System.err.println(line); - } - break; - } - - // translate the java filename and line number into a un-preprocessed - // location inside a source file or tab in the environment. - String dotJavaFilename = pieces[1]; - // Line numbers are 1-indexed from javac - int dotJavaLineIndex = PApplet.parseInt(pieces[2]) - 1; - String errorMessage = pieces[4]; - - exception = build.placeException(errorMessage, - dotJavaFilename, - dotJavaLineIndex); - /* - int codeIndex = 0; //-1; - int codeLine = -1; - - // first check to see if it's a .java file - for (int i = 0; i < sketch.getCodeCount(); i++) { - SketchCode code = sketch.getCode(i); - if (code.isExtension("java")) { - if (dotJavaFilename.equals(code.getFileName())) { - codeIndex = i; - codeLine = dotJavaLineIndex; - } - } - } - - // if it's not a .java file, codeIndex will still be 0 - if (codeIndex == 0) { // main class, figure out which tab - //for (int i = 1; i < sketch.getCodeCount(); i++) { - for (int i = 0; i < sketch.getCodeCount(); i++) { - SketchCode code = sketch.getCode(i); - - if (code.isExtension("pde")) { - if (code.getPreprocOffset() <= dotJavaLineIndex) { - codeIndex = i; - //System.out.println("i'm thinkin file " + i); - codeLine = dotJavaLineIndex - code.getPreprocOffset(); - } - } - } - } - //System.out.println("code line now " + codeLine); - exception = new RunnerException(errorMessage, codeIndex, codeLine, -1, false); - */ - - if (exception == null) { - exception = new SketchException(errorMessage); - } - - // for a test case once message parsing is implemented, - // use new Font(...) since that wasn't getting picked up properly. - - /* - if (errorMessage.equals("cannot find symbol")) { - handleCannotFindSymbol(reader, exception); - - } else if (errorMessage.indexOf("is already defined") != -1) { - reader.readLine(); // repeats the line of code w/ error - int codeColumn = caretColumn(reader.readLine()); - exception = new RunnerException(errorMessage, - codeIndex, codeLine, codeColumn); - - } else if (errorMessage.startsWith("package") && - errorMessage.endsWith("does not exist")) { - // Because imports are stripped out and re-added to the 0th line of - // the preprocessed code, codeLine will always be wrong for imports. - exception = new RunnerException("P" + errorMessage.substring(1) + - ". You might be missing a library."); - } else { - exception = new RunnerException(errorMessage); - } - */ - if (errorMessage.startsWith("The import ") && - errorMessage.endsWith("cannot be resolved")) { - // The import poo cannot be resolved - //import poo.shoe.blah.*; - //String what = errorMessage.substring("The import ".length()); - String[] m = PApplet.match(errorMessage, "The import (.*) cannot be resolved"); - //what = what.substring(0, what.indexOf(' ')); - if (m != null) { -// System.out.println("'" + m[1] + "'"); - if (m[1].equals("processing.xml")) { - exception.setMessage("processing.xml no longer exists, this code needs to be updated for 2.0."); - System.err.println("The processing.xml library has been replaced " + - "with a new 'XML' class that's built-in."); - handleCrustyCode(); - - } else { - exception.setMessage("The package " + - "\u201C" + m[1] + "\u201D" + - " does not exist. " + - "You might be missing a library."); - System.err.println("Libraries must be " + - "installed in a folder named 'libraries' " + - "inside the 'sketchbook' folder."); - } - } - -// // Actually create the folder and open it for the user -// File sketchbookLibraries = Base.getSketchbookLibrariesFolder(); -// if (!sketchbookLibraries.exists()) { -// if (sketchbookLibraries.mkdirs()) { -// Base.openFolder(sketchbookLibraries); -// } -// } - - } else if (errorMessage.endsWith("cannot be resolved to a type")) { - // xxx cannot be resolved to a type - //xxx c; - - String what = errorMessage.substring(0, errorMessage.indexOf(' ')); - - if (what.equals("BFont") || - what.equals("BGraphics") || - what.equals("BImage")) { - exception.setMessage(what + " has been replaced with P" + what.substring(1)); - handleCrustyCode(); - - } else { - exception.setMessage("Cannot find a class or type " + - "named \u201C" + what + "\u201D"); - } - - } else if (errorMessage.endsWith("cannot be resolved")) { - // xxx cannot be resolved - //println(xxx); - - String what = errorMessage.substring(0, errorMessage.indexOf(' ')); - - if (what.equals("LINE_LOOP") || - what.equals("LINE_STRIP")) { - exception.setMessage("LINE_LOOP and LINE_STRIP are not available, " + - "please update your code."); - handleCrustyCode(); - - } else if (what.equals("framerate")) { - exception.setMessage("framerate should be changed to frameRate."); - handleCrustyCode(); - - } else if (what.equals("screen")) { - exception.setMessage("Change screen.width and screen.height to " + - "displayWidth and displayHeight."); - handleCrustyCode(); - - } else if (what.equals("screenWidth") || - what.equals("screenHeight")) { - exception.setMessage("Change screenWidth and screenHeight to " + - "displayWidth and displayHeight."); - handleCrustyCode(); - - } else { - exception.setMessage("Cannot find anything " + - "named \u201C" + what + "\u201D"); - } - - } else if (errorMessage.startsWith("Duplicate")) { - // "Duplicate nested type xxx" - // "Duplicate local variable xxx" - - } else { - String[] parts = null; - - // The method xxx(String) is undefined for the type Temporary_XXXX_XXXX - //xxx("blah"); - // The method xxx(String, int) is undefined for the type Temporary_XXXX_XXXX - //xxx("blah", 34); - // The method xxx(String, int) is undefined for the type PApplet - //PApplet.sub("ding"); - String undefined = - "The method (\\S+\\(.*\\)) is undefined for the type (.*)"; - parts = PApplet.match(errorMessage, undefined); - if (parts != null) { - if (parts[1].equals("framerate(int)")) { - exception.setMessage("framerate() no longer exists, use frameRate() instead."); - handleCrustyCode(); - - } else if (parts[1].equals("push()")) { - exception.setMessage("push() no longer exists, use pushMatrix() instead."); - handleCrustyCode(); - - } else if (parts[1].equals("pop()")) { - exception.setMessage("pop() no longer exists, use popMatrix() instead."); - handleCrustyCode(); - - } else { - String mess = "The function " + parts[1] + " does not exist."; - exception.setMessage(mess); - } - break; - } - } - if (exception != null) { - // The stack trace just shows that this happened inside the compiler, - // which is a red herring. Don't ever show it for compiler stuff. - exception.hideStackTrace(); - break; - } - } - } catch (IOException e) { - String bigSigh = "Error while compiling. (" + e.getMessage() + ")"; - exception = new SketchException(bigSigh); - e.printStackTrace(); - success = false; - } - // In case there was something else. - if (exception != null) throw exception; - - return success; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/CompletionCandidate.java b/pdex/experimental/src/processing/mode/experimental/CompletionCandidate.java deleted file mode 100644 index 4ff73400f..000000000 --- a/pdex/experimental/src/processing/mode/experimental/CompletionCandidate.java +++ /dev/null @@ -1,130 +0,0 @@ -package processing.mode.experimental; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.List; - -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.MethodDeclaration; - -public class CompletionCandidate implements Comparable{ - - private String definingClass; - - private String elementName; // - - private String label; // the toString value - - private String completionString; - - private int type; - - public static final int METHOD = 0, FIELD = 1, LOCAL_VAR = 3; - - public CompletionCandidate(String name, String className, String label, - int TYPE) { - definingClass = className; - elementName = name; - if (label.length() > 0) - this.label = label; - else - this.label = name; - this.type = TYPE; - if (type == METHOD) { - this.label += "()"; - } - completionString = this.label; - } - - public CompletionCandidate(Method method) { - definingClass = method.getDeclaringClass().getName(); - elementName = method.getName(); - type = METHOD; - StringBuffer label = new StringBuffer(method.getName() + "("); - StringBuffer cstr = new StringBuffer(method.getName() + "("); - for (int i = 0; i < method.getParameterTypes().length; i++) { - label.append(method.getParameterTypes()[i].getSimpleName()); - if (i < method.getParameterTypes().length - 1) { - label.append(","); - cstr.append(","); - } - } - - label.append(")"); - cstr.append(")"); - this.label = label.toString(); - this.completionString = cstr.toString(); - } - - public CompletionCandidate(MethodDeclaration method) { - definingClass = ""; - elementName = method.getName().toString(); - type = METHOD; - List params = (List) method - .getStructuralProperty(MethodDeclaration.PARAMETERS_PROPERTY); - StringBuffer label = new StringBuffer(elementName + "("); - StringBuffer cstr = new StringBuffer(method.getName() + "("); - for (int i = 0; i < params.size(); i++) { - label.append(params.get(i).toString()); - if (i < params.size() - 1){ - label.append(","); - cstr.append(","); - } - } - label.append(")"); - cstr.append(")"); - this.label = label.toString(); - this.completionString = cstr.toString(); - } - - public CompletionCandidate(Field f) { - definingClass = f.getDeclaringClass().getName(); - elementName = f.getName(); - type = FIELD; - label = f.getName(); - completionString = elementName; - } - - public CompletionCandidate(String name, String className) { - definingClass = className; - elementName = name; - label = name; - completionString = name; - } - - public CompletionCandidate(String name) { - definingClass = ""; - elementName = name; - label = name; - completionString = name; - } - - public String getDefiningClass() { - return definingClass; - } - - public String getElementName() { - return elementName; - } - - public String getCompletionString() { - return completionString; - } - - public String toString() { - return label; - } - - public int getType() { - return type; - } - - public int compareTo(CompletionCandidate cc) { - if(type != cc.getType()){ - return cc.getType() - type; - } - - return (elementName.compareTo(cc.getElementName())); - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/CompletionPanel.java b/pdex/experimental/src/processing/mode/experimental/CompletionPanel.java deleted file mode 100644 index 3e0f7678d..000000000 --- a/pdex/experimental/src/processing/mode/experimental/CompletionPanel.java +++ /dev/null @@ -1,153 +0,0 @@ -package processing.mode.experimental; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Point; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - -import javax.swing.BorderFactory; -import javax.swing.JList; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.ListSelectionModel; -import javax.swing.text.BadLocationException; - -import processing.app.syntax.JEditTextArea; - -public class CompletionPanel { - private JList list; - - private JPopupMenu popupMenu; - - private String subWord; - - private final int insertionPosition; - - private TextArea textarea; - - private JScrollPane scrollPane; - - public CompletionPanel(JEditTextArea textarea, int position, String subWord, - CompletionCandidate[] items, Point location) { - this.textarea = (TextArea) textarea; - this.insertionPosition = position; - if (subWord.indexOf('.') != -1) - this.subWord = subWord.substring(subWord.lastIndexOf('.') + 1); - else - this.subWord = subWord; - popupMenu = new JPopupMenu(); - popupMenu.removeAll(); - popupMenu.setOpaque(false); - popupMenu.setBorder(null); - scrollPane = new JScrollPane(); - scrollPane.setViewportView(list = createSuggestionList(position, items)); - popupMenu.add(scrollPane, BorderLayout.CENTER); - this.textarea.errorCheckerService.astGenerator - .updateJavaDoc((CompletionCandidate) list.getSelectedValue()); - popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0) - + location.y); - - } - - public void hide() { - popupMenu.setVisible(false); - } - - public boolean isVisible() { - return popupMenu.isVisible(); - } - - public JList createSuggestionList(final int position, - final CompletionCandidate[] items) { - - JList list = new JList(items); - list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1)); - list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - list.setSelectedIndex(0); - list.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - insertSelection(); - hideSuggestion(); - } - } - }); - return list; - } - - public boolean insertSelection() { - if (list.getSelectedValue() != null) { - try { - final String selectedSuggestion = ((CompletionCandidate) list - .getSelectedValue()).getCompletionString().substring(subWord.length()); - textarea.getDocument().insertString(insertionPosition, - selectedSuggestion, null); - textarea.setCaretPosition(insertionPosition - + selectedSuggestion.length()); - return true; - } catch (BadLocationException e1) { - e1.printStackTrace(); - } - hideSuggestion(); - } - return false; - } - - public void hideSuggestion() { - hide(); - //textarea.errorCheckerService.astGenerator.jdocWindowVisible(false); - } - - public void moveUp() { - if (list.getSelectedIndex() == 0) { - scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum()); - selectIndex(list.getModel().getSize() - 1); - return; - } else { - int index = Math.max(list.getSelectedIndex() - 1, 0); - selectIndex(index); - } - int step = scrollPane.getVerticalScrollBar().getMaximum() - / list.getModel().getSize(); - scrollPane.getVerticalScrollBar().setValue(scrollPane - .getVerticalScrollBar() - .getValue() - - step); - textarea.errorCheckerService.astGenerator - .updateJavaDoc((CompletionCandidate) list.getSelectedValue()); - - } - - public void moveDown() { - if (list.getSelectedIndex() == list.getModel().getSize() - 1) { - scrollPane.getVerticalScrollBar().setValue(0); - selectIndex(0); - return; - } else { - int index = Math.min(list.getSelectedIndex() + 1, list.getModel() - .getSize() - 1); - selectIndex(index); - } - textarea.errorCheckerService.astGenerator - .updateJavaDoc((CompletionCandidate) list.getSelectedValue()); - int step = scrollPane.getVerticalScrollBar().getMaximum() - / list.getModel().getSize(); - scrollPane.getVerticalScrollBar().setValue(scrollPane - .getVerticalScrollBar() - .getValue() - + step); - } - - private void selectIndex(int index) { - list.setSelectedIndex(index); -// final int position = textarea.getCaretPosition(); -// SwingUtilities.invokeLater(new Runnable() { -// @Override -// public void run() { -// textarea.setCaretPosition(position); -// }; -// }); - } -} \ No newline at end of file diff --git a/pdex/experimental/src/processing/mode/experimental/DebugBuild.java b/pdex/experimental/src/processing/mode/experimental/DebugBuild.java deleted file mode 100755 index fdb9b34e3..000000000 --- a/pdex/experimental/src/processing/mode/experimental/DebugBuild.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.io.File; -import processing.app.Sketch; -import processing.app.SketchException; -import processing.mode.java.JavaBuild; - -/** - * Copied from processing.mode.java.JavaBuild, just changed compiler. - * - * @author Martin Leopold - */ -public class DebugBuild extends JavaBuild { - - public DebugBuild(Sketch sketch) { - super(sketch); - } - - /** - * Preprocess and compile sketch. Copied from - * processing.mode.java.JavaBuild, just changed compiler. - * - * @param srcFolder - * @param binFolder - * @param sizeWarning - * @return main class name or null on compile failure - * @throws SketchException - */ - @Override - public String build(File srcFolder, File binFolder, boolean sizeWarning) throws SketchException { - this.srcFolder = srcFolder; - this.binFolder = binFolder; - -// Base.openFolder(srcFolder); -// Base.openFolder(binFolder); - - // run the preprocessor - String classNameFound = preprocess(srcFolder, sizeWarning); - - // compile the program. errors will happen as a RunnerException - // that will bubble up to whomever called build(). -// Compiler compiler = new Compiler(this); -// String bootClasses = System.getProperty("sun.boot.class.path"); -// if (compiler.compile(this, srcFolder, binFolder, primaryClassName, getClassPath(), bootClasses)) { - - if (Compiler.compile(this)) { // use compiler with debug info enabled (-g switch flicked) - sketchClassName = classNameFound; - return classNameFound; - } - return null; - } - - public ExperimentalMode getMode() { - return (ExperimentalMode)mode; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/DebugEditor.java b/pdex/experimental/src/processing/mode/experimental/DebugEditor.java deleted file mode 100755 index 099e90d1a..000000000 --- a/pdex/experimental/src/processing/mode/experimental/DebugEditor.java +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Color; -import java.awt.EventQueue; -import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.swing.Box; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.border.EtchedBorder; -import javax.swing.table.TableModel; -import javax.swing.text.Document; -import processing.app.*; -import processing.app.syntax.JEditTextArea; -import processing.app.syntax.PdeTextAreaDefaults; -import processing.core.PApplet; -import processing.mode.java.JavaEditor; - -/** - * Main View Class. Handles the editor window including tool bar and menu. Has - * access to the Sketch. Provides line highlighting (for breakpoints and the - * debuggers current line). - * - * @author Martin Leopold - * @author Manindra Moharana <me@mkmoharana.com> - * - * - */ -public class DebugEditor extends JavaEditor implements ActionListener { - // important fields from superclass - //protected Sketch sketch; - //private JMenu fileMenu; - //protected EditorToolbar toolbar; - - // highlighting - protected Color breakpointColor = new Color(240, 240, 240); // the background color for highlighting lines - protected Color currentLineColor = new Color(255, 255, 150); // the background color for highlighting lines - protected Color breakpointMarkerColor = new Color(74, 84, 94); // the color of breakpoint gutter markers - protected Color currentLineMarkerColor = new Color(226, 117, 0); // the color of current line gutter markers - protected List breakpointedLines = new ArrayList(); // breakpointed lines - protected LineHighlight currentLine; // line the debugger is currently suspended at - protected final String breakpointMarkerComment = " //<>//"; // breakpoint marker comment - // menus - protected JMenu debugMenu; // the debug menu - // debugger control - protected JMenuItem debugMenuItem; - protected JMenuItem continueMenuItem; - protected JMenuItem stopMenuItem; - // breakpoints - protected JMenuItem toggleBreakpointMenuItem; - protected JMenuItem listBreakpointsMenuItem; - // stepping - protected JMenuItem stepOverMenuItem; - protected JMenuItem stepIntoMenuItem; - protected JMenuItem stepOutMenuItem; - // info - protected JMenuItem printStackTraceMenuItem; - protected JMenuItem printLocalsMenuItem; - protected JMenuItem printThisMenuItem; - protected JMenuItem printSourceMenuItem; - protected JMenuItem printThreads; - // variable inspector - protected JMenuItem toggleVariableInspectorMenuItem; - // references - protected ExperimentalMode dmode; // the mode - protected Debugger dbg; // the debugger - protected VariableInspector vi; // the variable inspector frame - protected TextArea ta; // the text area - - - protected ErrorBar errorBar; - /** - * Show Console button - */ - protected XQConsoleToggle btnShowConsole; - - /** - * Show Problems button - */ - protected XQConsoleToggle btnShowErrors; - - /** - * Scroll pane for Error Table - */ - protected JScrollPane errorTableScrollPane; - - /** - * Panel with card layout which contains the p5 console and Error Table - * panes - */ - protected JPanel consoleProblemsPane; - - protected XQErrorTable errorTable; - - /** - * Enable/Disable compilation checking - */ - protected boolean compilationCheckEnabled = true; - - /** - * Show warnings menu item - */ - protected JCheckBoxMenuItem showWarnings; - - /** - * Check box menu item for show/hide Problem Window - */ - public JCheckBoxMenuItem problemWindowMenuCB; - - public DebugEditor(Base base, String path, EditorState state, Mode mode) { - super(base, path, state, mode); - - // get mode - dmode = (ExperimentalMode) mode; - - // init controller class - dbg = new Debugger(this); - - // variable inspector window - vi = new VariableInspector(this); - - // access to customized (i.e. subclassed) text area - ta = (TextArea) textarea; - - // add refactor option - JMenuItem renameItem = new JMenuItem("Rename.."); - renameItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - handleRefactor(); - } - }); - // TODO: Add support for word select on right click and rename. -// ta.customPainter.addMouseListener(new MouseAdapter() { -// public void mouseClicked(MouseEvent evt) { -// System.out.println(evt); -// } -// }); - ta.getRightClickPopup().add(renameItem); - // set action on frame close -// addWindowListener(new WindowAdapter() { -// @Override -// public void windowClosing(WindowEvent e) { -// onWindowClosing(e); -// } -// }); - - // load settings from theme.txt - ExperimentalMode theme = dmode; - breakpointColor = theme.getThemeColor("breakpoint.bgcolor", breakpointColor); - breakpointMarkerColor = theme.getThemeColor("breakpoint.marker.color", breakpointMarkerColor); - currentLineColor = theme.getThemeColor("currentline.bgcolor", currentLineColor); - currentLineMarkerColor = theme.getThemeColor("currentline.marker.color", currentLineMarkerColor); - - // set breakpoints from marker comments - for (LineID lineID : stripBreakpointComments()) { - //System.out.println("setting: " + lineID); - dbg.setBreakpoint(lineID); - } - getSketch().setModified(false); // setting breakpoints will flag sketch as modified, so override this here - - checkForJavaTabs(); - initializeErrorChecker(); - ta.setECSandThemeforTextArea(errorCheckerService, dmode); - addXQModeUI(); - //TODO: Remove this later - setBounds(160, 300, getWidth(), getHeight()); - } - - private void addXQModeUI(){ - - // Adding ErrorBar - JPanel textAndError = new JPanel(); - Box box = (Box) textarea.getParent(); - box.remove(2); // Remove textArea from it's container, i.e Box - textAndError.setLayout(new BorderLayout()); - errorBar = new ErrorBar(this, textarea.getMinimumSize().height, dmode); - textAndError.add(errorBar, BorderLayout.EAST); - textarea.setBounds(0, 0, errorBar.getX() - 1, textarea.getHeight()); - textAndError.add(textarea); - box.add(textAndError); - - // Adding Error Table in a scroll pane - errorTableScrollPane = new JScrollPane(); - errorTable = new XQErrorTable(errorCheckerService); - // errorTableScrollPane.setBorder(new EmptyBorder(2, 2, 2, 2)); - errorTableScrollPane.setBorder(new EtchedBorder()); - errorTableScrollPane.setViewportView(errorTable); - - // Adding toggle console button - consolePanel.remove(2); - JPanel lineStatusPanel = new JPanel(); - lineStatusPanel.setLayout(new BorderLayout()); - btnShowConsole = new XQConsoleToggle(this, - XQConsoleToggle.text[0], lineStatus.getHeight()); - btnShowErrors = new XQConsoleToggle(this, - XQConsoleToggle.text[1], lineStatus.getHeight()); - btnShowConsole.addMouseListener(btnShowConsole); - - // lineStatusPanel.add(btnShowConsole, BorderLayout.EAST); - // lineStatusPanel.add(btnShowErrors); - btnShowErrors.addMouseListener(btnShowErrors); - - JPanel toggleButtonPanel = new JPanel(new BorderLayout()); - toggleButtonPanel.add(btnShowConsole, BorderLayout.EAST); - toggleButtonPanel.add(btnShowErrors, BorderLayout.WEST); - lineStatusPanel.add(toggleButtonPanel, BorderLayout.EAST); - lineStatus.setBounds(0, 0, toggleButtonPanel.getX() - 1, - toggleButtonPanel.getHeight()); - lineStatusPanel.add(lineStatus); - consolePanel.add(lineStatusPanel, BorderLayout.SOUTH); - lineStatusPanel.repaint(); - - // Adding JPanel with CardLayout for Console/Problems Toggle - consolePanel.remove(1); - consoleProblemsPane = new JPanel(new CardLayout()); - consoleProblemsPane.add(errorTableScrollPane, XQConsoleToggle.text[1]); - consoleProblemsPane.add(console, XQConsoleToggle.text[0]); - consolePanel.add(consoleProblemsPane, BorderLayout.CENTER); - } - -// /** -// * Event handler called when closing the editor window. Kills the variable -// * inspector window. -// * -// * @param e the event object -// */ -// protected void onWindowClosing(WindowEvent e) { -// // remove var.inspector -// vi.dispose(); -// // quit running debug session -// dbg.stopDebug(); -// } - /** - * Used instead of the windowClosing event handler, since it's not called on - * mode switch. Called when closing the editor window. Stops running debug - * sessions and kills the variable inspector window. - */ - @Override - public void dispose() { - //System.out.println("window dispose"); - // quit running debug session - dbg.stopDebug(); - // remove var.inspector - vi.dispose(); - // original dispose - super.dispose(); - } - - /** - * Overrides sketch menu creation to change keyboard shortcuts from "Run". - * - * @return the sketch menu - */ - @Override - public JMenu buildSketchMenu() { - JMenuItem runItem = Toolkit.newJMenuItemShift(DebugToolbar.getTitle(DebugToolbar.RUN, false), KeyEvent.VK_R); - runItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - handleRun(); - } - }); - - JMenuItem presentItem = new JMenuItem(DebugToolbar.getTitle(DebugToolbar.RUN, true)); - presentItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - handlePresent(); - } - }); - - JMenuItem stopItem = new JMenuItem(DebugToolbar.getTitle(DebugToolbar.STOP, false)); - stopItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - handleStop(); - } - }); - return buildSketchMenu(new JMenuItem[]{runItem, presentItem, stopItem}); - } - - /** - * Creates the debug menu. Includes ActionListeners for the menu items. - * Intended for adding to the menu bar. - * - * @return The debug menu - */ - protected JMenu buildDebugMenu() { - debugMenu = new JMenu("Debug"); - - debugMenuItem = Toolkit.newJMenuItem("Debug", KeyEvent.VK_R); - debugMenuItem.addActionListener(this); - continueMenuItem = Toolkit.newJMenuItem("Continue", KeyEvent.VK_U); - continueMenuItem.addActionListener(this); - stopMenuItem = new JMenuItem("Stop"); - stopMenuItem.addActionListener(this); - - toggleBreakpointMenuItem = Toolkit.newJMenuItem("Toggle Breakpoint", KeyEvent.VK_B); - toggleBreakpointMenuItem.addActionListener(this); - listBreakpointsMenuItem = new JMenuItem("List Breakpoints"); - listBreakpointsMenuItem.addActionListener(this); - - stepOverMenuItem = Toolkit.newJMenuItem("Step", KeyEvent.VK_J); - stepOverMenuItem.addActionListener(this); - stepIntoMenuItem = Toolkit.newJMenuItemShift("Step Into", KeyEvent.VK_J); - stepIntoMenuItem.addActionListener(this); - stepOutMenuItem = Toolkit.newJMenuItemAlt("Step Out", KeyEvent.VK_J); - stepOutMenuItem.addActionListener(this); - - printStackTraceMenuItem = new JMenuItem("Print Stack Trace"); - printStackTraceMenuItem.addActionListener(this); - printLocalsMenuItem = new JMenuItem("Print Locals"); - printLocalsMenuItem.addActionListener(this); - printThisMenuItem = new JMenuItem("Print Fields"); - printThisMenuItem.addActionListener(this); - printSourceMenuItem = new JMenuItem("Print Source Location"); - printSourceMenuItem.addActionListener(this); - printThreads = new JMenuItem("Print Threads"); - printThreads.addActionListener(this); - - toggleVariableInspectorMenuItem = Toolkit.newJMenuItem("Toggle Variable Inspector", KeyEvent.VK_I); - toggleVariableInspectorMenuItem.addActionListener(this); - - debugMenu.add(debugMenuItem); - debugMenu.add(continueMenuItem); - debugMenu.add(stopMenuItem); - debugMenu.addSeparator(); - debugMenu.add(toggleBreakpointMenuItem); - debugMenu.add(listBreakpointsMenuItem); - debugMenu.addSeparator(); - debugMenu.add(stepOverMenuItem); - debugMenu.add(stepIntoMenuItem); - debugMenu.add(stepOutMenuItem); - debugMenu.addSeparator(); - debugMenu.add(printStackTraceMenuItem); - debugMenu.add(printLocalsMenuItem); - debugMenu.add(printThisMenuItem); - debugMenu.add(printSourceMenuItem); - debugMenu.add(printThreads); - debugMenu.addSeparator(); - debugMenu.add(toggleVariableInspectorMenuItem); - debugMenu.addSeparator(); - - // XQMode menu items - - JCheckBoxMenuItem item; - final DebugEditor thisEditor = this; - item = new JCheckBoxMenuItem("Error Checker Enabled"); - item.setSelected(true); - item.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - - if (!((JCheckBoxMenuItem) e.getSource()).isSelected()) { - // unticked Menu Item - errorCheckerService.pauseThread(); - System.out.println(thisEditor.getSketch().getName() - + " - Error Checker paused."); - errorBar.errorPoints.clear(); - errorCheckerService.problemsList.clear(); - errorCheckerService.updateErrorTable(); - errorCheckerService.updateEditorStatus(); - getTextArea().repaint(); - errorBar.repaint(); - } else { - errorCheckerService.resumeThread(); - System.out.println(thisEditor.getSketch().getName() - + " - Error Checker resumed."); - } - } - }); - debugMenu.add(item); - - problemWindowMenuCB = new JCheckBoxMenuItem("Show Problem Window"); - // problemWindowMenuCB.setSelected(true); - problemWindowMenuCB.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (errorCheckerService.errorWindow == null) { - return; - } - errorCheckerService.errorWindow - .setVisible(((JCheckBoxMenuItem) e.getSource()) - .isSelected()); - // switch to console, now that Error Window is open - toggleView(XQConsoleToggle.text[0]); - } - }); - debugMenu.add(problemWindowMenuCB); - - showWarnings = new JCheckBoxMenuItem("Warnings Enabled"); - showWarnings.setSelected(true); - showWarnings.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - errorCheckerService.warningsEnabled = ((JCheckBoxMenuItem) e - .getSource()).isSelected(); - } - }); - debugMenu.add(showWarnings); - - - return debugMenu; - } - - @Override - public JMenu buildModeMenu() { - return buildDebugMenu(); - } - - /** - * Callback for menu items. Implementation of Swing ActionListener. - * - * @param ae Action event - */ - @Override - public void actionPerformed(ActionEvent ae) { - //System.out.println("ActionEvent: " + ae.toString()); - - JMenuItem source = (JMenuItem) ae.getSource(); - if (source == debugMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Debug' menu item"); - //dmode.handleDebug(sketch, this); - dbg.startDebug(); - } else if (source == stopMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Stop' menu item"); - //dmode.handleDebug(sketch, this); - dbg.stopDebug(); - } else if (source == continueMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Continue' menu item"); - //dmode.handleDebug(sketch, this); - dbg.continueDebug(); - } else if (source == stepOverMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Step Over' menu item"); - dbg.stepOver(); - } else if (source == stepIntoMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Step Into' menu item"); - dbg.stepInto(); - } else if (source == stepOutMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Step Out' menu item"); - dbg.stepOut(); - } else if (source == printStackTraceMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Print Stack Trace' menu item"); - dbg.printStackTrace(); - } else if (source == printLocalsMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Print Locals' menu item"); - dbg.printLocals(); - } else if (source == printThisMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Print This' menu item"); - dbg.printThis(); - } else if (source == printSourceMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Print Source' menu item"); - dbg.printSource(); - } else if (source == printThreads) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Print Threads' menu item"); - dbg.printThreads(); - } else if (source == toggleBreakpointMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Toggle Breakpoint' menu item"); - dbg.toggleBreakpoint(); - } else if (source == listBreakpointsMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'List Breakpoints' menu item"); - dbg.listBreakpoints(); - } else if (source == toggleVariableInspectorMenuItem) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.INFO, "Invoked 'Toggle Variable Inspector' menu item"); - toggleVariableInspector(); - } - } - -// @Override -// public void handleRun() { -// dbg.continueDebug(); -// } - /** - * Event handler called when hitting the stop button. Stops a running debug - * session or performs standard stop action if not currently debugging. - */ - @Override - public void handleStop() { - if (dbg.isStarted()) { - dbg.stopDebug(); - } else { - super.handleStop(); - } - } - - /** - * Event handler called when loading another sketch in this editor. Clears - * breakpoints of previous sketch. - * - * @param path - * @return true if a sketch was opened, false if aborted - */ - @Override - protected boolean handleOpenInternal(String path) { - boolean didOpen = super.handleOpenInternal(path); - if (didOpen && dbg != null) { - // should already been stopped (open calls handleStop) - dbg.clearBreakpoints(); - clearBreakpointedLines(); // force clear breakpoint highlights - variableInspector().reset(); // clear contents of variable inspector - } - return didOpen; - } - - /** - * Extract breakpointed lines from source code marker comments. This removes - * marker comments from the editor text. Intended to be called on loading a - * sketch, since re-setting the sketches contents after removing the markers - * will clear all breakpoints. - * - * @return the list of {@link LineID}s where breakpoint marker comments were - * removed from. - */ - protected List stripBreakpointComments() { - List bps = new ArrayList(); - // iterate over all tabs - Sketch sketch = getSketch(); - for (int i = 0; i < sketch.getCodeCount(); i++) { - SketchCode tab = sketch.getCode(i); - String code = tab.getProgram(); - String lines[] = code.split("\\r?\\n"); // newlines not included - //System.out.println(code); - - // scan code for breakpoint comments - int lineIdx = 0; - for (String line : lines) { - //System.out.println(line); - if (line.endsWith(breakpointMarkerComment)) { - LineID lineID = new LineID(tab.getFileName(), lineIdx); - bps.add(lineID); - //System.out.println("found breakpoint: " + lineID); - // got a breakpoint - //dbg.setBreakpoint(lineID); - int index = line.lastIndexOf(breakpointMarkerComment); - lines[lineIdx] = line.substring(0, index); - } - lineIdx++; - } - //tab.setProgram(code); - code = PApplet.join(lines, "\n"); - setTabContents(tab.getFileName(), code); - } - return bps; - } - - /** - * Add breakpoint marker comments to the source file of a specific tab. This - * acts on the source file on disk, not the editor text. Intended to be - * called just after saving the sketch. - * - * @param tabFilename the tab file name - */ - protected void addBreakpointComments(String tabFilename) { - SketchCode tab = getTab(tabFilename); - List bps = dbg.getBreakpoints(tab.getFileName()); - - // load the source file - File sourceFile = new File(sketch.getFolder(), tab.getFileName()); - //System.out.println("file: " + sourceFile); - try { - String code = Base.loadFile(sourceFile); - //System.out.println("code: " + code); - String lines[] = code.split("\\r?\\n"); // newlines not included - for (LineBreakpoint bp : bps) { - //System.out.println("adding bp: " + bp.lineID()); - lines[bp.lineID().lineIdx()] += breakpointMarkerComment; - } - code = PApplet.join(lines, "\n"); - //System.out.println("new code: " + code); - Base.saveFile(code, sourceFile); - } catch (IOException ex) { - Logger.getLogger(DebugEditor.class.getName()).log(Level.SEVERE, null, ex); - } - } - - @Override - public boolean handleSave(boolean immediately) { - //System.out.println("handleSave " + immediately); - - // note modified tabs - final List modified = new ArrayList(); - for (int i = 0; i < getSketch().getCodeCount(); i++) { - SketchCode tab = getSketch().getCode(i); - if (tab.isModified()) { - modified.add(tab.getFileName()); - } - } - - boolean saved = super.handleSave(immediately); - if (saved) { - if (immediately) { - for (String tabFilename : modified) { - addBreakpointComments(tabFilename); - } - } else { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - for (String tabFilename : modified) { - addBreakpointComments(tabFilename); - } - } - }); - } - } - return saved; - } - - @Override - public boolean handleSaveAs() { - //System.out.println("handleSaveAs"); - String oldName = getSketch().getCode(0).getFileName(); - //System.out.println("old name: " + oldName); - boolean saved = super.handleSaveAs(); - if (saved) { - // re-set breakpoints in first tab (name has changed) - List bps = dbg.getBreakpoints(oldName); - dbg.clearBreakpoints(oldName); - String newName = getSketch().getCode(0).getFileName(); - //System.out.println("new name: " + newName); - for (LineBreakpoint bp : bps) { - LineID line = new LineID(newName, bp.lineID().lineIdx()); - //System.out.println("setting: " + line); - dbg.setBreakpoint(line); - } - // add breakpoint marker comments to source file - for (int i = 0; i < getSketch().getCodeCount(); i++) { - addBreakpointComments(getSketch().getCode(i).getFileName()); - } - - // set new name of variable inspector - vi.setTitle(getSketch().getName()); - } - return saved; - } - - /** - * Set text contents of a specific tab. Updates underlying document and text - * area. Clears Breakpoints. - * - * @param tabFilename the tab file name - * @param code the text to set - */ - protected void setTabContents(String tabFilename, String code) { - // remove all breakpoints of this tab - dbg.clearBreakpoints(tabFilename); - - SketchCode currentTab = getCurrentTab(); - - // set code of tab - SketchCode tab = getTab(tabFilename); - if (tab != null) { - tab.setProgram(code); - // this updates document and text area - // TODO: does this have any negative effects? (setting the doc to null) - tab.setDocument(null); - setCode(tab); - - // switch back to original tab - setCode(currentTab); - } - } - - /** - * Clear the console. - */ - public void clearConsole() { - console.clear(); - } - - /** - * Clear current text selection. - */ - public void clearSelection() { - setSelection(getCaretOffset(), getCaretOffset()); - } - - /** - * Select a line in the current tab. - * - * @param lineIdx 0-based line number - */ - public void selectLine(int lineIdx) { - setSelection(getLineStartOffset(lineIdx), getLineStopOffset(lineIdx)); - } - - /** - * Set the cursor to the start of a line. - * - * @param lineIdx 0-based line number - */ - public void cursorToLineStart(int lineIdx) { - setSelection(getLineStartOffset(lineIdx), getLineStartOffset(lineIdx)); - } - - /** - * Set the cursor to the end of a line. - * - * @param lineIdx 0-based line number - */ - public void cursorToLineEnd(int lineIdx) { - setSelection(getLineStopOffset(lineIdx), getLineStopOffset(lineIdx)); - } - - /** - * Switch to a tab. - * - * @param tabFileName the file name identifying the tab. (as in - * {@link SketchCode#getFileName()}) - */ - public void switchToTab(String tabFileName) { - Sketch s = getSketch(); - for (int i = 0; i < s.getCodeCount(); i++) { - if (tabFileName.equals(s.getCode(i).getFileName())) { - s.setCurrentCode(i); - break; - } - } - } - - /** - * Access the debugger. - * - * @return the debugger controller object - */ - public Debugger dbg() { - return dbg; - } - - /** - * Access the mode. - * - * @return the mode object - */ - public ExperimentalMode mode() { - return dmode; - } - - /** - * Access the custom text area object. - * - * @return the text area object - */ - public TextArea textArea() { - return ta; - } - - /** - * Access variable inspector window. - * - * @return the variable inspector object - */ - public VariableInspector variableInspector() { - return vi; - } - - public DebugToolbar toolbar() { - return (DebugToolbar) toolbar; - } - - /** - * Show the variable inspector window. - */ - public void showVariableInspector() { - vi.setVisible(true); - } - - /** - * Set visibility of the variable inspector window. - * - * @param visible true to set the variable inspector visible, false for - * invisible. - */ - public void showVariableInspector(boolean visible) { - vi.setVisible(visible); - } - - /** - * Hide the variable inspector window. - */ - public void hideVariableInspector() { - vi.setVisible(true); - } - - /** - * Toggle visibility of the variable inspector window. - */ - public void toggleVariableInspector() { - vi.setFocusableWindowState(false); // to not get focus when set visible - vi.setVisible(!vi.isVisible()); - vi.setFocusableWindowState(true); // allow to get focus again - } - - /** - * Text area factory method. Instantiates the customized TextArea. - * - * @return the customized text area object - */ - @Override - protected JEditTextArea createTextArea() { - //System.out.println("overriding creation of text area"); - return new TextArea(new PdeTextAreaDefaults(mode), this); - } - - /** - * Set the line to highlight as currently suspended at. Will override the - * breakpoint color, if set. Switches to the appropriate tab and scroll to - * the line by placing the cursor there. - * - * @param line the line to highlight as current suspended line - */ - public void setCurrentLine(LineID line) { - clearCurrentLine(); - if (line == null) { - return; // safety, e.g. when no line mapping is found and the null line is used. - } - switchToTab(line.fileName()); - // scroll to line, by setting the cursor - cursorToLineStart(line.lineIdx()); - // highlight line - currentLine = new LineHighlight(line.lineIdx(), currentLineColor, this); - currentLine.setMarker(ta.currentLineMarker, currentLineMarkerColor); - currentLine.setPriority(10); // fixes current line being hidden by the breakpoint when moved down - } - - /** - * Clear the highlight for the debuggers current line. - */ - public void clearCurrentLine() { - if (currentLine != null) { - currentLine.clear(); - currentLine.dispose(); - - // revert to breakpoint color if any is set on this line - for (LineHighlight hl : breakpointedLines) { - if (hl.lineID().equals(currentLine.lineID())) { - hl.paint(); - break; - } - } - currentLine = null; - } - } - - /** - * Add highlight for a breakpointed line. - * - * @param lineID the line id to highlight as breakpointed - */ - public void addBreakpointedLine(LineID lineID) { - LineHighlight hl = new LineHighlight(lineID, breakpointColor, this); - hl.setMarker(ta.breakpointMarker, breakpointMarkerColor); - breakpointedLines.add(hl); - // repaint current line if it's on this line - if (currentLine != null && currentLine.lineID().equals(lineID)) { - currentLine.paint(); - } - } - - /** - * Add highlight for a breakpointed line on the current tab. - * - * @param lineIdx the line index on the current tab to highlight as - * breakpointed - */ - //TODO: remove and replace by {@link #addBreakpointedLine(LineID lineID)} - public void addBreakpointedLine(int lineIdx) { - addBreakpointedLine(getLineIDInCurrentTab(lineIdx)); - } - - /** - * Remove a highlight for a breakpointed line. Needs to be on the current - * tab. - * - * @param lineIdx the line index on the current tab to remove a breakpoint - * highlight from - */ - public void removeBreakpointedLine(int lineIdx) { - LineID line = getLineIDInCurrentTab(lineIdx); - //System.out.println("line id: " + line.fileName() + " " + line.lineIdx()); - LineHighlight foundLine = null; - for (LineHighlight hl : breakpointedLines) { - if (hl.lineID.equals(line)) { - foundLine = hl; - break; - } - } - if (foundLine != null) { - foundLine.clear(); - breakpointedLines.remove(foundLine); - foundLine.dispose(); - // repaint current line if it's on this line - if (currentLine != null && currentLine.lineID().equals(line)) { - currentLine.paint(); - } - } - } - - /** - * Remove all highlights for breakpointed lines. - */ - public void clearBreakpointedLines() { - for (LineHighlight hl : breakpointedLines) { - hl.clear(); - hl.dispose(); - } - breakpointedLines.clear(); // remove all breakpoints - // fix highlights not being removed when tab names have changed due to opening a new sketch in same editor - ta.clearLineBgColors(); // force clear all highlights - ta.clearGutterText(); - - // repaint current line - if (currentLine != null) { - currentLine.paint(); - } - } - - /** - * Retrieve a {@link LineID} object for a line on the current tab. - * - * @param lineIdx the line index on the current tab - * @return the {@link LineID} object representing a line index on the - * current tab - */ - public LineID getLineIDInCurrentTab(int lineIdx) { - return new LineID(getSketch().getCurrentCode().getFileName(), lineIdx); - } - - /** - * Retrieve line of sketch where the cursor currently resides. - * - * @return the current {@link LineID} - */ - protected LineID getCurrentLineID() { - String tab = getSketch().getCurrentCode().getFileName(); - int lineNo = getTextArea().getCaretLine(); - return new LineID(tab, lineNo); - } - - /** - * Check whether a {@link LineID} is on the current tab. - * - * @param line the {@link LineID} - * @return true, if the {@link LineID} is on the current tab. - */ - public boolean isInCurrentTab(LineID line) { - return line.fileName().equals(getSketch().getCurrentCode().getFileName()); - } - - /** - * Event handler called when switching between tabs. Loads all line - * background colors set for the tab. - * - * @param code tab to switch to - */ - @Override - protected void setCode(SketchCode code) { - //System.out.println("tab switch: " + code.getFileName()); - super.setCode(code); // set the new document in the textarea, etc. need to do this first - - // set line background colors for tab - if (ta != null) { // can be null when setCode is called the first time (in constructor) - // clear all line backgrounds - ta.clearLineBgColors(); - // clear all gutter text - ta.clearGutterText(); - // load appropriate line backgrounds for tab - // first paint breakpoints - for (LineHighlight hl : breakpointedLines) { - if (isInCurrentTab(hl.lineID())) { - hl.paint(); - } - } - // now paint current line (if any) - if (currentLine != null) { - if (isInCurrentTab(currentLine.lineID())) { - currentLine.paint(); - } - } - } - if (dbg() != null && dbg().isStarted()) { - dbg().startTrackingLineChanges(); - } - } - - /** - * Get a tab by its file name. - * - * @param fileName the filename to search for. - * @return the {@link SketchCode} object representing the tab, or null if - * not found - */ - public SketchCode getTab(String fileName) { - Sketch s = getSketch(); - for (SketchCode c : s.getCode()) { - if (c.getFileName().equals(fileName)) { - return c; - } - } - return null; - } - - /** - * Retrieve the current tab. - * - * @return the {@link SketchCode} representing the current tab - */ - public SketchCode getCurrentTab() { - return getSketch().getCurrentCode(); - } - - /** - * Access the currently edited document. - * - * @return the document object - */ - public Document currentDocument() { - //return ta.getDocument(); - return getCurrentTab().getDocument(); - } - - /** - * Factory method for the editor toolbar. Instantiates the customized - * toolbar. - * - * @return the toolbar - */ - @Override - public EditorToolbar createToolbar() { - return new DebugToolbar(this, base); - } - - /** - * Event Handler for double clicking in the left hand gutter area. - * - * @param lineIdx the line (0-based) that was double clicked - */ - public void gutterDblClicked(int lineIdx) { - if (dbg != null) { - dbg.toggleBreakpoint(lineIdx); - } - } - - public void statusBusy() { - statusNotice("Debugger busy..."); - } - - public void statusHalted() { - statusNotice("Debugger halted."); - } - - ErrorCheckerService errorCheckerService; - - /** - * Initializes and starts Error Checker Service - */ - private void initializeErrorChecker() { - Thread errorCheckerThread = null; - - if (errorCheckerThread == null) { - errorCheckerService = new ErrorCheckerService(this); - errorCheckerThread = new Thread(errorCheckerService); - try { - errorCheckerThread.start(); - } catch (Exception e) { - System.err - .println("Error Checker Service not initialized [XQEditor]: " - + e); - // e.printStackTrace(); - } - // System.out.println("Error Checker Service initialized."); - } - - } - - /** - * Updates the error bar - * @param problems - */ - public void updateErrorBar(ArrayList problems) { - errorBar.updateErrorPoints(problems); - } - - /** - * Toggle between Console and Errors List - * - * @param buttonName - * - Button Label - */ - public void toggleView(String buttonName) { - CardLayout cl = (CardLayout) consoleProblemsPane.getLayout(); - cl.show(consoleProblemsPane, buttonName); - } - - /** - * Updates the error table - * @param tableModel - * @return - */ - synchronized public boolean updateTable(final TableModel tableModel) { - return errorTable.updateTable(tableModel); - } - - private void handleRefactor() { - System.out.println("Caret at:"); - System.out.println(ta.getLineText(ta.getCaretLine())); - errorCheckerService.astGenerator.handleRefactor(); - } - - /** - * Checks if the sketch contains java tabs. If it does, XQMode ain't built - * for it, yet. Also, user should really start looking at Eclipse. Disable - * compilation check. - */ - private void checkForJavaTabs() { - for (int i = 0; i < this.getSketch().getCodeCount(); i++) { - if (this.getSketch().getCode(i).getExtension().equals("java")) { - compilationCheckEnabled = false; - JOptionPane.showMessageDialog(new Frame(), this - .getSketch().getName() - + " contains .java tabs. Live compilation error checking isn't " - + "supported for java tabs. Only " - + "syntax errors will be reported for .pde tabs."); - break; - } - } - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/DebugRunner.java b/pdex/experimental/src/processing/mode/experimental/DebugRunner.java deleted file mode 100755 index 1f810d964..000000000 --- a/pdex/experimental/src/processing/mode/experimental/DebugRunner.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.VirtualMachine; -import processing.app.RunnerListener; -import processing.app.SketchException; -import processing.app.exec.StreamRedirectThread; -import processing.mode.java.JavaBuild; -import processing.mode.java.runner.MessageSiphon; - -/** - * Runs a {@link JavaBuild}. Launches the build in a new debuggee VM. - * - * @author Martin Leopold - */ -public class DebugRunner extends processing.mode.java.runner.Runner { - - // important inherited fields - // protected VirtualMachine vm; - public DebugRunner(JavaBuild build, RunnerListener listener) throws SketchException { - super(build, listener); - } - - /** - * Launch the virtual machine. Simple non-blocking launch. VM starts - * suspended. - * - * @return debuggee VM or null on failure - */ - public VirtualMachine launch() { -// String[] machineParamList = getMachineParams(); -// String[] sketchParamList = getSketchParams(false); -// /* -// * System.out.println("vm launch sketch params:"); for (int i=0; -// * i - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.awt.Image; -import java.awt.event.MouseEvent; -import java.util.logging.Level; -import java.util.logging.Logger; -import processing.app.Base; -import processing.app.Editor; -import processing.mode.java.JavaToolbar; - -/** - * Custom toolbar for the editor window. Preserves original button numbers - * ({@link JavaToolbar#RUN}, {@link JavaToolbar#STOP}, {@link JavaToolbar#NEW}, - * {@link JavaToolbar#OPEN}, {@link JavaToolbar#SAVE}, {@link JavaToolbar#EXPORT}) - * which can be used e.g. in {@link #activate} and - * {@link #deactivate}. - * - * @author Martin Leopold - */ -public class DebugToolbar extends JavaToolbar { - // preserve original button id's, but re-define so they are accessible - // (they are used by DebugEditor, so they want to be public) - - static protected final int RUN = 100; // change this, to be able to get it's name via getTitle() - static protected final int DEBUG = JavaToolbar.RUN; - - static protected final int CONTINUE = 101; - static protected final int STEP = 102; - static protected final int TOGGLE_BREAKPOINT = 103; - static protected final int TOGGLE_VAR_INSPECTOR = 104; - - static protected final int STOP = JavaToolbar.STOP; - - static protected final int NEW = JavaToolbar.NEW; - static protected final int OPEN = JavaToolbar.OPEN; - static protected final int SAVE = JavaToolbar.SAVE; - static protected final int EXPORT = JavaToolbar.EXPORT; - - - // the sequence of button ids. (this maps button position = index to button ids) - static protected final int[] buttonSequence = { - DEBUG, CONTINUE, STEP, STOP, TOGGLE_BREAKPOINT, TOGGLE_VAR_INSPECTOR, - NEW, OPEN, SAVE, EXPORT - }; - - - public DebugToolbar(Editor editor, Base base) { - super(editor, base); - } - - - /** - * Initialize buttons. Loads images and adds the buttons to the toolbar. - */ - @Override - public void init() { - Image[][] images = loadImages(); - for (int idx = 0; idx < buttonSequence.length; idx++) { - int id = buttonId(idx); - addButton(getTitle(id, false), getTitle(id, true), images[idx], id == NEW || id == TOGGLE_BREAKPOINT); - } - } - - - /** - * Get the title for a toolbar button. Displayed in the toolbar when - * hovering over a button. - * @param id id of the toolbar button - * @param shift true if shift is pressed - * @return the title - */ - public static String getTitle(int id, boolean shift) { - switch (id) { - case DebugToolbar.RUN: - return JavaToolbar.getTitle(JavaToolbar.RUN, shift); - case STOP: - return JavaToolbar.getTitle(JavaToolbar.STOP, shift); - case NEW: - return JavaToolbar.getTitle(JavaToolbar.NEW, shift); - case OPEN: - return JavaToolbar.getTitle(JavaToolbar.OPEN, shift); - case SAVE: - return JavaToolbar.getTitle(JavaToolbar.SAVE, shift); - case EXPORT: - return JavaToolbar.getTitle(JavaToolbar.EXPORT, shift); - case DEBUG: - if (shift) { - return "Run"; - } else { - return "Debug"; - } - case CONTINUE: - return "Continue"; - case TOGGLE_BREAKPOINT: - return "Toggle Breakpoint"; - case STEP: - if (shift) { - return "Step Into"; - } else { - return "Step"; - } - case TOGGLE_VAR_INSPECTOR: - return "Variable Inspector"; - } - return null; - } - - - /** - * Event handler called when a toolbar button is clicked. - * @param e the mouse event - * @param idx index (i.e. position) of the toolbar button clicked - */ - @Override - public void handlePressed(MouseEvent e, int idx) { - boolean shift = e.isShiftDown(); - DebugEditor deditor = (DebugEditor) editor; - int id = buttonId(idx); // convert index/position to button id - - switch (id) { -// case DebugToolbar.RUN: -// super.handlePressed(e, JavaToolbar.RUN); -// break; - case STOP: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Stop' toolbar button"); - super.handlePressed(e, JavaToolbar.STOP); - break; - case NEW: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'New' toolbar button"); - super.handlePressed(e, JavaToolbar.NEW); - break; - case OPEN: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Open' toolbar button"); - super.handlePressed(e, JavaToolbar.OPEN); - break; - case SAVE: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Save' toolbar button"); - super.handlePressed(e, JavaToolbar.SAVE); - break; - case EXPORT: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Export' toolbar button"); - super.handlePressed(e, JavaToolbar.EXPORT); - break; - case DEBUG: - deditor.handleStop(); // Close any running sketches - if (shift) { - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Run' toolbar button"); - deditor.handleRun(); - } else { - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Debug' toolbar button"); - deditor.dbg.startDebug(); - } - break; - case CONTINUE: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Continue' toolbar button"); - deditor.dbg.continueDebug(); - break; - case TOGGLE_BREAKPOINT: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Toggle Breakpoint' toolbar button"); - deditor.dbg.toggleBreakpoint(); - break; - case STEP: - if (shift) { - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Step Into' toolbar button"); - deditor.dbg.stepInto(); - } else { - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Step' toolbar button"); - deditor.dbg.stepOver(); - } - break; -// case STEP_INTO: -// deditor.dbg.stepInto(); -// break; -// case STEP_OUT: -// deditor.dbg.stepOut(); -// break; - case TOGGLE_VAR_INSPECTOR: - Logger.getLogger(DebugToolbar.class.getName()).log(Level.INFO, "Invoked 'Variable Inspector' toolbar button"); - deditor.toggleVariableInspector(); - break; - } - } - - - /** - * Activate (light up) a button. - * @param id the button id - */ - @Override - public void activate(int id) { - //System.out.println("activate button idx: " + buttonIndex(id)); - super.activate(buttonIndex(id)); - } - - - /** - * Set a button to be inactive. - * @param id the button id - */ - @Override - public void deactivate(int id) { - //System.out.println("deactivate button idx: " + buttonIndex(id)); - super.deactivate(buttonIndex(id)); - } - - - /** - * Get button position (index) from it's id. - * @param buttonId the button id - * ({@link #RUN}, {@link #DEBUG}, {@link #CONTINUE}), {@link #STEP}, ...) - * @return the button index - */ - protected int buttonIndex(int buttonId) { - for (int i = 0; i < buttonSequence.length; i++) { - if (buttonSequence[i] == buttonId) { - return i; - } - } - return -1; - } - - - /** - * Get the button id from its position (index). - * @param buttonIdx the button index - * @return the button id - * ({@link #RUN}, {@link #DEBUG}, {@link #CONTINUE}), {@link #STEP}, ...) - */ - protected int buttonId(int buttonIdx) { - return buttonSequence[buttonIdx]; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/Debugger.java b/pdex/experimental/src/processing/mode/experimental/Debugger.java deleted file mode 100755 index 758f6cfae..000000000 --- a/pdex/experimental/src/processing/mode/experimental/Debugger.java +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.*; -import com.sun.jdi.event.*; -import com.sun.jdi.request.*; -import java.io.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.JTree; // needed for javadocs -import javax.swing.tree.DefaultMutableTreeNode; -import processing.app.Sketch; -import processing.app.SketchCode; - -/** - * Main controller class for debugging mode. Mainly works with DebugEditor as - * the corresponding "view". Uses DebugRunner to launch a VM. - * - * @author Martin Leopold - */ -public class Debugger implements VMEventListener { - - protected DebugEditor editor; // editor window, acting as main view - protected DebugRunner runtime; // the runtime, contains debuggee VM - protected boolean started = false; // debuggee vm has started, VMStartEvent received, main class loaded - protected boolean paused = false; // currently paused at breakpoint or step - protected ThreadReference currentThread; // thread the last breakpoint or step occured in - protected String mainClassName; // name of the main class that's currently being debugged - protected ReferenceType mainClass; // the debuggee's main class - protected Set classes = new HashSet(); // holds all loaded classes in the debuggee VM - protected List classLoadListeners = new ArrayList(); // listeners for class load events - protected String srcPath; // path to the src folder of the current build - protected List breakpoints = new ArrayList(); // list of current breakpoints - protected StepRequest requestedStep; // the step request we are currently in, or null if not in a step - protected Map runtimeLineChanges = new HashMap(); // maps line number changes at runtime (orig -> changed) - protected Set runtimeTabsTracked = new HashSet(); // contains tab filenames which already have been tracked for runtime changes - - /** - * Construct a Debugger object. - * - * @param editor The Editor that will act as primary view - */ - public Debugger(DebugEditor editor) { - this.editor = editor; - } - - /** - * Access the VM. - * - * @return the virtual machine object or null if not available. - */ - public VirtualMachine vm() { - if (runtime != null) { - return runtime.vm(); - } else { - return null; - } - } - - /** - * Access the editor associated with this debugger. - * - * @return the editor object - */ - public DebugEditor editor() { - return editor; - } - - /** - * Retrieve the main class of the debuggee VM. - * - * @return the main classes {@link ReferenceType} or null if the debugger is - * not started. - */ - public ReferenceType getMainClass() { - if (isStarted()) { - return mainClass; - } else { - return null; - } - - } - - /** - * Get the {@link ReferenceType} for a class name. - * - * @param name the class name - * @return the {@link ReferenceType} or null if not found (e.g. not yet - * loaded) - */ - public ReferenceType getClass(String name) { - if (name == null) { - return null; - } - if (name.equals(mainClassName)) { - return mainClass; - } - for (ReferenceType rt : classes) { - if (rt.name().equals(name)) { - return rt; - } - } - return null; - } - - /** - * Add a class load listener. Will be notified when a class is loaded in the - * debuggee VM. - * - * @param listener the {@link ClassLoadListener} - */ - public void addClassLoadListener(ClassLoadListener listener) { - classLoadListeners.add(listener); - } - - /** - * Remove a class load listener. Cease to be notified when classes are - * loaded in the debuggee VM. - * - * @param listener {@link ClassLoadListener} - */ - public void removeClassLoadListener(ClassLoadListener listener) { - classLoadListeners.remove(listener); - } - - /** - * Start a debugging session. Builds the sketch and launches a VM to run it. - * VM starts suspended. Should produce a VMStartEvent. - */ - public synchronized void startDebug() { - //stopDebug(); // stop any running sessions - if (isStarted()) { - return; // do nothing - } - - // we are busy now - editor.statusBusy(); - - // clear console - editor.clearConsole(); - - // clear variable inspector (also resets expanded states) - editor.variableInspector().reset(); - - // load edits into sketch obj, etc... - editor.prepareRun(); - - editor.toolbar().activate(DebugToolbar.DEBUG); // after prepareRun, since this removes highlights - - try { - Sketch sketch = editor.getSketch(); - DebugBuild build = new DebugBuild(sketch); - - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "building sketch: {0}", sketch.getName()); - //LineMapping.addLineNumbers(sketch); // annotate - mainClassName = build.build(false); - //LineMapping.removeLineNumbers(sketch); // annotate - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "class: {0}", mainClassName); - - // folder with assembled/preprocessed src - srcPath = build.getSrcFolder().getPath(); - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "build src: {0}", srcPath); - // folder with compiled code (.class files) - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "build bin: {0}", build.getBinFolder().getPath()); - - if (mainClassName != null) { - // generate the source line mapping - //lineMap = LineMapping.generateMapping(srcPath + File.separator + mainClassName + ".java"); - - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "launching debuggee runtime"); - runtime = new DebugRunner(build, editor); - VirtualMachine vm = runtime.launch(); // non-blocking - if (vm == null) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, "error 37: launch failed"); - } - - // start receiving vm events - VMEventReader eventThread = new VMEventReader(vm.eventQueue(), this); - eventThread.start(); - - //return runtime; - - /* - * // launch runner in new thread new Thread(new Runnable() { - * - * @Override public void run() { runtime.launch(false); // this - * blocks until finished } }).start(); return runtime; - */ - - startTrackingLineChanges(); - editor.statusBusy(); - } - } catch (Exception e) { - editor.statusError(e); - } - } - - /** - * End debugging session. Stops and disconnects VM. Should produce - * VMDisconnectEvent. - */ - public synchronized void stopDebug() { - editor.variableInspector().lock(); - if (runtime != null) { - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "closing runtime"); - runtime.close(); - runtime = null; - //build = null; - classes.clear(); - // need to clear highlight here because, VMDisconnectedEvent seems to be unreliable. TODO: likely synchronization problem - editor.clearCurrentLine(); - } - stopTrackingLineChanges(); - started = false; - editor.toolbar().deactivate(DebugToolbar.DEBUG); - editor.toolbar().deactivate(DebugToolbar.CONTINUE); - editor.toolbar().deactivate(DebugToolbar.STEP); - editor.statusEmpty(); - } - - /** - * Resume paused debugging session. Resumes VM. - */ - public synchronized void continueDebug() { - editor.toolbar().activate(DebugToolbar.CONTINUE); - editor.variableInspector().lock(); - //editor.clearSelection(); - //clearHighlight(); - editor.clearCurrentLine(); - if (!isStarted()) { - startDebug(); - } else if (isPaused()) { - runtime.vm().resume(); - paused = false; - editor.statusBusy(); - } - } - - /** - * Step through source code lines. - * - * @param stepDepth the step depth ({@link StepRequest#STEP_OVER}, - * {@link StepRequest#STEP_INTO} or {@link StepRequest#STEP_OUT}) - */ - protected void step(int stepDepth) { - if (!isStarted()) { - startDebug(); - } else if (isPaused()) { - editor.variableInspector().lock(); - editor.toolbar().activate(DebugToolbar.STEP); - - // use global to mark that there is a step request pending - requestedStep = runtime.vm().eventRequestManager().createStepRequest(currentThread, StepRequest.STEP_LINE, stepDepth); - requestedStep.addCountFilter(1); // valid for one step only - requestedStep.enable(); - paused = false; - runtime.vm().resume(); - editor.statusBusy(); - } - } - - /** - * Step over current statement. - */ - public synchronized void stepOver() { - step(StepRequest.STEP_OVER); - } - - /** - * Step into current statement. - */ - public synchronized void stepInto() { - step(StepRequest.STEP_INTO); - } - - /** - * Step out of current function. - */ - public synchronized void stepOut() { - step(StepRequest.STEP_OUT); - } - - /** - * Print the current stack trace. - */ - public synchronized void printStackTrace() { - if (isStarted()) { - printStackTrace(currentThread); - } - } - - /** - * Print local variables. Outputs type, name and value of each variable. - */ - public synchronized void printLocals() { - if (isStarted()) { - printLocalVariables(currentThread); - } - } - - /** - * Print fields of current {@code this}-object. Outputs type, name and value - * of each field. - */ - public synchronized void printThis() { - if (isStarted()) { - printThis(currentThread); - } - } - - /** - * Print a source code snippet of the current location. - */ - public synchronized void printSource() { - if (isStarted()) { - printSourceLocation(currentThread); - } - } - - /** - * Set a breakpoint on the current line. - */ - public synchronized void setBreakpoint() { - setBreakpoint(editor.getCurrentLineID()); - } - - /** - * Set a breakpoint on a line in the current tab. - * - * @param lineIdx the line index (0-based) of the current tab to set the - * breakpoint on - */ - public synchronized void setBreakpoint(int lineIdx) { - setBreakpoint(editor.getLineIDInCurrentTab(lineIdx)); - } - - /** - * Set a breakpoint. - * - * @param line the line id to set the breakpoint on - */ - public synchronized void setBreakpoint(LineID line) { - // do nothing if we are kinda busy - if (isStarted() && !isPaused()) { - return; - } - // do nothing if there already is a breakpoint on this line - if (hasBreakpoint(line)) { - return; - } - breakpoints.add(new LineBreakpoint(line, this)); - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "set breakpoint on line {0}", line); - } - - /** - * Remove a breakpoint from the current line (if set). - */ - public synchronized void removeBreakpoint() { - removeBreakpoint(editor.getCurrentLineID().lineIdx()); - } - - /** - * Remove a breakpoint from a line in the current tab. - * - * @param lineIdx the line index (0-based) in the current tab to remove the - * breakpoint from - */ - protected void removeBreakpoint(int lineIdx) { - // do nothing if we are kinda busy - if (isBusy()) { - return; - } - - LineBreakpoint bp = breakpointOnLine(editor.getLineIDInCurrentTab(lineIdx)); - if (bp != null) { - bp.remove(); - breakpoints.remove(bp); - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "removed breakpoint {0}", bp); - } - } - - /** - * Remove all breakpoints. - */ - public synchronized void clearBreakpoints() { - //TODO: handle busy-ness correctly - if (isBusy()) { - Logger.getLogger(Debugger.class.getName()).log(Level.WARNING, "busy"); - return; - } - - for (LineBreakpoint bp : breakpoints) { - bp.remove(); - } - breakpoints.clear(); - } - - /** - * Clear breakpoints in a specific tab. - * - * @param tabFilename the tab's file name - */ - public synchronized void clearBreakpoints(String tabFilename) { - //TODO: handle busy-ness correctly - if (isBusy()) { - Logger.getLogger(Debugger.class.getName()).log(Level.WARNING, "busy"); - return; - } - - Iterator i = breakpoints.iterator(); - while (i.hasNext()) { - LineBreakpoint bp = i.next(); - if (bp.lineID().fileName().equals(tabFilename)) { - bp.remove(); - i.remove(); - } - } - } - - /** - * Get the breakpoint on a certain line, if set. - * - * @param line the line to get the breakpoint from - * @return the breakpoint, or null if no breakpoint is set on the specified - * line. - */ - protected LineBreakpoint breakpointOnLine(LineID line) { - for (LineBreakpoint bp : breakpoints) { - if (bp.isOnLine(line)) { - return bp; - } - } - return null; - } - - /** - * Toggle a breakpoint on the current line. - */ - public synchronized void toggleBreakpoint() { - toggleBreakpoint(editor.getCurrentLineID().lineIdx()); - } - - /** - * Toggle a breakpoint on a line in the current tab. - * - * @param lineIdx the line index (0-based) in the current tab - */ - public synchronized void toggleBreakpoint(int lineIdx) { - LineID line = editor.getLineIDInCurrentTab(lineIdx); - if (!hasBreakpoint(line)) { - setBreakpoint(line.lineIdx()); - } else { - removeBreakpoint(line.lineIdx()); - } - } - - /** - * Check if there's a breakpoint on a particular line. - * - * @param line the line id - * @return true if a breakpoint is set on the given line, otherwise false - */ - protected boolean hasBreakpoint(LineID line) { - LineBreakpoint bp = breakpointOnLine(line); - return bp != null; - } - - /** - * Print a list of currently set breakpoints. - */ - public synchronized void listBreakpoints() { - if (breakpoints.isEmpty()) { - System.out.println("no breakpoints"); - } else { - System.out.println("line breakpoints:"); - for (LineBreakpoint bp : breakpoints) { - System.out.println(bp); - } - } - } - - /** - * Retrieve a list of breakpoint in a particular tab. - * - * @param tabFilename the tab's file name - * @return the list of breakpoints in the given tab - */ - public synchronized List getBreakpoints(String tabFilename) { - List list = new ArrayList(); - for (LineBreakpoint bp : breakpoints) { - if (bp.lineID().fileName().equals(tabFilename)) { - list.add(bp); - } - } - return list; - } - - /** - * Callback for VM events. Will be called from another thread. - * ({@link VMEventReader}) - * - * @param es Incoming set of events from VM - */ - @Override - public synchronized void vmEvent(EventSet es) { - for (Event e : es) { - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "*** VM Event: {0}", e.toString()); - if (e instanceof VMStartEvent) { - //initialThread = ((VMStartEvent) e).thread(); -// ThreadReference t = ((VMStartEvent) e).thread(); - //printStackTrace(t); - - // break on main class load - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "requesting event on main class load: {0}", mainClassName); - ClassPrepareRequest mainClassPrepare = runtime.vm().eventRequestManager().createClassPrepareRequest(); - mainClassPrepare.addClassFilter(mainClassName); - mainClassPrepare.enable(); - - // break on loading custom classes - for (SketchCode tab : editor.getSketch().getCode()) { - if (tab.isExtension("java")) { - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "requesting event on class load: {0}", tab.getPrettyName()); - ClassPrepareRequest customClassPrepare = runtime.vm().eventRequestManager().createClassPrepareRequest(); - customClassPrepare.addClassFilter(tab.getPrettyName()); - customClassPrepare.enable(); - } - } - - runtime.vm().resume(); - } else if (e instanceof ClassPrepareEvent) { - ClassPrepareEvent ce = (ClassPrepareEvent) e; - ReferenceType rt = ce.referenceType(); - currentThread = ce.thread(); - paused = true; // for now we're paused - - if (rt.name().equals(mainClassName)) { - //printType(rt); - mainClass = rt; - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "main class load: {0}", rt.name()); - started = true; // now that main class is loaded, we're started - } else { - classes.add(rt); // save loaded classes - Logger.getLogger(Debugger.class.getName()).log(Level.INFO, "class load: {0}", rt.name()); - } - - // notify listeners - for (ClassLoadListener listener : classLoadListeners) { - if (listener != null) { - listener.classLoaded(rt); - } - } - - paused = false; // resuming now - runtime.vm().resume(); - } else if (e instanceof BreakpointEvent) { - BreakpointEvent be = (BreakpointEvent) e; - currentThread = be.thread(); // save this thread -// BreakpointRequest br = (BreakpointRequest) be.request(); - - //printSourceLocation(currentThread); - updateVariableInspector(currentThread); // this is already on the EDT - final LineID newCurrentLine = locationToLineID(be.location()); - javax.swing.SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - editor.setCurrentLine(newCurrentLine); - editor.toolbar().deactivate(DebugToolbar.STEP); - editor.toolbar().deactivate(DebugToolbar.CONTINUE); - } - }); - - // hit a breakpoint during a step, need to cancel the step. - if (requestedStep != null) { - runtime.vm().eventRequestManager().deleteEventRequest(requestedStep); - requestedStep = null; - } - - // fix canvas update issue - // TODO: is this a good solution? - resumeOtherThreads(currentThread); - - paused = true; - editor.statusHalted(); - } else if (e instanceof StepEvent) { - StepEvent se = (StepEvent) e; - currentThread = se.thread(); - - //printSourceLocation(currentThread); - updateVariableInspector(currentThread); // this is already on the EDT - final LineID newCurrentLine = locationToLineID(se.location()); - javax.swing.SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - editor.setCurrentLine(newCurrentLine); - editor.toolbar().deactivate(DebugToolbar.STEP); - editor.toolbar().deactivate(DebugToolbar.CONTINUE); - } - }); - - // delete the steprequest that triggered this step so new ones can be placed (only one per thread) - EventRequestManager mgr = runtime.vm().eventRequestManager(); - mgr.deleteEventRequest(se.request()); - requestedStep = null; // mark that there is no step request pending - paused = true; - editor.statusHalted(); - - // disallow stepping into invisible lines - if (!locationIsVisible(se.location())) { - stepOutIntoViewOrContinue(); // TODO: this leads to stepping, should it run on the EDT? - } - } else if (e instanceof VMDisconnectEvent) { -// started = false; -// // clear line highlight -// editor.clearCurrentLine(); - stopDebug(); - } else if (e instanceof VMDeathEvent) { - started = false; - editor.statusEmpty(); - } - } - } - - /** - * Check whether a location corresponds to a code line in the editor. - * - * @param l the location - * @return true if the location corresponds to a line in the editor - */ - protected boolean locationIsVisible(Location l) { - return locationToLineID(l) != null; - } - - /** - * Step out if this results in a visible location, otherwise continue. - */ - protected void stepOutIntoViewOrContinue() { - try { - List frames = currentThread.frames(); - if (frames.size() > 1) { - if (locationIsVisible(frames.get(1).location())) { - //System.out.println("stepping out to: " + locationToString(frames.get(1).location())); - stepOut(); - return; - } - } - continueDebug(); - -// //Step out to the next visible location on the stack frame -// if (thread.frames(i, i1)) -// for (StackFrame f : thread.frames()) { -// Location l = f.location(); -// if (locationIsVisible(l)) { -// System.out.println("need to step out to: " + locationToString(l)); -// } -// } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Check whether a debugging session is running. i.e. the debugger is - * connected to a debuggee VM, VMStartEvent has been received and main class - * is loaded. - * - * @return true if the debugger is started. - */ - public synchronized boolean isStarted() { - return started && runtime != null && runtime.vm() != null; - } - - /** - * Check whether the debugger is paused. i.e. it is currently suspended at a - * breakpoint or step. - * - * @return true if the debugger is paused, false otherwise or if not started - * ({@link #isStarted()}) - */ - public synchronized boolean isPaused() { - return isStarted() && paused && currentThread != null && currentThread.isSuspended(); - } - - /** - * Check whether the debugger is currently busy. i.e. running (not - * suspended). - * - * @return true if the debugger is currently running and not suspended. - */ - public synchronized boolean isBusy() { - return isStarted() && !isPaused(); - } - - /** - * Print call stack trace of a thread. Only works on suspended threads. - * - * @param t suspended thread to print stack trace of - */ - protected void printStackTrace(ThreadReference t) { - if (!t.isSuspended()) { - return; - } - try { - System.out.println("stack trace for thread " + t.name() + ":"); - int i = 0; - for (StackFrame f : t.frames()) { -// Location l = f.location(); - System.out.println(i++ + ": " + f.toString()); - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Resume all other threads except the one given as parameter. Useful e.g. - * to just keep the thread suspended a breakpoint occurred in. - * - * @param t the thread not to resume - */ - protected void resumeOtherThreads(ThreadReference t) { - if (!isStarted()) { - return; - } - for (ThreadReference other : vm().allThreads()) { - if (!other.equals(t) && other.isSuspended()) { - other.resume(); - } - } - } - - /** - * Print info about all current threads. Includes name, status, isSuspended, - * isAtBreakpoint. - */ - public synchronized void printThreads() { - if (!isPaused()) { - return; - } - System.out.println("threads:"); - for (ThreadReference t : vm().allThreads()) { - printThread(t); - } - } - - /** - * Print info about a thread. Includes name, status, isSuspended, - * isAtBreakpoint. - * - * @param t the thread to print info about - */ - protected void printThread(ThreadReference t) { - System.out.println(t.name()); - System.out.println(" is suspended: " + t.isSuspended()); - System.out.println(" is at breakpoint: " + t.isAtBreakpoint()); - System.out.println(" status: " + threadStatusToString(t.status())); - } - - /** - * Convert a status code returned by {@link ThreadReference#status() } to a - * human readable form. - * - * @param status {@link ThreadReference#THREAD_STATUS_MONITOR}, - * {@link ThreadReference#THREAD_STATUS_NOT_STARTED}, - * {@link ThreadReference#THREAD_STATUS_RUNNING}, - * {@link ThreadReference#THREAD_STATUS_SLEEPING}, - * {@link ThreadReference#THREAD_STATUS_UNKNOWN}, - * {@link ThreadReference#THREAD_STATUS_WAIT} or - * {@link ThreadReference#THREAD_STATUS_ZOMBIE} - * @return String containing readable status code. - */ - protected String threadStatusToString(int status) { - switch (status) { - case ThreadReference.THREAD_STATUS_MONITOR: - return "THREAD_STATUS_MONITOR"; - case ThreadReference.THREAD_STATUS_NOT_STARTED: - return "THREAD_STATUS_NOT_STARTED"; - case ThreadReference.THREAD_STATUS_RUNNING: - return "THREAD_STATUS_RUNNING"; - case ThreadReference.THREAD_STATUS_SLEEPING: - return "THREAD_STATUS_SLEEPING"; - case ThreadReference.THREAD_STATUS_UNKNOWN: - return "THREAD_STATUS_UNKNOWN"; - case ThreadReference.THREAD_STATUS_WAIT: - return "THREAD_STATUS_WAIT"; - case ThreadReference.THREAD_STATUS_ZOMBIE: - return "THREAD_STATUS_ZOMBIE"; - default: - return ""; - } - } - - /** - * Print local variables on a suspended thread. Takes the topmost stack - * frame and lists all local variables and their values. - * - * @param t suspended thread - */ - protected void printLocalVariables(ThreadReference t) { - if (!t.isSuspended()) { - return; - } - try { - if (t.frameCount() == 0) { - System.out.println("call stack empty"); - } else { - StackFrame sf = t.frame(0); - List locals = sf.visibleVariables(); - if (locals.isEmpty()) { - System.out.println("no local variables"); - return; - } - for (LocalVariable lv : locals) { - System.out.println(lv.typeName() + " " + lv.name() + " = " + sf.getValue(lv)); - } - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } catch (AbsentInformationException ex) { - System.out.println("local variable information not available"); - } - } - - /** - * Update variable inspector window. Displays local variables and this - * fields. - * - * @param t suspended thread to retrieve locals and this - */ - protected void updateVariableInspector(ThreadReference t) { - if (!t.isSuspended()) { - return; - } - try { - if (t.frameCount() == 0) { - // TODO: needs to be handled in a better way: - Logger.getLogger(Debugger.class.getName()).log(Level.WARNING, "call stack empty"); - } else { - final VariableInspector vi = editor.variableInspector(); - // first get data - final List stackTrace = getStackTrace(t); - final List locals = getLocals(t, 0); - final String currentLocation = currentLocation(t); - final List thisFields = getThisFields(t, 0, true); - final List declaredThisFields = getThisFields(t, 0, false); - final String thisName = thisName(t); - // now update asynchronously - javax.swing.SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - //System.out.println("updating vi. from EDT: " + javax.swing.SwingUtilities.isEventDispatchThread()); - vi.updateCallStack(stackTrace, "Call Stack"); - vi.updateLocals(locals, "Locals at " + currentLocation); - vi.updateThisFields(thisFields, "Class " + thisName); - vi.updateDeclaredThisFields(declaredThisFields, "Class " + thisName); - vi.unlock(); // need to do this before rebuilding, otherwise we get these ... dots in the labels - vi.rebuild(); - } - }); - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Get the class name of the current this object in a suspended thread. - * - * @param t a suspended thread - * @return the class name of this - */ - protected String thisName(ThreadReference t) { - try { - if (!t.isSuspended() || t.frameCount() == 0) { - return ""; - } - return t.frame(0).thisObject().referenceType().name(); - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - return ""; - } - } - - /** - * Get a description of the current location in a suspended thread. Format: - * class.method:translated_line_number - * - * @param t a suspended thread - * @return descriptive string for the given location - */ - protected String currentLocation(ThreadReference t) { - try { - if (!t.isSuspended() || t.frameCount() == 0) { - return ""; - } - return locationToString(t.frame(0).location()); - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - return ""; - } - } - - /** - * Get a string describing a location. Format: - * class.method:translated_line_number - * - * @param l a location - * @return descriptive string for the given location - */ - protected String locationToString(Location l) { - LineID line = locationToLineID(l); - int lineNumber; - if (line != null) { - lineNumber = line.lineIdx() + 1; - } else { - lineNumber = l.lineNumber(); - } - return l.declaringType().name() + "." + l.method().name() + ":" + lineNumber; - } - - /** - * Compile a list of current locals usable for insertion into a - * {@link JTree}. Recursively resolves object references. - * - * @param t the suspended thread to get locals for - * @param depth how deep to resolve nested object references. 0 will not - * resolve nested objects. - * @return the list of current locals - */ - protected List getLocals(ThreadReference t, int depth) { - //System.out.println("getting locals"); - List vars = new ArrayList(); - try { - if (t.frameCount() > 0) { - StackFrame sf = t.frame(0); - for (LocalVariable lv : sf.visibleVariables()) { - //System.out.println("local var: " + lv.name()); - Value val = sf.getValue(lv); - VariableNode var = new LocalVariableNode(lv.name(), lv.typeName(), val, lv, sf); - if (depth > 0) { - var.addChildren(getFields(val, depth - 1, true)); - } - vars.add(var); - } - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } catch (AbsentInformationException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.WARNING, "local variable information not available", ex); - } - return vars; - } - - /** - * Compile a list of fields in the current this object usable for insertion - * into a {@link JTree}. Recursively resolves object references. - * - * @param t the suspended thread to get locals for - * @param depth how deep to resolve nested object references. 0 will not - * resolve nested objects. - * @return the list of fields in the current this object - */ - protected List getThisFields(ThreadReference t, int depth, boolean includeInherited) { - //System.out.println("getting this"); - try { - if (t.frameCount() > 0) { - StackFrame sf = t.frame(0); - ObjectReference thisObj = sf.thisObject(); - return getFields(thisObj, depth, includeInherited); - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - return new ArrayList(); - } - - /** - * Recursively get the fields of a {@link Value} for insertion into a - * {@link JTree}. - * - * @param value must be an instance of {@link ObjectReference} - * @param depth the current depth - * @param maxDepth the depth to stop at (inclusive) - * @return list of child fields of the given value - */ - protected List getFields(Value value, int depth, int maxDepth, boolean includeInherited) { - // remember: Value <- ObjectReference, ArrayReference - List vars = new ArrayList(); - if (depth <= maxDepth) { - if (value instanceof ArrayReference) { - return getArrayFields((ArrayReference) value); - } else if (value instanceof ObjectReference) { - ObjectReference obj = (ObjectReference) value; - // get the fields of this object - List fields = includeInherited ? obj.referenceType().visibleFields() : obj.referenceType().fields(); - for (Field field : fields) { - Value val = obj.getValue(field); // get the value, may be null - VariableNode var = new FieldNode(field.name(), field.typeName(), val, field, obj); - // recursively add children - if (val != null) { - var.addChildren(getFields(val, depth + 1, maxDepth, includeInherited)); - } - vars.add(var); - } - } - } - return vars; - } - - /** - * Recursively get the fields of a {@link Value} for insertion into a - * {@link JTree}. - * - * @param value must be an instance of {@link ObjectReference} - * @param maxDepth max recursion depth. 0 will give only direct children - * @return list of child fields of the given value - */ - protected List getFields(Value value, int maxDepth, boolean includeInherited) { - return getFields(value, 0, maxDepth, includeInherited); - } - - /** - * Get the fields of an array for insertion into a {@link JTree}. - * - * @param array the array reference - * @return list of array fields - */ - protected List getArrayFields(ArrayReference array) { - List fields = new ArrayList(); - if (array != null) { - String arrayType = array.type().name(); - if (arrayType.endsWith("[]")) { - arrayType = arrayType.substring(0, arrayType.length() - 2); - } - int i = 0; - for (Value val : array.getValues()) { - VariableNode var = new ArrayFieldNode("[" + i + "]", arrayType, val, array, i); - fields.add(var); - i++; - } - } - return fields; - } - - /** - * Get the current call stack trace usable for insertion into a - * {@link JTree}. - * - * @param t the suspended thread to retrieve the call stack from - * @return call stack as list of {@link DefaultMutableTreeNode}s - */ - protected List getStackTrace(ThreadReference t) { - List stack = new ArrayList(); - try { -// int i = 0; - for (StackFrame f : t.frames()) { - stack.add(new DefaultMutableTreeNode(locationToString(f.location()))); - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - return stack; - } - - /** - * Print visible fields of current "this" object on a suspended thread. - * Prints type, name and value. - * - * @param t suspended thread - */ - protected void printThis(ThreadReference t) { - if (!t.isSuspended()) { - return; - } - try { - if (t.frameCount() == 0) { - // TODO: needs to be handled in a better way - System.out.println("call stack empty"); - } else { - StackFrame sf = t.frame(0); - ObjectReference thisObject = sf.thisObject(); - if (this != null) { - ReferenceType type = thisObject.referenceType(); - System.out.println("fields in this (" + type.name() + "):"); - for (Field f : type.visibleFields()) { - System.out.println(f.typeName() + " " + f.name() + " = " + thisObject.getValue(f)); - } - } else { - System.out.println("can't get this (in native or static method)"); - } - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Print source code snippet of current location in a suspended thread. - * - * @param t suspended thread - */ - protected void printSourceLocation(ThreadReference t) { - try { - if (t.frameCount() == 0) { - // TODO: needs to be handled in a better way - System.out.println("call stack empty"); - } else { - Location l = t.frame(0).location(); // current stack frame location - printSourceLocation(l); - } - } catch (IncompatibleThreadStateException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Print source code snippet. - * - * @param l {@link Location} object to print source code for - */ - protected void printSourceLocation(Location l) { - try { - //System.out.println(l.sourceName() + ":" + l.lineNumber()); - System.out.println("in method " + l.method() + ":"); - System.out.println(getSourceLine(l.sourcePath(), l.lineNumber(), 2)); - - } catch (AbsentInformationException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Read a line from the given file in the builds src folder. 1-based i.e. - * first line has line no. 1 - * - * @param filePath - * @param lineNo - * @return the requested source line - */ - protected String getSourceLine(String filePath, int lineNo, int radius) { - if (lineNo == -1) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, "invalid line number: {0}", lineNo); - return ""; - } - //System.out.println("getting line: " + lineNo); - File f = new File(srcPath + File.separator + filePath); - String output = ""; - try { - BufferedReader r = new BufferedReader(new FileReader(f)); - int i = 1; - //String line = ""; - while (i <= lineNo + radius) { - String line = r.readLine(); // line no. i - if (line == null) { - break; // end of file - } - if (i >= lineNo - radius) { - if (i > lineNo - radius) { - output += "\n"; // add newlines before all lines but the first - } - output += f.getName() + ":" + i + (i == lineNo ? " => " : " ") + line; - } - i++; - } - r.close(); - return output; - } catch (FileNotFoundException ex) { - //System.err.println(ex); - return f.getName() + ":" + lineNo; - } catch (IOException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - return ""; - } - } - - /** - * Print info about a ReferenceType. Prints class name, source file name, - * lists methods. - * - * @param rt the reference type to print out - */ - protected void printType(ReferenceType rt) { - System.out.println("ref.type: " + rt); - System.out.println("name: " + rt.name()); - try { - System.out.println("sourceName: " + rt.sourceName()); - } catch (AbsentInformationException ex) { - System.out.println("sourceName: unknown"); - } - System.out.println("methods:"); - for (Method m : rt.methods()) { - System.out.println(m.toString()); - } - } - - /** - * Translate a java source location to a sketch line id. - * - * @param l the location to translate - * @return the corresponding line id, or null if not found - */ - protected LineID locationToLineID(Location l) { - try { - //return lineMap.get(LineID.create(l.sourceName(), l.lineNumber() - 1)); - return javaToSketchLine(new LineID(l.sourceName(), l.lineNumber() - 1)); - - } catch (AbsentInformationException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - return null; - } - } - - /** - * Translate a line (index) from java space to sketch space. - * - * @param javaLine the java line id - * @return the corresponding sketch line id or null if failed to translate - */ - public LineID javaToSketchLine(LineID javaLine) { - Sketch sketch = editor.getSketch(); - - // it may belong to a pure java file created in the sketch - // try to find an exact filename match and check the extension - SketchCode tab = editor.getTab(javaLine.fileName()); - if (tab != null && tab.isExtension("java")) { - // can translate 1:1 - return originalToRuntimeLine(javaLine); - } - - // check if it is the preprocessed/assembled file for this sketch - // java file name needs to match the sketches filename - if (!javaLine.fileName().equals(sketch.getName() + ".java")) { - return null; - } - - // find the tab (.pde file) this line belongs to - // get the last tab that has an offset not greater than the java line number - for (int i = sketch.getCodeCount() - 1; i >= 0; i--) { - tab = sketch.getCode(i); - // ignore .java files - // the tab's offset must not be greater than the java line number - if (tab.isExtension("pde") && tab.getPreprocOffset() <= javaLine.lineIdx()) { - return originalToRuntimeLine(new LineID(tab.getFileName(), javaLine.lineIdx() - tab.getPreprocOffset())); - } - } - - return null; - } - - /** - * Get the runtime-changed line id for an original sketch line. Used to - * translate line numbers from the VM (which runs on the original line - * numbers) to their current (possibly changed) counterparts. - * - * @param line the original line id (at compile time) - * @return the changed version or the line given as parameter if not found - */ - protected LineID originalToRuntimeLine(LineID line) { - LineID transformed = runtimeLineChanges.get(line); - if (transformed == null) { - return line; - } - return transformed; - } - - /** - * Get the original line id for a sketch line that was changed at runtime. - * Used to translate line numbers from the UI at runtime (which can differ - * from the ones the VM runs on) to their original counterparts. - * - * @param line the (possibly) changed runtime line - * @return the original line or the line given as parameter if not found - */ - protected LineID runtimeToOriginalLine(LineID line) { - for (Entry entry : runtimeLineChanges.entrySet()) { - if (entry.getValue().equals(line)) { - return entry.getKey(); - } - } - return line; - } - - /** - * Translate a line (index) from sketch space to java space. - * - * @param sketchLine the sketch line id - * @return the corresponding java line id or null if failed to translate - */ - public LineID sketchToJavaLine(LineID sketchLine) { - sketchLine = runtimeToOriginalLine(sketchLine); // transform back to orig (before changes at runtime) - - // check if there is a tab for this line - SketchCode tab = editor.getTab(sketchLine.fileName()); - if (tab == null) { - return null; - } - - // check if the tab is a pure java file anyway - if (tab.isExtension("java")) { - // 1:1 translation - return sketchLine; - } - - // the java file has a name sketchname.java - // just add the tab's offset to get the java name - LineID javaLine = new LineID(editor.getSketch().getName() + ".java", sketchLine.lineIdx() + tab.getPreprocOffset()); - return javaLine; - } - - /** - * Start tracking all line changes (due to edits) in the current tab. - */ - // TODO: maybe move this to the editor? - protected void startTrackingLineChanges() { - SketchCode tab = editor.getSketch().getCurrentCode(); - if (runtimeTabsTracked.contains(tab.getFileName())) { - return; - } - - for (int i = 0; i < tab.getLineCount(); i++) { - LineID old = new LineID(tab.getFileName(), i); - LineID tracked = new LineID(tab.getFileName(), i); - tracked.startTracking(editor.currentDocument()); - runtimeLineChanges.put(old, tracked); - } - runtimeTabsTracked.add(tab.getFileName()); - //System.out.println("tracking tab: " + tab.getFileName()); - } - - /** - * Stop tracking line changes in all tabs. - */ - protected void stopTrackingLineChanges() { - //System.out.println("stop tracking line changes"); - for (LineID tracked : runtimeLineChanges.values()) { - tracked.stopTracking(); - } - runtimeLineChanges.clear(); - runtimeTabsTracked.clear(); - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/ErrorBar.java b/pdex/experimental/src/processing/mode/experimental/ErrorBar.java deleted file mode 100755 index 24d552ae5..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ErrorBar.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package processing.mode.experimental; - -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionListener; -import java.util.ArrayList; - -import javax.swing.JPanel; -import javax.swing.SwingWorker; - -import processing.app.Base; -import processing.app.SketchCode; - -/** - * The bar on the left of the text area which displays all errors as rectangles.
- *
- * All errors and warnings of a sketch are drawn on the bar, clicking on one, - * scrolls to the tab and location. Error messages displayed on hover. Markers - * are not in sync with the error line. Similar to eclipse's right error bar - * which displays the overall errors in a document - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class ErrorBar extends JPanel { - /** - * Preferred height of the component - */ - protected int preferredHeight; - - /** - * Preferred height of the component - */ - protected int preferredWidth = 12; - - /** - * Height of marker - */ - public static final int errorMarkerHeight = 4; - - /** - * Color of Error Marker - */ - public Color errorColor = new Color(0xED2630); - - /** - * Color of Warning Marker - */ - public Color warningColor = new Color(0xFFC30E); - - /** - * Background color of the component - */ - public Color backgroundColor = new Color(0x2C343D); - - /** - * DebugEditor instance - */ - protected DebugEditor editor; - - /** - * ErrorCheckerService instance - */ - protected ErrorCheckerService errorCheckerService; - - /** - * Stores error markers displayed PER TAB along the error bar. - */ - protected ArrayList errorPoints = new ArrayList(); - - /** - * Stores previous list of error markers. - */ - protected ArrayList errorPointsOld = new ArrayList(); - - public void paintComponent(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setColor(backgroundColor); - g.fillRect(0, 0, getWidth(), getHeight()); - - for (ErrorMarker emarker : errorPoints) { - if (emarker.type == ErrorMarker.Error) { - g.setColor(errorColor); - } else { - g.setColor(warningColor); - } - g.fillRect(2, emarker.y, (getWidth() - 3), errorMarkerHeight); - } - } - - public Dimension getPreferredSize() { - return new Dimension(preferredWidth, preferredHeight); - } - - public Dimension getMinimumSize() { - return getPreferredSize(); - } - - public ErrorBar(DebugEditor editor, int height, ExperimentalMode mode) { - this.editor = editor; - this.preferredHeight = height; - this.errorCheckerService = editor.errorCheckerService; - errorColor = mode.getThemeColor("errorbar.errorcolor", errorColor); - warningColor = mode - .getThemeColor("errorbar.warningcolor", warningColor); - backgroundColor = mode.getThemeColor("errorbar.backgroundcolor", - backgroundColor); - addListeners(); - } - - /** - * Update error markers in the error bar. - * - * @param problems - * - List of problems. - */ - synchronized public void updateErrorPoints(final ArrayList problems) { - - // NOTE TO SELF: ErrorMarkers are calculated for the present tab only - // Error Marker index in the arraylist is LOCALIZED for current tab. - // Also, need to do the update in the UI thread to prevent concurrency issues. - final int fheight = this.getHeight(); - SwingWorker worker = new SwingWorker() { - - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - int totalLines = 0; - int currentTab = 0; - for (SketchCode sc : editor.getSketch().getCode()) { - if (sc.isExtension("pde")) { - try { - if (editor.getSketch().getCurrentCode().equals(sc)) { - // Adding + 1 to len because \n gets appended - // for each - // sketchcode extracted during processPDECode() - totalLines = Base.countLines(sc.getDocument() - .getText(0, - sc.getDocument().getLength())) + 1; - break; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - currentTab++; - } - // System.out.println("Total lines: " + totalLines); - - errorPointsOld.clear(); - for (ErrorMarker marker : errorPoints) { - errorPointsOld.add(marker); - } - errorPoints.clear(); - - // Each problem.getSourceLine() will have an extra line added - // because of - // class declaration in the beginning as well as default imports - for (Problem problem : problems) { - if (problem.tabIndex == currentTab) { - // Ratio of error line to total lines - float y = (problem.lineNumber - errorCheckerService.defaultImportsOffset) - / ((float) totalLines); - // Ratio multiplied by height of the error bar - y *= fheight - 15; // -15 is just a vertical offset - errorPoints.add(new ErrorMarker(problem, (int) y, - problem.isError() ? ErrorMarker.Error - : ErrorMarker.Warning)); - // System.out.println("Y: " + y); - } - } - - repaint(); - } - }; - - try { - worker.execute(); // I eat concurrency bugs for breakfast. - } catch (Exception exp) { - System.out.println("Errorbar update markers is slacking." - + exp.getMessage()); - // e.printStackTrace(); - } - } - - /** - * Check if new errors have popped up in the sketch since the last check - * - * @return true - if errors have changed - */ - public boolean errorPointsChanged() { - if (errorPointsOld.size() != errorPoints.size()) { - editor.getTextArea().repaint(); - // System.out.println("2 Repaint " + System.currentTimeMillis()); - return true; - } - - else { - for (int i = 0; i < errorPoints.size(); i++) { - if (errorPoints.get(i).y != errorPointsOld.get(i).y) { - editor.getTextArea().repaint(); - // System.out.println("3 Repaint " + - // System.currentTimeMillis()); - return true; - } - } - } - return false; - } - - /** - * Add various mouse listeners. - */ - protected void addListeners() { - - this.addMouseListener(new MouseAdapter() { - - // Find out which error/warning the user has clicked - // and then scroll to that - @SuppressWarnings("rawtypes") - @Override - public void mouseClicked(final MouseEvent e) { - SwingWorker worker = new SwingWorker() { - - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - for (ErrorMarker eMarker : errorPoints) { - // -2 and +2 are extra allowance, clicks in the - // vicinity of the markers register that way - if (e.getY() >= eMarker.y - 2 - && e.getY() <= eMarker.y + 2 - + errorMarkerHeight) { - int currentTabErrorIndex = errorPoints - .indexOf(eMarker); - // System.out.println("Index: " + - // currentTabErrorIndex); - int currentTab = editor.getSketch() - .getCodeIndex( - editor.getSketch() - .getCurrentCode()); - - int totalErrorIndex = currentTabErrorIndex; - - for (int i = 0; i < errorCheckerService.problemsList - .size(); i++) { - Problem p = errorCheckerService.problemsList - .get(i); - if (p.tabIndex < currentTab) { - totalErrorIndex++; - } - if (p.tabIndex == currentTab) { - break; - } - } - errorCheckerService - .scrollToErrorLine(totalErrorIndex); - } - } - - } - }; - - try { - worker.execute(); - } catch (Exception exp) { - System.out.println("Errorbar mouseClicked is slacking." - + exp.getMessage()); - // e.printStackTrace(); - } - - } - }); - - // Tooltip on hover - this.addMouseMotionListener(new MouseMotionListener() { - - @SuppressWarnings("rawtypes") - @Override - public void mouseMoved(final MouseEvent e) { - // System.out.println(e); - SwingWorker worker = new SwingWorker() { - - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - - for (ErrorMarker eMarker : errorPoints) { - if (e.getY() >= eMarker.y - 2 - && e.getY() <= eMarker.y + 2 - + errorMarkerHeight) { - // System.out.println("Index: " + - // errorPoints.indexOf(y)); - int currentTab = editor.getSketch() - .getCodeIndex( - editor.getSketch() - .getCurrentCode()); - int currentTabErrorCount = 0; - - for (int i = 0; i < errorPoints.size(); i++) { - Problem p = errorPoints.get(i).problem; - if (p.tabIndex == currentTab) { - if (currentTabErrorCount == errorPoints - .indexOf(eMarker)) { - // System.out.println("Roger that."); - String msg = (p.isError() ? "Error: " - : "Warning: ") - + p.message; - setToolTipText(msg); - setCursor(Cursor - .getPredefinedCursor(Cursor.HAND_CURSOR)); - return; - } else { - currentTabErrorCount++; - // System.out.println("Still looking.."); - } - } - - } - } - // Reset cursor and tooltip - else { - setToolTipText(""); - setCursor(Cursor - .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - } - - } - }; - try { - worker.execute(); - } catch (Exception exp) { - System.out - .println("Errorbar mousemoved Worker is slacking." - + exp.getMessage()); - // e.printStackTrace(); - } - } - - @Override - public void mouseDragged(MouseEvent arg0) { - - } - }); - - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/ErrorCheckerService.java b/pdex/experimental/src/processing/mode/experimental/ErrorCheckerService.java deleted file mode 100644 index 395def5e2..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ErrorCheckerService.java +++ /dev/null @@ -1,1297 +0,0 @@ -package processing.mode.experimental; - -import java.awt.EventQueue; -import java.io.File; -import java.io.FileFilter; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.table.DefaultTableModel; - -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTParser; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; - -import processing.app.Base; -import processing.app.Editor; -import processing.app.Library; -import processing.app.SketchCode; -import processing.core.PApplet; -import processing.mode.java.preproc.PdePreprocessor; - -public class ErrorCheckerService implements Runnable{ - - private DebugEditor editor; - /** - * Error check happens every sleepTime milliseconds - */ - public static final int sleepTime = 1000; - - /** - * The amazing eclipse ast parser - */ - private ASTParser parser; - - /** - * Used to indirectly stop the Error Checker Thread - */ - public boolean stopThread = false; - - /** - * If true, Error Checking is paused. Calls to checkCode() become useless. - */ - private boolean pauseThread = false; - - protected ErrorWindow errorWindow; - - /** - * IProblem[] returned by parser stored in here - */ - private IProblem[] problems; - - /** - * Class name of current sketch - */ - protected String className; - - /** - * Source code of current sketch - */ - protected String sourceCode; - - /** - * URLs of extra imports jar files stored here. - */ - protected URL[] classpath; - - /** - * Stores all Problems in the sketch - */ - public ArrayList problemsList; - - /** - * How many lines are present till the initial class declaration? In static - * mode, this would include imports, class declaration and setup - * declaration. In nomral mode, this would include imports, class - * declaration only. It's fate is decided inside preprocessCode() - */ - public int mainClassOffset; - - /** - * Fixed p5 offsets for all sketches - */ - public int defaultImportsOffset; - - /** - * Is the sketch running in static mode or active mode? - */ - public boolean staticMode = false; - - /** - * Compilation Unit for current sketch - */ - protected CompilationUnit cu; - - /** - * If true, compilation checker will be reloaded with updated classpath - * items. - */ - private boolean loadCompClass = true; - - /** - * Compiler Checker class. Note that methods for compilation checking are - * called from the compilationChecker object, not from this - */ - protected Class checkerClass; - - /** - * Compilation Checker object. - */ - protected Object compilationChecker; - - - /** - * List of jar files to be present in compilation checker's classpath - */ - protected ArrayList classpathJars; - - /** - * Timestamp - for measuring total overhead - */ - private long lastTimeStamp = System.currentTimeMillis(); - - /** - * Used for displaying the rotating slash on the Problem Window title bar - */ - private String[] slashAnimation = { "|", "/", "--", "\\", "|", "/", "--", - "\\" }; - private int slashAnimationIndex = 0; - - /** - * Used to detect if the current tab index has changed and thus repaint the - * textarea. - */ - public int currentTab = 0, lastTab = 0; - - /** - * Stores the current import statements in the program. Used to compare for - * changed import statements and update classpath if needed. - */ - protected ArrayList programImports; - - /** - * List of imports when sketch was last checked. Used for checking for - * changed imports - */ - protected ArrayList previousImports = new ArrayList(); - - /** - * Teh Preprocessor - */ - protected XQPreprocessor xqpreproc; - - /** - * Regexp for import statements. (Used from Processing source) - */ - final public String importRegexp = "(?:^|;)\\s*(import\\s+)((?:static\\s+)?\\S+)(\\s*;)"; - - /** - * Regexp for function declarations. (Used from Processing source) - */ - final Pattern FUNCTION_DECL = Pattern - .compile("(^|;)\\s*((public|private|protected|final|static)\\s+)*" - + "(void|int|float|double|String|char|byte)" - + "(\\s*\\[\\s*\\])?\\s+[a-zA-Z0-9]+\\s*\\(", Pattern.MULTILINE); - - public ErrorCheckerService(DebugEditor debugEditor) { - this.editor = debugEditor; - initParser(); - initializeErrorWindow(); - xqpreproc = new XQPreprocessor(); - PdePreprocessor pdePrepoc = new PdePreprocessor(null); - defaultImportsOffset = pdePrepoc.getCoreImports().length + - pdePrepoc.getDefaultImports().length + 1; - astGenerator = new ASTGenerator(this); - } - - /** - * Initializes ASTParser - */ - private void initParser() { - try { - parser = ASTParser.newParser(AST.JLS4); - } catch (Exception e) { - System.err.println("Experimental Mode initialization failed. " - + "Are you running the right version of Processing? "); - pauseThread(); - } catch (Error e) { - System.err.println("Experimental Mode initialization failed. "); - e.printStackTrace(); - pauseThread(); - } - } - - /** - * Initialiazes the Error Window - */ - public void initializeErrorWindow() { - - if (editor == null) { - return; - } - - if (errorWindow != null) { - return; - } - - final ErrorCheckerService thisService = this; - final DebugEditor thisEditor = editor; - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - errorWindow = new ErrorWindow(thisEditor, thisService); - // errorWindow.setVisible(true); - editor.toFront(); - errorWindow.errorTable.setFocusable(false); - editor.setSelection(0, 0); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - - public void run() { - stopThread = false; - - checkCode(); - while (!stopThread) { - try { - // Take a nap. - Thread.sleep(sleepTime); - } catch (Exception e) { - System.out.println("Oops! [ErrorCheckerThreaded]: " + e); - // e.printStackTrace(); - } - - updatePaintedThingys(); - - if (pauseThread) - continue; - if(textModified.get() == 0) - continue; - // Check every x seconds - checkCode(); - - } - } - - protected ASTGenerator astGenerator; - AtomicInteger textModified = new AtomicInteger(); - private boolean checkCode() { - System.out.println("checkCode() " + textModified.get() ); - lastTimeStamp = System.currentTimeMillis(); - try { - sourceCode = preprocessCode(editor.getSketch().getMainProgram()); - - syntaxCheck(); - System.out.println(editor.getSketch().getName() + "1 MCO " - + mainClassOffset); - // No syntax errors, proceed for compilation check, Stage 2. - - if (problems.length == 0 && editor.compilationCheckEnabled) { - //mainClassOffset++; // just a hack. - astGenerator.buildAST(cu); - sourceCode = xqpreproc.doYourThing(sourceCode, programImports); - prepareCompilerClasspath(); -// mainClassOffset = xqpreproc.mainClassOffset; // tiny, but -// // significant -// if (staticMode) { -// mainClassOffset++; // Extra line for setup() decl. -// } - // System.out.println(sourceCode); - // System.out.println("--------------------------"); - compileCheck(); - System.out.println(editor.getSketch().getName() + "2 MCO " - + mainClassOffset); - } - - updateErrorTable(); - editor.updateErrorBar(problemsList); - updateEditorStatus(); - updatePaintedThingys(); - int x = textModified.get(); - //System.out.println("TM " + x); - if(x>=3){ - textModified.set(3); - x = 3; - } - - if(x>0) - textModified.set(x - 1); - else - textModified.set(0); - return true; - - } catch (Exception e) { - System.out.println("Oops! [ErrorCheckerService.checkCode]: " + e); - e.printStackTrace(); - } - return false; - } - - private void syntaxCheck() { - parser.setSource(sourceCode.toCharArray()); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - - @SuppressWarnings("unchecked") - Map options = JavaCore.getOptions(); - - JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); - options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); - parser.setCompilerOptions(options); - cu = (CompilationUnit) parser.createAST(null); - - // Store errors returned by the ast parser - problems = cu.getProblems(); - // System.out.println("Problem Count: " + problems.length); - // Populate the probList - problemsList = new ArrayList(); - for (int i = 0; i < problems.length; i++) { - int a[] = calculateTabIndexAndLineNumber(problems[i]); - Problem p = new Problem(problems[i], a[0], a[1]); - problemsList.add(p); - // System.out.println(p.toString()); - } - } - protected URLClassLoader classLoader; - private void compileCheck() { - - // Currently (Sept, 2012) I'm using Java's reflection api to load the - // CompilationChecker class(from CompilationChecker.jar) that houses the - // Eclispe JDT compiler and call its getErrorsAsObj method to obtain - // errors. This way, I'm able to add the paths of contributed libraries - // to the classpath of CompilationChecker, dynamically. The eclipse compiler - // needs all referenced libraries in the classpath. - - try { - - // NOTE TO SELF: If classpath contains null Strings - // URLClassLoader gets angry. Drops NPE bombs. - - // If imports have changed, reload classes with new classpath. - if (loadCompClass) { - - // if (classpathJars.size() > 0) - // System.out - // .println("Experimental Mode: Loading contributed libraries referenced by import statements."); - - File f = Base.getContentFile("modes" + File.separator + "experimental" - + File.separator + "mode"); - - if(!f.exists()) { - System.err.println("Could not locate the files required for on-the-fly error checking. Bummer."); - return; - } - - FileFilter fileFilter = new FileFilter() { - public boolean accept(File file) { - return (file.getName().endsWith(".jar") && !file - .getName().startsWith("experimental")); - } - }; - - File[] jarFiles = f.listFiles(fileFilter); - // System.out.println( "Jar files found? " + (jarFiles != null)); - //for (File jarFile : jarFiles) { - //classpathJars.add(jarFile.toURI().toURL()); - //} - - classpath = new URL[classpathJars.size() + jarFiles.length]; - int ii = 0; - for (; ii < classpathJars.size(); ii++) { - classpath[ii] = classpathJars.get(ii); - } - for (int i = 0; i < jarFiles.length; i++) { - classpath[ii++] = jarFiles[i].toURI().toURL(); - } - - // System.out.println("CP Len -- " + classpath.length); - classLoader = new URLClassLoader(classpath); - // System.out.println("1."); - checkerClass = Class.forName("CompilationChecker", true, - classLoader); - // System.out.println("2."); - compilationChecker = checkerClass.newInstance(); - - astGenerator.loadJars(); // Update jar files for completition list - loadCompClass = false; - } - - if (compilerSettings == null) { - prepareCompilerSetting(); - } - Method getErrors = checkerClass.getMethod("getErrorsAsObjArr", - new Class[] { String.class, String.class, Map.class }); - - Object[][] errorList = (Object[][]) getErrors - .invoke(compilationChecker, className, sourceCode, - compilerSettings); - - if (errorList == null) { - return; - } - - problems = new DefaultProblem[errorList.length]; - - for (int i = 0; i < errorList.length; i++) { - - // for (int j = 0; j < errorList[i].length; j++) - // System.out.print(errorList[i][j] + ", "); - - problems[i] = new DefaultProblem((char[]) errorList[i][0], - (String) errorList[i][1], - ((Integer) errorList[i][2]).intValue(), - (String[]) errorList[i][3], - ((Integer) errorList[i][4]).intValue(), - ((Integer) errorList[i][5]).intValue(), - ((Integer) errorList[i][6]).intValue(), - ((Integer) errorList[i][7]).intValue(), 0); - - // System.out - // .println("ECS: " + problems[i].getMessage() + "," - // + problems[i].isError() + "," - // + problems[i].isWarning()); - - IProblem problem = problems[i]; - - int a[] = calculateTabIndexAndLineNumber(problem); - Problem p = new Problem(problem, a[0], a[1]); - if ((Boolean) errorList[i][8]) { - p.setType(Problem.ERROR); - } - - if ((Boolean) errorList[i][9]) { - p.setType(Problem.WARNING); - } - - // If warnings are disabled, skip 'em - if (p.isWarning() && !warningsEnabled) { - continue; - } - problemsList.add(p); - } - - } catch (ClassNotFoundException e) { - System.err.println("Compiltation Checker files couldn't be found! " - + e + " compileCheck() problem."); - stopThread(); - } catch (MalformedURLException e) { - System.err.println("Compiltation Checker files couldn't be found! " - + e + " compileCheck() problem."); - stopThread(); - } catch (Exception e) { - System.err.println("compileCheck() problem." + e); - e.printStackTrace(); - stopThread(); - } catch (NoClassDefFoundError e) { - System.err - .println(e - + " compileCheck() problem. Somebody tried to mess with Experimental Mode files."); - stopThread(); - } - // System.out.println("Compilecheck, Done."); - } - - /** - * Processes import statements to obtain classpaths of contributed - * libraries. This would be needed for compilation check. Also, adds - * stuff(jar files, class files, candy) from the code folder. And it looks - * messed up. - * - */ - private void prepareCompilerClasspath() { - if (!loadCompClass) { - return; - } - - // System.out.println("1.."); - classpathJars = new ArrayList(); - String entry = ""; - boolean codeFolderChecked = false; - for (ImportStatement impstat : programImports) { - String item = impstat.importName; - int dot = item.lastIndexOf('.'); - entry = (dot == -1) ? item : item.substring(0, dot); - - entry = entry.substring(6).trim(); - // System.out.println("Entry--" + entry); - if (ignorableImport(entry)) { - // System.out.println("Ignoring: " + entry); - continue; - } - Library library = null; - - // Try to get the library classpath and add it to the list - try { - library = editor.getMode().getLibrary(entry); - // System.out.println("lib->" + library.getClassPath() + "<-"); - String libraryPath[] = PApplet.split(library.getClassPath() - .substring(1).trim(), File.pathSeparatorChar); - for (int i = 0; i < libraryPath.length; i++) { - // System.out.println(entry + " ::" - // + new File(libraryPath[i]).toURI().toURL()); - classpathJars.add(new File(libraryPath[i]).toURI().toURL()); - } - // System.out.println("-- "); - // classpath[count] = (new File(library.getClassPath() - // .substring(1))).toURI().toURL(); - // System.out.println(" found "); - // System.out.println(library.getClassPath().substring(1)); - } catch (Exception e) { - if (library == null && !codeFolderChecked) { - // System.out.println(1); - // Look around in the code folder for jar files - if (editor.getSketch().hasCodeFolder()) { - File codeFolder = editor.getSketch().getCodeFolder(); - - // get a list of .jar files in the "code" folder - // (class files in subfolders should also be picked up) - String codeFolderClassPath = Base - .contentsToClassPath(codeFolder); - codeFolderChecked = true; - if (codeFolderClassPath.equalsIgnoreCase("")) { - System.err.println("Experimental Mode: Yikes! Can't find \"" - + entry - + "\" library! Line: " - + impstat.lineNumber - + " in tab: " - + editor.getSketch().getCode(impstat.tab) - .getPrettyName()); - System.out - .println("Please make sure that the library is present in /libraries folder or in the code folder of your sketch"); - - } - String codeFolderPath[] = PApplet.split( - codeFolderClassPath.substring(1).trim(), - File.pathSeparatorChar); - try { - for (int i = 0; i < codeFolderPath.length; i++) { - classpathJars.add(new File(codeFolderPath[i]) - .toURI().toURL()); - } - - } catch (Exception e2) { - System.out - .println("Yikes! codefolder, prepareImports(): " - + e2); - } - } else { - System.err.println("Experimental Mode: Yikes! Can't find \"" - + entry - + "\" library! Line: " - + impstat.lineNumber - + " in tab: " - + editor.getSketch().getCode(impstat.tab) - .getPrettyName()); - System.out - .println("Please make sure that the library is present in /libraries folder or in the code folder of your sketch"); - } - - } else { - System.err - .println("Yikes! There was some problem in prepareImports(): " - + e); - System.err.println("I was processing: " + entry); - - // e.printStackTrace(); - } - } - - } - - } - - /** - * Ignore processing packages, java.*.*. etc. - * - * @param packageName - * @return boolean - */ - protected boolean ignorableImport(String packageName) { - // packageName.startsWith("processing.") - // || - if (packageName.startsWith("java.") || packageName.startsWith("javax.")) { - return true; - } - return false; - } - - /** - * Various option for JDT Compiler - */ - @SuppressWarnings("rawtypes") - protected Map compilerSettings; - - /** - * Enable/Disable warnings from being shown - */ - public boolean warningsEnabled = true; - - /** - * Sets compiler options for JDT Compiler - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected void prepareCompilerSetting() { - compilerSettings = new HashMap(); - - compilerSettings.put(CompilerOptions.OPTION_LineNumberAttribute, - CompilerOptions.GENERATE); - compilerSettings.put(CompilerOptions.OPTION_SourceFileAttribute, - CompilerOptions.GENERATE); - compilerSettings.put(CompilerOptions.OPTION_Source, - CompilerOptions.VERSION_1_6); - compilerSettings.put(CompilerOptions.OPTION_ReportUnusedImport, - CompilerOptions.IGNORE); - compilerSettings.put(CompilerOptions.OPTION_ReportMissingSerialVersion, - CompilerOptions.IGNORE); - compilerSettings.put(CompilerOptions.OPTION_ReportRawTypeReference, - CompilerOptions.IGNORE); - compilerSettings.put( - CompilerOptions.OPTION_ReportUncheckedTypeOperation, - CompilerOptions.IGNORE); - } - - - /** - * Updates the error table in the Error Window. - */ - synchronized public void updateErrorTable() { - - try { - String[][] errorData = new String[problemsList.size()][3]; - for (int i = 0; i < problemsList.size(); i++) { - errorData[i][0] = problemsList.get(i).message; - errorData[i][1] = editor.getSketch() - .getCode(problemsList.get(i).tabIndex).getPrettyName(); - errorData[i][2] = problemsList.get(i).lineNumber + ""; - } - - if (errorWindow != null) { - DefaultTableModel tm = new DefaultTableModel(errorData, - XQErrorTable.columnNames); - if (errorWindow.isVisible()) { - errorWindow.updateTable(tm); - } - - // Update error table in the editor - editor.updateTable(tm); - - // A rotating slash animation on the title bar to show - // that error checker thread is running - - slashAnimationIndex++; - if (slashAnimationIndex == slashAnimation.length) { - slashAnimationIndex = 0; - } - if (editor != null) { - String info = slashAnimation[slashAnimationIndex] + " T:" - + (System.currentTimeMillis() - lastTimeStamp) - + "ms"; - errorWindow.setTitle("Problems - " - + editor.getSketch().getName() + " " + info); - } - } - - } catch (Exception e) { - System.out.println("Exception at updateErrorTable() " + e); - e.printStackTrace(); - stopThread(); - } - - } - - /** - * Repaints the textarea if required - */ - public void updatePaintedThingys() { - editor.getTextArea().repaint(); - updateEditorStatus(); - currentTab = editor.getSketch().getCodeIndex( - editor.getSketch().getCurrentCode()); - //System.out.println("awesome! " + currentTab + " LT " + lastTab); - if (currentTab != lastTab) { - textModified.incrementAndGet(); - lastTab = currentTab; - return; - } - - } - - /** - * Updates editor status bar, depending on whether the caret is on an error - * line or not - */ - public void updateEditorStatus() { - // editor.statusNotice("Position: " + - // editor.getTextArea().getCaretLine()); - boolean notFound = true; - for (ErrorMarker emarker : editor.errorBar.errorPoints) { - if (emarker.problem.lineNumber == editor.getTextArea() - .getCaretLine() + 1) { - if (emarker.type == ErrorMarker.Warning) { - editor.statusNotice(emarker.problem.message); - } - else { - editor.statusError(emarker.problem.message); - } - return; - } - } - if (notFound) { - editor.statusEmpty(); - } - } - - /** - * Maps offset from java code to pde code. Returns a bunch of offsets as array - * - * @param line - * - line number in java code - * @param offset - * - offset from the start of the 'line' - * @return int[0] - tab number, int[1] - line number in the int[0] tab, int[2] - * - line start offset, int[3] - offset from line start. int[2] and - * int[3] are on TODO - */ - public int[] JavaToPdeOffsets(int line, int offset){ - int codeIndex = 0; - - int x = line - mainClassOffset; - if (x < 0) { - // System.out.println("Negative line number " - // + problem.getSourceLineNumber() + " , offset " - // + mainClassOffset); - x = line - 2; // Another -1 for 0 index - if (x < programImports.size() && x >= 0) { - ImportStatement is = programImports.get(x); - // System.out.println(is.importName + ", " + is.tab + ", " - // + is.lineNumber); - return new int[] { is.tab, is.lineNumber }; - } else { - - // Some seriously ugly stray error, just can't find the source - // line! Simply return first line for first tab. - return new int[] { 0, 1 }; - } - - } - - try { - for (SketchCode sc : editor.getSketch().getCode()) { - if (sc.isExtension("pde")) { - int len = 0; - if (editor.getSketch().getCurrentCode().equals(sc)) { - len = Base.countLines(sc.getDocument().getText(0, - sc.getDocument().getLength())) + 1; - } else { - len = Base.countLines(sc.getProgram()) + 1; - } - - // System.out.println("x,len, CI: " + x + "," + len + "," - // + codeIndex); - - if (x >= len) { - - // We're in the last tab and the line count is greater - // than the no. - // of lines in the tab, - if (codeIndex >= editor.getSketch().getCodeCount() - 1) { - // System.out.println("Exceeds lc " + x + "," + len - // + problem.toString()); - // x = len - x = editor.getSketch().getCode(codeIndex) - .getLineCount(); - // TODO: Obtain line having last non-white space - // character in the code. - break; - } else { - x -= len; - codeIndex++; - } - } else { - - if (codeIndex >= editor.getSketch().getCodeCount()) { - codeIndex = editor.getSketch().getCodeCount() - 1; - } - break; - } - - } - } - } catch (Exception e) { - System.err - .println("Things got messed up in ErrorCheckerService.JavaToPdeOffset()"); - } - return new int[] { codeIndex, x }; - } - - public String getPDECodeAtLine(int tab, int linenumber){ - editor.getSketch().setCurrentCode(tab); - return editor.ta.getLineText(linenumber); - } - - /** - * Calculates the tab number and line number of the error in that particular - * tab. Provides mapping between pure java and pde code. - * - * @param problem - * - IProblem - * @return int[0] - tab number, int[1] - line number - */ - public int[] calculateTabIndexAndLineNumber(IProblem problem) { - // String[] lines = {};// = PApplet.split(sourceString, '\n'); - int codeIndex = 0; - - int x = problem.getSourceLineNumber() - mainClassOffset; - if (x < 0) { - // System.out.println("Negative line number " - // + problem.getSourceLineNumber() + " , offset " - // + mainClassOffset); - x = problem.getSourceLineNumber() - 2; // Another -1 for 0 index - if (x < programImports.size() && x >= 0) { - ImportStatement is = programImports.get(x); - // System.out.println(is.importName + ", " + is.tab + ", " - // + is.lineNumber); - return new int[] { is.tab, is.lineNumber }; - } else { - - // Some seriously ugly stray error, just can't find the source - // line! Simply return first line for first tab. - return new int[] { 0, 1 }; - } - - } - - try { - for (SketchCode sc : editor.getSketch().getCode()) { - if (sc.isExtension("pde")) { - int len = 0; - if (editor.getSketch().getCurrentCode().equals(sc)) { - len = Base.countLines(sc.getDocument().getText(0, - sc.getDocument().getLength())) + 1; - } else { - len = Base.countLines(sc.getProgram()) + 1; - } - - // System.out.println("x,len, CI: " + x + "," + len + "," - // + codeIndex); - - if (x >= len) { - - // We're in the last tab and the line count is greater - // than the no. - // of lines in the tab, - if (codeIndex >= editor.getSketch().getCodeCount() - 1) { - // System.out.println("Exceeds lc " + x + "," + len - // + problem.toString()); - // x = len - x = editor.getSketch().getCode(codeIndex) - .getLineCount(); - // TODO: Obtain line having last non-white space - // character in the code. - break; - } else { - x -= len; - codeIndex++; - } - } else { - - if (codeIndex >= editor.getSketch().getCodeCount()) { - codeIndex = editor.getSketch().getCodeCount() - 1; - } - break; - } - - } - } - } catch (Exception e) { - System.err - .println("Things got messed up in ErrorCheckerService.calculateTabIndexAndLineNumber()"); - } - - return new int[] { codeIndex, x }; - } - - /** - * Fetches code from the editor tabs and pre-processes it into parsable pure - * java source. And there's a difference between parsable and compilable. - * XQPrerocessor.java makes this code compilable.
- * Handles:
  • Removal of import statements
  • Conversion of int(), - * char(), etc to PApplet.parseInt(), etc.
  • Replacing '#' with 0xff for - * color representation
  • Converts all 'color' datatypes to int - * (experimental)
  • Appends class declaration statement after determining - * the mode the sketch is in - ACTIVE or STATIC - * - * @return String - Pure java representation of PDE code. Note that this - * code is not yet compile ready. - */ - - private String preprocessCode(String pdeCode) { - - programImports = new ArrayList(); - - StringBuffer rawCode = new StringBuffer(); - - try { - - for (SketchCode sc : editor.getSketch().getCode()) { - if (sc.isExtension("pde")) { - - try { - - if (editor.getSketch().getCurrentCode().equals(sc)) { - - rawCode.append(scrapImportStatements(sc.getDocument() - .getText(0, - sc.getDocument() - .getLength()), - editor.getSketch() - .getCodeIndex(sc))); - } else { - - rawCode.append(scrapImportStatements(sc.getProgram(), editor - .getSketch().getCodeIndex(sc))); - - } - rawCode.append('\n'); - } catch (Exception e) { - System.err.println("Exception in preprocessCode() - bigCode " - + e.toString()); - } - rawCode.append('\n'); - } - } - - } catch (Exception e) { - System.out.println("Exception in preprocessCode()"); - } - String sourceAlt = rawCode.toString(); - // Replace comments with whitespaces - // sourceAlt = scrubComments(sourceAlt); - - // Find all int(*), replace with PApplet.parseInt(*) - - // \bint\s*\(\s*\b , i.e all exclusive "int(" - - String dataTypeFunc[] = { "int", "char", "float", "boolean", "byte" }; - - for (String dataType : dataTypeFunc) { - String dataTypeRegexp = "\\b" + dataType + "\\s*\\("; - Pattern pattern = Pattern.compile(dataTypeRegexp); - Matcher matcher = pattern.matcher(sourceAlt); - - // while (matcher.find()) { - // System.out.print("Start index: " + matcher.start()); - // System.out.println(" End index: " + matcher.end() + " "); - // System.out.println("-->" + matcher.group() + "<--"); - // } - sourceAlt = matcher.replaceAll("PApplet.parse" - + Character.toUpperCase(dataType.charAt(0)) - + dataType.substring(1) + "("); - - } - - // Find all #[web color] and replace with 0xff[webcolor] - // Should be 6 digits only. - final String webColorRegexp = "#{1}[A-F|a-f|0-9]{6}\\W"; - Pattern webPattern = Pattern.compile(webColorRegexp); - Matcher webMatcher = webPattern.matcher(sourceAlt); - while (webMatcher.find()) { - // System.out.println("Found at: " + webMatcher.start()); - String found = sourceAlt.substring(webMatcher.start(), - webMatcher.end()); - // System.out.println("-> " + found); - sourceAlt = webMatcher.replaceFirst("0xff" + found.substring(1)); - webMatcher = webPattern.matcher(sourceAlt); - } - - // Replace all color data types with int - // Regex, Y U SO powerful? - final String colorTypeRegex = "color(?![a-zA-Z0-9_])(?=\\[*)(?!(\\s*\\())"; - Pattern colorPattern = Pattern.compile(colorTypeRegex); - Matcher colorMatcher = colorPattern.matcher(sourceAlt); - sourceAlt = colorMatcher.replaceAll("int"); - - checkForChangedImports(); - - className = (editor == null) ? "DefaultClass" : editor.getSketch() - .getName(); - - - // Check whether the code is being written in STATIC mode(no function - // declarations) - append class declaration and void setup() declaration - Matcher matcher = FUNCTION_DECL.matcher(sourceAlt); - if (!matcher.find()) { - sourceAlt = xqpreproc.prepareImports(programImports) + "public class " + className + " extends PApplet {\n" - + "public void setup() {\n" + sourceAlt - + "\nnoLoop();\n}\n" + "\n}\n"; - staticMode = true; - - } else { - sourceAlt = xqpreproc.prepareImports(programImports) + "public class " + className + " extends PApplet {\n" - + sourceAlt + "\n}"; - staticMode = false; - } - - int position = sourceAlt.indexOf("{") + 1; - mainClassOffset = 1; - for (int i = 0; i <= position; i++) { - if (sourceAlt.charAt(i) == '\n') { - mainClassOffset++; - } - } - if(staticMode) { - mainClassOffset++; - } - //mainClassOffset += 2; - // Handle unicode characters - sourceAlt = substituteUnicode(sourceAlt); - -// System.out.println("-->\n" + sourceAlt + "\n<--"); -// System.out.println("PDE code processed - " -// + editor.getSketch().getName()); - sourceCode = sourceAlt; - return sourceAlt; - - } - - /** - * The super method that highlights any ASTNode in the pde editor =D - * @param node - * @return true - if highlighting happened correctly. - */ - public boolean highlightNode(ASTNodeWrapper awrap){ - int pdeoffsets[] = awrap.getPDECodeOffsets(this); - int javaoffsets[] = awrap.getJavaCodeOffsets(this); - try { - scrollToErrorLine(editor, pdeoffsets[0], - pdeoffsets[1],javaoffsets[1], - javaoffsets[2]); - return true; - } catch (Exception e) { - - e.printStackTrace(); - } - return false; - } - - public boolean highlightNode(ASTNode node){ - ASTNodeWrapper awrap = new ASTNodeWrapper(node); - return highlightNode(awrap); - } - - /** - * Scrolls to the error source in code. And selects the line text. Used by - * XQErrorTable and ErrorBar - * - * @param errorIndex - * - index of error - */ - public void scrollToErrorLine(int errorIndex) { - if (editor == null) { - return; - } - - if (errorIndex < problemsList.size() && errorIndex >= 0) { - Problem p = problemsList.get(errorIndex); - scrollToErrorLine(p); - } - } - - public void scrollToErrorLine(Problem p) { - if (editor == null) { - return; - } - if (p == null) - return; - try { - editor.toFront(); - editor.getSketch().setCurrentCode(p.tabIndex); - - editor - .setSelection(editor.getTextArea() - .getLineStartNonWhiteSpaceOffset(p.lineNumber - 1) - + editor.getTextArea() - .getLineText(p.lineNumber - 1).trim().length(), - editor.getTextArea() - .getLineStartNonWhiteSpaceOffset(p.lineNumber - 1)); - editor.getTextArea().scrollTo(p.lineNumber - 1, 0); - editor.repaint(); - } catch (Exception e) { - System.err.println(e - + " : Error while selecting text in scrollToErrorLine()"); - e.printStackTrace(); - } - // System.out.println("---"); - } - - /** - * Static method for scroll to a particular line in the PDE. Also highlights - * the length of the text. Requires the editor instance as arguement. - * - * @param edt - * @param tabIndex - * @param lineNoInTab - * - line number in the corresponding tab - * @param lineStartOffset - * - selection start offset(from line start non-whitespace offset) - * @param length - * - length of selection - * @return - true, if scroll was successful - */ - public static boolean scrollToErrorLine(Editor edt, int tabIndex, int lineNoInTab, int lineStartOffset, int length) { - if (edt == null) { - return false; - } - try { - edt.toFront(); - edt.getSketch().setCurrentCode(tabIndex); - int lsno = edt.getTextArea() - .getLineStartNonWhiteSpaceOffset(lineNoInTab - 1) + lineStartOffset; - edt.setSelection(lsno, lsno + length); - edt.getTextArea().scrollTo(lineNoInTab - 1, 0); - edt.repaint(); - System.out.println(lineStartOffset + " LSO,len " + length); - } catch (Exception e) { - System.err.println(e - + " : Error while selecting text in static scrollToErrorLine()"); - e.printStackTrace(); - return false; - } - return true; - } - - /** - * Checks if import statements in the sketch have changed. If they have, - * compiler classpath needs to be updated. - */ - private void checkForChangedImports() { - // System.out.println("Imports: " + programImports.size() + - // " Prev Imp: " - // + previousImports.size()); - if (programImports.size() != previousImports.size()) { - // System.out.println(1); - loadCompClass = true; - previousImports = programImports; - } else { - for (int i = 0; i < programImports.size(); i++) { - if (!programImports.get(i).importName.equals(previousImports - .get(i).importName)) { - // System.out.println(2); - loadCompClass = true; - previousImports = programImports; - break; - } - } - } - // System.out.println("load..? " + loadCompClass); - } - - /** - * Removes import statements from tabSource, replaces each with white spaces - * and adds the import to the list of program imports - * - * @param tabProgram - * - Code in a tab - * @param tabNumber - * - index of the tab - * @return String - Tab code with imports replaced with white spaces - */ - private String scrapImportStatements(String tabProgram, int tabNumber) { - //TODO: Commented out imports are still detected as main imports. - String tabSource = new String(tabProgram); - do { - // System.out.println("-->\n" + sourceAlt + "\n<--"); - String[] pieces = PApplet.match(tabSource, importRegexp); - - // Stop the loop if we've removed all the import lines - if (pieces == null) { - break; - } - - String piece = pieces[1] + pieces[2] + pieces[3]; - int len = piece.length(); // how much to trim out - - // programImports.add(piece); // the package name - - // find index of this import in the program - int idx = tabSource.indexOf(piece); - // System.out.print("Import -> " + piece); - // System.out.println(" - " - // + Base.countLines(tabSource.substring(0, idx)) + " tab " - // + tabNumber); - programImports.add(new ImportStatement(piece, tabNumber, Base - .countLines(tabSource.substring(0, idx)))); - // Remove the import from the main program - // Substitute with white spaces - String whiteSpace = ""; - for (int j = 0; j < piece.length(); j++) { - whiteSpace += " "; - } - tabSource = tabSource.substring(0, idx) + whiteSpace - + tabSource.substring(idx + len); - - } while (true); - // System.out.println(tabSource); - return tabSource; - } - - /** - * Replaces non-ascii characters with their unicode escape sequences and - * stuff. Used as it is from - * processing.src.processing.mode.java.preproc.PdePreprocessor - * - * @param program - * - Input String containing non ascii characters - * @return String - Converted String - */ - public static String substituteUnicode(String program) { - // check for non-ascii chars (these will be/must be in unicode format) - char p[] = program.toCharArray(); - int unicodeCount = 0; - for (int i = 0; i < p.length; i++) { - if (p[i] > 127) { - unicodeCount++; - } - } - if (unicodeCount == 0) { - return program; - } - // if non-ascii chars are in there, convert to unicode escapes - // add unicodeCount * 5.. replacing each unicode char - // with six digit uXXXX sequence (xxxx is in hex) - // (except for nbsp chars which will be a replaced with a space) - int index = 0; - char p2[] = new char[p.length + unicodeCount * 5]; - for (int i = 0; i < p.length; i++) { - if (p[i] < 128) { - p2[index++] = p[i]; - } else if (p[i] == 160) { // unicode for non-breaking space - p2[index++] = ' '; - } else { - int c = p[i]; - p2[index++] = '\\'; - p2[index++] = 'u'; - char str[] = Integer.toHexString(c).toCharArray(); - // add leading zeros, so that the length is 4 - // for (int i = 0; i < 4 - str.length; i++) p2[index++] = '0'; - for (int m = 0; m < 4 - str.length; m++) - p2[index++] = '0'; - System.arraycopy(str, 0, p2, index, str.length); - index += str.length; - } - } - return new String(p2, 0, index); - } - - /** - * Stops the Error Checker Service thread - */ - public void stopThread() { - stopThread = true; - } - - /** - * Pauses the Error Checker Service thread - */ - public void pauseThread() { - pauseThread = true; - } - - /** - * Resumes the Error Checker Service thread - */ - public void resumeThread() { - pauseThread = false; - } - - public DebugEditor getEditor() { - return editor; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/ErrorMarker.java b/pdex/experimental/src/processing/mode/experimental/ErrorMarker.java deleted file mode 100755 index 0a10cff4b..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ErrorMarker.java +++ /dev/null @@ -1,36 +0,0 @@ -package processing.mode.experimental; -/** - * Error markers displayed on the Error Bar. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ - public class ErrorMarker { - /** - * y co-ordinate of the marker - */ - public int y; - /** - * Type of marker: Error or Warning? - */ - public int type = -1; - /** - * Error Type constant - */ - public static final int Error = 1; - /** - * Warning Type constant - */ - public static final int Warning = 2; - /** - * Problem that the error marker represents - * @see Problem - */ - public Problem problem; - - public ErrorMarker(Problem problem, int y, int type) { - this.problem = problem; - this.y = y; - this.type = type; - } - } \ No newline at end of file diff --git a/pdex/experimental/src/processing/mode/experimental/ErrorWindow.java b/pdex/experimental/src/processing/mode/experimental/ErrorWindow.java deleted file mode 100755 index 6494b58ed..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ErrorWindow.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package processing.mode.experimental; - -import java.awt.BorderLayout; -import java.awt.Frame; -import java.awt.Point; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.WindowConstants; -import javax.swing.border.EmptyBorder; -import javax.swing.table.TableModel; - -import processing.app.Editor; -import processing.app.Toolkit; - -/** - * Error Window that displays a tablular list of errors. Clicking on an error - * scrolls to its location in the code. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class ErrorWindow extends JFrame { - - private JPanel contentPane; - /** - * The table displaying the errors - */ - protected XQErrorTable errorTable; - /** - * Scroll pane that contains the Error Table - */ - protected JScrollPane scrollPane; - - protected DebugEditor thisEditor; - private JFrame thisErrorWindow; - - /** - * Handles the sticky Problem window - */ - private DockTool2Base Docker; - - protected ErrorCheckerService errorCheckerService; - - /** - * Preps up ErrorWindow - * - * @param editor - * - Editor - * @param ecs - ErrorCheckerService - */ - public ErrorWindow(DebugEditor editor, ErrorCheckerService ecs) { - thisErrorWindow = this; - errorCheckerService = ecs; - thisEditor = editor; - setTitle("Problems"); - prepareFrame(); - } - - /** - * Sets up ErrorWindow - */ - protected void prepareFrame() { - Toolkit.setIcon(this); - setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); - // Default size: setBounds(100, 100, 458, 160); - setBounds(100, 100, 458, 160); // Yeah, I hardcode such things sometimes. Hate me. - - contentPane = new JPanel(); - contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); - setContentPane(contentPane); - contentPane.setLayout(new BorderLayout(0, 0)); - - scrollPane = new JScrollPane(); - contentPane.add(scrollPane); - - errorTable = new XQErrorTable(errorCheckerService); - scrollPane.setViewportView(errorTable); - - try { - Docker = new DockTool2Base(); - addListeners(); - } catch (Exception e) { - System.out.println("addListeners() acted silly."); - e.printStackTrace(); - } - - if (thisEditor != null) { - setLocation(new Point(thisEditor.getLocation().x - + thisEditor.getWidth(), thisEditor.getLocation().y)); - } - - } - - /** - * Updates the error table with new data(Table Model). Called from Error - * Checker Service. - * - * @param tableModel - * - Table Model - * @return True - If error table was updated successfully. - */ - synchronized public boolean updateTable(final TableModel tableModel) { - // XQErrorTable handles evrything now - return errorTable.updateTable(tableModel); - } - - /** - * Adds various listeners to components of EditorWindow and to the Editor - * window - */ - protected void addListeners() { - - if (thisErrorWindow == null) - System.out.println("ERW null"); - - thisErrorWindow.addComponentListener(new ComponentListener() { - - @Override - public void componentShown(ComponentEvent e) { - - } - - @Override - public void componentResized(ComponentEvent e) { - Docker.tryDocking(); - } - - @Override - public void componentMoved(ComponentEvent e) { - Docker.tryDocking(); - } - - @Override - public void componentHidden(ComponentEvent e) { - - } - }); - - thisErrorWindow.addWindowListener(new WindowAdapter() { - - @Override - public void windowClosing(WindowEvent e) { - thisEditor.problemWindowMenuCB.setSelected(false); - } - - @Override - public void windowDeiconified(WindowEvent e) { - thisEditor.setExtendedState(Frame.NORMAL); - } - - }); - - if (thisEditor == null) { - System.out.println("Editor null"); - return; - } - - thisEditor.addWindowListener(new WindowAdapter() { - - @Override - public void windowClosing(WindowEvent e) { - - } - - @Override - public void windowClosed(WindowEvent e) { - errorCheckerService.pauseThread(); - errorCheckerService.stopThread(); // Bye bye thread. - thisErrorWindow.dispose(); - } - - @Override - public void windowIconified(WindowEvent e) { - thisErrorWindow.setExtendedState(Frame.ICONIFIED); - } - - @Override - public void windowDeiconified(WindowEvent e) { - thisErrorWindow.setExtendedState(Frame.NORMAL); - } - - }); - - thisEditor.addComponentListener(new ComponentListener() { - - @Override - public void componentShown(ComponentEvent e) { - - } - - @Override - public void componentResized(ComponentEvent e) { - if (Docker.isDocked()) { - Docker.dock(); - } else { - Docker.tryDocking(); - } - } - - @Override - public void componentMoved(ComponentEvent e) { - - if (Docker.isDocked()) { - Docker.dock(); - } else { - Docker.tryDocking(); - } - - } - - @Override - public void componentHidden(ComponentEvent e) { - // System.out.println("ed hidden"); - } - }); - - } - - - /** - * Implements the docking feature of the tool - The frame sticks to the - * editor and once docked, moves along with it as the editor is resized, - * moved, or closed. - * - * This class has been borrowed from Tab Manager tool by Thomas Diewald. It - * has been slightly modified and used here. - * - * @author Thomas Diewald , http://thomasdiewald.com - */ - private class DockTool2Base { - - private int docking_border = 0; - private int dock_on_editor_y_offset_ = 0; - private int dock_on_editor_x_offset_ = 0; - - // /////////////////////////////// - // ____2____ - // | | - // | | - // 0 | editor | 1 - // | | - // |_________| - // 3 - // /////////////////////////////// - - // public void reset() { - // dock_on_editor_y_offset_ = 0; - // dock_on_editor_x_offset_ = 0; - // docking_border = 0; - // } - - public boolean isDocked() { - return (docking_border >= 0); - } - - private final int MAX_GAP_ = 20; - - // - public void tryDocking() { - if (thisEditor == null) - return; - Editor editor = thisEditor; - Frame frame = thisErrorWindow; - - int ex = editor.getX(); - int ey = editor.getY(); - int ew = editor.getWidth(); - int eh = editor.getHeight(); - - int fx = frame.getX(); - int fy = frame.getY(); - int fw = frame.getWidth(); - int fh = frame.getHeight(); - - if (((fy > ey) && (fy < ey + eh)) - || ((fy + fh > ey) && (fy + fh < ey + eh))) { - int dis_border_left = Math.abs(ex - (fx + fw)); - int dis_border_right = Math.abs((ex + ew) - (fx)); - - if (dis_border_left < MAX_GAP_ || dis_border_right < MAX_GAP_) { - docking_border = (dis_border_left < dis_border_right) ? 0 - : 1; - dock_on_editor_y_offset_ = fy - ey; - dock(); - return; - } - } - - if (((fx > ex) && (fx < ex + ew)) - || ((fx + fw > ey) && (fx + fw < ex + ew))) { - int dis_border_top = Math.abs(ey - (fy + fh)); - int dis_border_bot = Math.abs((ey + eh) - (fy)); - - if (dis_border_top < MAX_GAP_ || dis_border_bot < MAX_GAP_) { - docking_border = (dis_border_top < dis_border_bot) ? 2 : 3; - dock_on_editor_x_offset_ = fx - ex; - dock(); - return; - } - } - docking_border = -1; - } - - public void dock() { - if (thisEditor == null) - return; - Editor editor = thisEditor; - Frame frame = thisErrorWindow; - - int ex = editor.getX(); - int ey = editor.getY(); - int ew = editor.getWidth(); - int eh = editor.getHeight(); - - // int fx = frame.getX(); - // int fy = frame.getY(); - int fw = frame.getWidth(); - int fh = frame.getHeight(); - - int x = 0, y = 0; - if (docking_border == -1) { - return; - } - - if (docking_border == 0) { - x = ex - fw; - y = ey + dock_on_editor_y_offset_; - } - if (docking_border == 1) { - x = ex + ew; - y = ey + dock_on_editor_y_offset_; - } - - if (docking_border == 2) { - x = ex + dock_on_editor_x_offset_; - y = ey - fh; - } - if (docking_border == 3) { - x = ex + dock_on_editor_x_offset_; - y = ey + eh; - } - frame.setLocation(x, y); - } - - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/ExperimentalMode.java b/pdex/experimental/src/processing/mode/experimental/ExperimentalMode.java deleted file mode 100755 index 50d7ce4b3..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ExperimentalMode.java +++ /dev/null @@ -1,171 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012 The Processing Foundation - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.mode.experimental; - -import java.awt.Color; -import java.io.File; -import java.io.IOException; -import java.util.logging.FileHandler; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import processing.app.Base; -import processing.app.Editor; -import processing.app.EditorState; -import processing.app.Mode; -import processing.mode.java.JavaMode; - - -/** - * Experimental Mode for Processing, combines Debug Mode and XQMode and - * starts us working toward our next generation editor/debugger setup. - */ -public class ExperimentalMode extends JavaMode { - public static final boolean VERBOSE_LOGGING = true; - //public static final boolean VERBOSE_LOGGING = false; - public static final int LOG_SIZE = 512 * 1024; // max log file size (in bytes) - - - public ExperimentalMode(Base base, File folder) { - super(base, folder); - - // use libraries folder from javamode. will make sketches using core libraries work, as well as import libraries and examples menus - for (Mode m : base.getModeList()) { - if (m.getClass() == JavaMode.class) { - JavaMode jMode = (JavaMode) m; - librariesFolder = jMode.getLibrariesFolder(); - rebuildLibraryList(); - break; - } - } - - // Fetch examples and reference from java mode - // thx to Manindra (https://github.com/martinleopold/DebugMode/issues/4) - examplesFolder = Base.getContentFile("modes/java/examples"); - // https://github.com/martinleopold/DebugMode/issues/6 - referenceFolder = Base.getContentFile("modes/java/reference"); - - // set logging level - Logger globalLogger = Logger.getLogger(""); - //Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); // doesn't work on os x - if (VERBOSE_LOGGING) { - globalLogger.setLevel(Level.INFO); - } else { - globalLogger.setLevel(Level.WARNING); - } - - // enable logging to file - try { - // settings is writable for built-in modes, mode folder is not writable - File logFolder = Base.getSettingsFile("debug"); - if (!logFolder.exists()) { - logFolder.mkdir(); - } - File logFile = new File(logFolder, "DebugMode.%g.log"); - Handler handler = new FileHandler(logFile.getAbsolutePath(), LOG_SIZE, 10, false); - globalLogger.addHandler(handler); - - } catch (IOException ex) { - Logger.getLogger(ExperimentalMode.class.getName()).log(Level.SEVERE, null, ex); - } catch (SecurityException ex) { - Logger.getLogger(ExperimentalMode.class.getName()).log(Level.SEVERE, null, ex); - } - - // disable initial chattiness for now -// // output version from manifest file -// Package p = ExperimentalMode.class.getPackage(); -// String titleAndVersion = p.getImplementationTitle() + " (v" + p.getImplementationVersion() + ")"; -// //System.out.println(titleAndVersion); -// Logger.getLogger(ExperimentalMode.class.getName()).log(Level.INFO, titleAndVersion); - } - - - @Override - public String getTitle() { - return "Experimental"; - } - - - public File[] getKeywordFiles() { - return new File[] { - Base.getContentFile("modes/java/keywords.txt") - }; - } - - - /** - * Create a new editor associated with this mode. - */ - @Override - public Editor createEditor(Base base, String path, EditorState state) { - return new DebugEditor(base, path, state, this); - } - - - /** - * Load a String value from theme.txt - * - * @param attribute the attribute key to load - * @param defaultValue the default value - * @return the attributes value, or the default value if the attribute - * couldn't be loaded - */ - public String loadThemeString(String attribute, String defaultValue) { - String newString = theme.get(attribute); - if (newString != null) { - return newString; - } - Logger.getLogger(getClass().getName()).log(Level.WARNING, "Error loading String: {0}", attribute); - return defaultValue; - } - - - /** - * Load a Color value from theme.txt - * - * @param attribute the attribute key to load - * @param defaultValue the default value - * @return the attributes value, or the default value if the attribute - * couldn't be loaded - */ - public Color getThemeColor(String attribute, Color defaultValue) { - Color newColor = theme.getColor(attribute); - if (newColor != null) { - return newColor; - } - System.out.println("error loading color: " + attribute); - Logger.getLogger(ExperimentalMode.class.getName()).log(Level.WARNING, "Error loading Color: {0}", attribute); - return defaultValue; - } - - - public ClassLoader getJavaModeClassLoader() { - for (Mode m : base.getModeList()) { - if (m.getClass() == JavaMode.class) { - JavaMode jMode = (JavaMode) m; - return jMode.getClassLoader(); - } - } - // badness - return null; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/FieldNode.java b/pdex/experimental/src/processing/mode/experimental/FieldNode.java deleted file mode 100755 index dbe9d4fd9..000000000 --- a/pdex/experimental/src/processing/mode/experimental/FieldNode.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.Field; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Specialized {@link VariableNode} for representing fields. Overrides - * {@link #setValue} to properly change the value of the encapsulated field. - * - * @author Martin Leopold - */ -public class FieldNode extends VariableNode { - - protected Field field; - protected ObjectReference obj; - - /** - * Construct a {@link FieldNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param field the field - * @param obj a reference to the object containing the field - */ - public FieldNode(String name, String type, Value value, Field field, ObjectReference obj) { - super(name, type, value); - this.field = field; - this.obj = obj; - } - - @Override - public void setValue(Value value) { - try { - obj.setValue(field, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(FieldNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(FieldNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/ImportStatement.java b/pdex/experimental/src/processing/mode/experimental/ImportStatement.java deleted file mode 100755 index 26d2db7d1..000000000 --- a/pdex/experimental/src/processing/mode/experimental/ImportStatement.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package processing.mode.experimental; - -/** - * Wrapper for import statements - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class ImportStatement { - /** - * Ex: processing.opengl.*, java.util.* - */ - String importName; - /** - * Which tab does it belong to? - */ - int tab; - - /** - * Line number(pde code) of the import - */ - int lineNumber; - - /** - * - * @param importName - Ex: processing.opengl.*, java.util.* - * @param tab - Which tab does it belong to? - * @param lineNumber - Line number(pde code) of the import - */ - public ImportStatement(String importName, int tab, int lineNumber) { - this.importName = importName; - this.tab = tab; - this.lineNumber = lineNumber; - } -} \ No newline at end of file diff --git a/pdex/experimental/src/processing/mode/experimental/JavadocHelper.java b/pdex/experimental/src/processing/mode/experimental/JavadocHelper.java deleted file mode 100644 index 7cc582072..000000000 --- a/pdex/experimental/src/processing/mode/experimental/JavadocHelper.java +++ /dev/null @@ -1,126 +0,0 @@ -package processing.mode.experimental; - -import java.io.File; -import java.io.FileFilter; -import java.util.Iterator; -import java.util.TreeMap; - -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -public class JavadocHelper { - - public static void loadJavaDoc(TreeMap jdocMap, File p5Ref){ - Document doc; - - //Pattern pat = Pattern.compile("\\w+"); - try { - if (p5Ref == null) { - System.out.println("P5 Ref location null"); - p5Ref = new File( - "/home/quarkninja/Workspaces/processing-workspace/processing/build/linux/work/modes/java/reference"); - } - - FileFilter fileFilter = new FileFilter() { - public boolean accept(File file) { - if(!file.getName().endsWith("_.html")) - return false; - int k = 0; - for (int i = 0; i < file.getName().length(); i++) { - if(file.getName().charAt(i)== '_') - k++; - if(k > 1) - return false; - } - return true; - } - }; - - for (File docFile : p5Ref.listFiles(fileFilter)) { - - doc = Jsoup.parse(docFile, null); - Elements elm = doc.getElementsByClass("ref-item"); - String msg = ""; - String methodName = docFile.getName().substring(0, docFile.getName().indexOf('_')); - //System.out.println(methodName); - for (Iterator it = elm.iterator(); it.hasNext();) { - Element ele = (Element) it.next(); - msg = "
    " - + ele.html() + "
    "; - //mat.replaceAll(""); - msg = msg.replaceAll("img src=\"", "img src=\"" - + p5Ref.toURI().toURL().toString() + "/"); - //System.out.println(ele.text()); - } - jdocMap.put(methodName, msg); - } - System.out.println("JDoc loaded "+jdocMap.size()); - /* File javaDocFile = new File( - "/home/quarkninja/Workspaces/processing-workspace/processing/build/javadoc/core/processing/core/PApplet.html"); - //SimpleOpenNI.SimpleOpenNI - doc = Jsoup.parse(javaDocFile, null); - - String msg = ""; - Elements elm = doc.getElementsByTag("pre"); -// Elements desc = doc.getElementsByTag("dl"); - //System.out.println(elm.toString()); - - for (Iterator iterator = elm.iterator(); iterator.hasNext();) { - Element element = (Element) iterator.next(); - - //System.out.println(element.text()); -// if (element.nextElementSibling() != null) -// System.out.println(element.nextElementSibling().text()); - //System.out.println("-------------------"); - msg = "
    " - + element.html() - + element.nextElementSibling() - + "
    "; - int k = 0; - Matcher matcher = pat.matcher(element.text()); - ArrayList parts = new ArrayList(); - while (matcher.find()) { -// System.out.print("Start index: " + matcher.start()); -// System.out.print(" End index: " + matcher.end() + " "); - if (k == 0 && !matcher.group().equals("public")) { - k = -1; - break; - } - // System.out.print(matcher.group() + " "); - parts.add(matcher.group()); - k++; - } - if (k <= 0 || parts.size() < 3) - continue; - int i = 0; - if (parts.get(i).equals("public")) - i++; - if (parts.get(i).equals("static") || parts.get(i).equals("final") - || parts.get(i).equals("class")) - i++; - if (parts.get(i).equals("static") || parts.get(i).equals("final")) - i++; -// System.out.println("Ret Type " + parts.get(i)); - - i++; // return type - - //System.out.println("Name " + parts.get(i)); - jdocMap.put(parts.get(i), msg); - } - -// for (String key : jdocMap.keySet()) { -// System.out.println("Method: " + key); -// System.out.println("Method: " + jdocMap.get(key)); -// } - * - */ - } catch (Exception e) { - e.printStackTrace(); - } - - - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/LineBreakpoint.java b/pdex/experimental/src/processing/mode/experimental/LineBreakpoint.java deleted file mode 100755 index 8d006fd9d..000000000 --- a/pdex/experimental/src/processing/mode/experimental/LineBreakpoint.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.AbsentInformationException; -import com.sun.jdi.Location; -import com.sun.jdi.ReferenceType; -import com.sun.jdi.request.BreakpointRequest; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Model/Controller of a line breakpoint. Can be set before or while debugging. - * Adds a highlight using the debuggers view ({@link DebugEditor}). - * - * @author Martin Leopold - */ -public class LineBreakpoint implements ClassLoadListener { - - protected Debugger dbg; // the debugger - protected LineID line; // the line this breakpoint is set on - protected BreakpointRequest bpr; // the request on the VM's event request manager - protected ReferenceType theClass; // the class containing this breakpoint, null when not yet loaded - - /** - * Create a {@link LineBreakpoint}. If in a debug session, will try to - * immediately set the breakpoint. If not in a debug session or the - * corresponding class is not yet loaded the breakpoint will activate on - * class load. - * - * @param line the line id to create the breakpoint on - * @param dbg the {@link Debugger} - */ - public LineBreakpoint(LineID line, Debugger dbg) { - this.line = line; - line.startTracking(dbg.editor().getTab(line.fileName()).getDocument()); - this.dbg = dbg; - theClass = dbg.getClass(className()); // try to get the class immediately, may return null if not yet loaded - set(); // activate the breakpoint (show highlight, attach if debugger is running) - } - - /** - * Create a {@link LineBreakpoint} on a line in the current tab. - * - * @param lineIdx the line index of the current tab to create the breakpoint - * on - * @param dbg the {@link Debugger} - */ - // TODO: remove and replace by {@link #LineBreakpoint(LineID line, Debugger dbg)} - public LineBreakpoint(int lineIdx, Debugger dbg) { - this(dbg.editor().getLineIDInCurrentTab(lineIdx), dbg); - } - - /** - * Get the line id this breakpoint is on. - * - * @return the line id - */ - public LineID lineID() { - return line; - } - - /** - * Test if this breakpoint is on a certain line. - * - * @param testLine the line id to test - * @return true if this breakpoint is on the given line - */ - public boolean isOnLine(LineID testLine) { - return line.equals(testLine); - } - - /** - * Attach this breakpoint to the VM. Creates and enables a - * {@link BreakpointRequest}. VM needs to be paused. - */ - protected void attach() { - if (!dbg.isPaused()) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "can't attach breakpoint, debugger not paused"); - return; - } - - if (theClass == null) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "can't attach breakpoint, class not loaded: {0}", className()); - return; - } - - // find line in java space - LineID javaLine = dbg.sketchToJavaLine(line); - if (javaLine == null) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "couldn't find line {0} in the java code", line); - return; - } - try { - List locations = theClass.locationsOfLine(javaLine.lineIdx() + 1); - if (locations.isEmpty()) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "no location found for line {0} -> {1}", new Object[]{line, javaLine}); - return; - } - // use first found location - bpr = dbg.vm().eventRequestManager().createBreakpointRequest(locations.get(0)); - bpr.enable(); - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.INFO, "attached breakpoint to {0} -> {1}", new Object[]{line, javaLine}); - } catch (AbsentInformationException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Detach this breakpoint from the VM. Deletes the - * {@link BreakpointRequest}. - */ - protected void detach() { - if (bpr != null) { - dbg.vm().eventRequestManager().deleteEventRequest(bpr); - bpr = null; - } - } - - /** - * Set this breakpoint. Adds the line highlight. If Debugger is paused also - * attaches the breakpoint by calling {@link #attach()}. - */ - protected void set() { - dbg.addClassLoadListener(this); // class may not yet be loaded - dbg.editor().addBreakpointedLine(line); - if (theClass != null && dbg.isPaused()) { // class is loaded - // immediately activate the breakpoint - attach(); - } - if (dbg.editor().isInCurrentTab(line)) { - dbg.editor().getSketch().setModified(true); - } - } - - /** - * Remove this breakpoint. Clears the highlight and detaches the breakpoint - * if the debugger is paused. - */ - public void remove() { - dbg.removeClassLoadListener(this); - //System.out.println("removing " + line.lineIdx()); - dbg.editor().removeBreakpointedLine(line.lineIdx()); - if (dbg.isPaused()) { - // immediately remove the breakpoint - detach(); - } - line.stopTracking(); - if (dbg.editor().isInCurrentTab(line)) { - dbg.editor().getSketch().setModified(true); - } - } - -// public void enable() { -// } -// -// public void disable() { -// } - @Override - public String toString() { - return line.toString(); - } - - /** - * Get the name of the class this breakpoint belongs to. Needed for fetching - * the right location to create a breakpoint request. - * - * @return the class name - */ - protected String className() { - if (line.fileName().endsWith(".pde")) { - // standard tab - ReferenceType mainClass = dbg.getMainClass(); - if (mainClass == null) { - return null; - } - return dbg.getMainClass().name(); - } - - if (line.fileName().endsWith(".java")) { - // pure java tab - return line.fileName().substring(0, line.fileName().lastIndexOf(".java")); - } - - return null; - } - - /** - * Event handler called when a class is loaded in the debugger. Causes the - * breakpoint to be attached, if its class was loaded. - * - * @param theClass the class that was just loaded. - */ - @Override - public void classLoaded(ReferenceType theClass) { - // check if our class is being loaded - if (theClass.name().equals(className())) { - this.theClass = theClass; - attach(); - } - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/LineHighlight.java b/pdex/experimental/src/processing/mode/experimental/LineHighlight.java deleted file mode 100755 index c1789cf24..000000000 --- a/pdex/experimental/src/processing/mode/experimental/LineHighlight.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.awt.Color; -import java.util.HashSet; -import java.util.Set; - -/** - * Model/Controller for a highlighted source code line. Implements a custom - * background color and a text based marker placed in the left-hand gutter area. - * - * @author Martin Leopold - */ -public class LineHighlight implements LineListener { - - protected DebugEditor editor; // the view, used for highlighting lines by setting a background color - protected Color bgColor; // the background color for highlighting lines - protected LineID lineID; // the id of the line - protected String marker; // - protected Color markerColor; - protected int priority = 0; - protected static Set allHighlights = new HashSet(); - - protected static boolean isHighestPriority(LineHighlight hl) { - for (LineHighlight check : allHighlights) { - if (check.lineID().equals(hl.lineID()) && check.priority() > hl.priority()) { - return false; - } - } - return true; - } - - /** - * Create a {@link LineHighlight}. - * - * @param lineID the line id to highlight - * @param bgColor the background color used for highlighting - * @param editor the {@link DebugEditor} - */ - public LineHighlight(LineID lineID, Color bgColor, DebugEditor editor) { - this.lineID = lineID; - this.bgColor = bgColor; - this.editor = editor; - lineID.addListener(this); - lineID.startTracking(editor.getTab(lineID.fileName()).getDocument()); // TODO: overwrite a previous doc? - paint(); // already checks if on current tab - allHighlights.add(this); - } - - public void setPriority(int p) { - this.priority = p; - } - - public int priority() { - return priority; - } - - /** - * Create a {@link LineHighlight} on the current tab. - * - * @param lineIdx the line index on the current tab to highlight - * @param bgColor the background color used for highlighting - * @param editor the {@link DebugEditor} - */ - // TODO: Remove and replace by {@link #LineHighlight(LineID lineID, Color bgColor, DebugEditor editor)} - public LineHighlight(int lineIdx, Color bgColor, DebugEditor editor) { - this(editor.getLineIDInCurrentTab(lineIdx), bgColor, editor); - } - - /** - * Set a text based marker displayed in the left hand gutter area of this - * highlighted line. - * - * @param marker the marker text - */ - public void setMarker(String marker) { - this.marker = marker; - paint(); - } - - /** - * Set a text based marker displayed in the left hand gutter area of this - * highlighted line. Also use a custom text color. - * - * @param marker the marker text - * @param markerColor the text color - */ - public void setMarker(String marker, Color markerColor) { - this.markerColor = markerColor; - setMarker(marker); - } - - /** - * Retrieve the line id of this {@link LineHighlight}. - * - * @return the line id - */ - public LineID lineID() { - return lineID; - } - - /** - * Retrieve the color for highlighting this line. - * - * @return the highlight color. - */ - public Color getColor() { - return bgColor; - } - - /** - * Test if this highlight is on a certain line. - * - * @param testLine the line to test - * @return true if this highlight is on the given line - */ - public boolean isOnLine(LineID testLine) { - return lineID.equals(testLine); - } - - /** - * Event handler for line number changes (due to editing). Will remove the - * highlight from the old line number and repaint it at the new location. - * - * @param line the line that has changed - * @param oldLineIdx the old line index (0-based) - * @param newLineIdx the new line index (0-based) - */ - @Override - public void lineChanged(LineID line, int oldLineIdx, int newLineIdx) { - // clear old line - if (editor.isInCurrentTab(new LineID(line.fileName(), oldLineIdx))) { - editor.textArea().clearLineBgColor(oldLineIdx); - editor.textArea().clearGutterText(oldLineIdx); - } - - // paint new line - // but only if it's on top -> fixes current line being hidden by breakpoint moving it down. - // lineChanged events seem to come in inverse order of startTracking the LineID. (and bp is created first...) - if (LineHighlight.isHighestPriority(this)) { - paint(); - } - } - - /** - * Notify this line highlight that it is no longer used. Call this for - * cleanup before the {@link LineHighlight} is discarded. - */ - public void dispose() { - lineID.removeListener(this); - lineID.stopTracking(); - allHighlights.remove(this); - } - - /** - * (Re-)paint this line highlight. - */ - public void paint() { - if (editor.isInCurrentTab(lineID)) { - editor.textArea().setLineBgColor(lineID.lineIdx(), bgColor); - if (marker != null) { - if (markerColor != null) { - editor.textArea().setGutterText(lineID.lineIdx(), marker, markerColor); - } else { - editor.textArea().setGutterText(lineID.lineIdx(), marker); - } - } - } - } - - /** - * Clear this line highlight. - */ - public void clear() { - if (editor.isInCurrentTab(lineID)) { - editor.textArea().clearLineBgColor(lineID.lineIdx()); - editor.textArea().clearGutterText(lineID.lineIdx()); - } - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/LineID.java b/pdex/experimental/src/processing/mode/experimental/LineID.java deleted file mode 100755 index a08d21296..000000000 --- a/pdex/experimental/src/processing/mode/experimental/LineID.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.Position; - -/** - * Describes an ID for a code line. Comprised of a file name and a (0-based) - * line number. Can track changes to the line number due to text editing by - * attaching a {@link Document}. Registered {@link LineListener}s are notified - * of changes to the line number. - * - * @author Martin Leopold - */ -public class LineID implements DocumentListener { - - protected String fileName; // the filename - protected int lineIdx; // the line number, 0-based - protected Document doc; // the Document to use for line number tracking - protected Position pos; // the Position acquired during line number tracking - protected Set listeners = new HashSet(); // listeners for line number changes - - public LineID(String fileName, int lineIdx) { - this.fileName = fileName; - this.lineIdx = lineIdx; - } - - /** - * Get the file name of this line. - * - * @return the file name - */ - public String fileName() { - return fileName; - } - - /** - * Get the (0-based) line number of this line. - * - * @return the line index (i.e. line number, starting at 0) - */ - public synchronized int lineIdx() { - return lineIdx; - } - - @Override - public int hashCode() { - return toString().hashCode(); - } - - /** - * Test whether this {@link LineID} is equal to another object. Two - * {@link LineID}'s are equal when both their fileName and lineNo are equal. - * - * @param obj the object to test for equality - * @return {@code true} if equal - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final LineID other = (LineID) obj; - if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) { - return false; - } - if (this.lineIdx != other.lineIdx) { - return false; - } - return true; - } - - /** - * Output a string representation in the form fileName:lineIdx+1. Note this - * uses a 1-based line number as is customary for human-readable line - * numbers. - * - * @return the string representation of this line ID - */ - @Override - public String toString() { - return fileName + ":" + (lineIdx + 1); - } - -// /** -// * Retrieve a copy of this line ID. -// * -// * @return the copy -// */ -// @Override -// public LineID clone() { -// return new LineID(fileName, lineIdx); -// } - - /** - * Attach a {@link Document} to enable line number tracking when editing. - * The position to track is before the first non-whitespace character on the - * line. Edits happening before that position will cause the line number to - * update accordingly. Multiple {@link #startTracking} calls will replace - * the tracked document. Whoever wants a tracked line should track it and - * add itself as listener if necessary. - * ({@link LineHighlight}, {@link LineBreakpoint}) - * - * @param doc the {@link Document} to use for line number tracking - */ - public synchronized void startTracking(Document doc) { - //System.out.println("tracking: " + this); - if (doc == null) { - return; // null arg - } - if (doc == this.doc) { - return; // already tracking that doc - } - try { - Element line = doc.getDefaultRootElement().getElement(lineIdx); - if (line == null) { - return; // line doesn't exist - } - String lineText = doc.getText(line.getStartOffset(), line.getEndOffset() - line.getStartOffset()); - // set tracking position at (=before) first non-white space character on line - pos = doc.createPosition(line.getStartOffset() + nonWhiteSpaceOffset(lineText)); - this.doc = doc; - doc.addDocumentListener(this); - } catch (BadLocationException ex) { - Logger.getLogger(LineID.class.getName()).log(Level.SEVERE, null, ex); - pos = null; - this.doc = null; - } - } - - /** - * Notify this {@link LineID} that it is no longer in use. Will stop - * position tracking. Call this when this {@link LineID} is no longer - * needed. - */ - public synchronized void stopTracking() { - if (doc != null) { - doc.removeDocumentListener(this); - doc = null; - } - } - - /** - * Update the tracked position. Will notify listeners if line number has - * changed. - */ - protected synchronized void updatePosition() { - if (doc != null && pos != null) { - // track position - int offset = pos.getOffset(); - int oldLineIdx = lineIdx; - lineIdx = doc.getDefaultRootElement().getElementIndex(offset); // offset to lineNo - if (lineIdx != oldLineIdx) { - for (LineListener l : listeners) { - if (l != null) { - l.lineChanged(this, oldLineIdx, lineIdx); - } else { - listeners.remove(l); // remove null listener - } - } - } - } - } - - /** - * Add listener to be notified when the line number changes. - * - * @param l the listener to add - */ - public void addListener(LineListener l) { - listeners.add(l); - } - - /** - * Remove a listener for line number changes. - * - * @param l the listener to remove - */ - public void removeListener(LineListener l) { - listeners.remove(l); - } - - /** - * Calculate the offset of the first non-whitespace character in a string. - * - * @param str the string to examine - * @return offset of first non-whitespace character in str - */ - protected static int nonWhiteSpaceOffset(String str) { - for (int i = 0; i < str.length(); i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return i; - } - } - return str.length(); - } - - /** - * Called when the {@link Document} registered using {@link #startTracking} - * is edited. This happens when text is inserted or removed. - * - * @param de - */ - protected void editEvent(DocumentEvent de) { - //System.out.println("document edit @ " + de.getOffset()); - if (de.getOffset() <= pos.getOffset()) { - updatePosition(); - //System.out.println("updating, new line no: " + lineNo); - } - } - - /** - * {@link DocumentListener} callback. Called when text is inserted. - * - * @param de - */ - @Override - public void insertUpdate(DocumentEvent de) { - editEvent(de); - } - - /** - * {@link DocumentListener} callback. Called when text is removed. - * - * @param de - */ - @Override - public void removeUpdate(DocumentEvent de) { - editEvent(de); - } - - /** - * {@link DocumentListener} callback. Called when attributes are changed. - * Not used. - * - * @param de - */ - @Override - public void changedUpdate(DocumentEvent de) { - // not needed. - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/LineListener.java b/pdex/experimental/src/processing/mode/experimental/LineListener.java deleted file mode 100755 index c6c3ae1b0..000000000 --- a/pdex/experimental/src/processing/mode/experimental/LineListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -/** - * A Listener for line number changes. - * - * @author Martin Leopold - */ -public interface LineListener { - - /** - * Event handler for line number changes (due to editing). - * - * @param line the line that has changed - * @param oldLineIdx the old line index (0-based) - * @param newLineIdx the new line index (0-based) - */ - void lineChanged(LineID line, int oldLineIdx, int newLineIdx); -} diff --git a/pdex/experimental/src/processing/mode/experimental/LocalVariableNode.java b/pdex/experimental/src/processing/mode/experimental/LocalVariableNode.java deleted file mode 100755 index d1bdb2092..000000000 --- a/pdex/experimental/src/processing/mode/experimental/LocalVariableNode.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.LocalVariable; -import com.sun.jdi.StackFrame; -import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Specialized {@link VariableNode} for representing local variables. Overrides - * {@link #setValue} to properly change the value of the encapsulated local - * variable. - * - * @author Martin Leopold - */ -public class LocalVariableNode extends VariableNode { - - protected LocalVariable var; - protected StackFrame frame; - - /** - * Construct a {@link LocalVariableNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param var the local variable - * @param frame the stack frame containing the local variable - */ - public LocalVariableNode(String name, String type, Value value, LocalVariable var, StackFrame frame) { - super(name, type, value); - this.var = var; - this.frame = frame; - } - - @Override - public void setValue(Value value) { - try { - frame.setValue(var, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(LocalVariableNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(LocalVariableNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/Problem.java b/pdex/experimental/src/processing/mode/experimental/Problem.java deleted file mode 100644 index 56cc0e833..000000000 --- a/pdex/experimental/src/processing/mode/experimental/Problem.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package processing.mode.experimental; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.jdt.core.compiler.IProblem; - -/** - * Wrapper class for IProblem. - * - * Stores the tabIndex and line number according to its tab, including the - * original IProblem object - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class Problem { - /** - * The IProblem which is being wrapped - */ - private IProblem iProblem; - /** - * The tab number to which the error belongs to - */ - public int tabIndex; - /** - * Line number(pde code) of the error - */ - public int lineNumber; - - /** - * Error Message. Processed form of IProblem.getMessage() - */ - public String message; - - /** - * The type of error - WARNING or ERROR. - */ - public int type; - - public static final int ERROR = 1, WARNING = 2; - - /** - * - * @param iProblem - The IProblem which is being wrapped - * @param tabIndex - The tab number to which the error belongs to - * @param lineNumber - Line number(pde code) of the error - */ - public Problem(IProblem iProblem, int tabIndex, int lineNumber) { - this.iProblem = iProblem; - if(iProblem.isError()) { - type = ERROR; - } - else if(iProblem.isWarning()) { - type = WARNING; - } - this.tabIndex = tabIndex; - this.lineNumber = lineNumber; - this.message = process(iProblem); - } - - public String toString() { - return new String("TAB " + tabIndex + ",LN " + lineNumber + ",PROB: " - + message); - } - - public boolean isError(){ - return type == ERROR; - } - - public boolean isWarning(){ - return type == WARNING; - } - - public String getMessage(){ - return message; - } - - public IProblem getIProblem(){ - return iProblem; - } - - public void setType(int ProblemType){ - if(ProblemType == ERROR) - type = ERROR; - else if(ProblemType == WARNING) - type = WARNING; - else throw new IllegalArgumentException("Illegal Problem type passed to Problem.setType(int)"); - } - - private static Pattern pattern; - private static Matcher matcher; - - private static final String tokenRegExp = "\\b token\\b"; - - public static String process(IProblem problem) { - return process(problem.getMessage()); - } - - /** - * Processes error messages and attempts to make them a bit more english like. - * Currently performs: - *
  • Remove all instances of token. "Syntax error on token 'blah', delete this token" - * becomes "Syntax error on 'blah', delete this" - * @param message - The message to be processed - * @return String - The processed message - */ - public static String process(String message) { - // Remove all instances of token - // "Syntax error on token 'blah', delete this token" - if(message == null) return null; - pattern = Pattern.compile(tokenRegExp); - matcher = pattern.matcher(message); - message = matcher.replaceAll(""); - - return message; - } - - // Split camel case words into separate words. - // "VaraibleDeclaration" becomes "Variable Declaration" - // But sadly "PApplet" become "P Applet" and so on. - public static String splitCamelCaseWord(String word) { - String newWord = ""; - for (int i = 1; i < word.length(); i++) { - if (Character.isUpperCase(word.charAt(i))) { - // System.out.println(word.substring(0, i) + " " - // + word.substring(i)); - newWord += word.substring(0, i) + " "; - word = word.substring(i); - i = 1; - } - } - newWord += word; - // System.out.println(newWord); - return newWord.trim(); - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/TextArea.java b/pdex/experimental/src/processing/mode/experimental/TextArea.java deleted file mode 100644 index e07cda0b3..000000000 --- a/pdex/experimental/src/processing/mode/experimental/TextArea.java +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.awt.Color; -import java.awt.Cursor; -import java.awt.FontMetrics; -import java.awt.Point; -import java.awt.event.ComponentListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.SwingUtilities; -import javax.swing.text.BadLocationException; - -import processing.app.syntax.JEditTextArea; -import processing.app.syntax.TextAreaDefaults; - -/** - * Customized text area. Adds support for line background colors. - * - * @author Martin Leopold - */ -public class TextArea extends JEditTextArea { - - protected MouseListener[] mouseListeners; // cached mouselisteners, these are wrapped by MouseHandler - - protected DebugEditor editor; // the editor - - // line properties - protected Map lineColors = new HashMap(); // contains line background colors - - // left-hand gutter properties - protected int gutterPadding = 3; // [px] space added to the left and right of gutter chars - - protected Color gutterBgColor = new Color(252, 252, 252); // gutter background color - - protected Color gutterLineColor = new Color(233, 233, 233); // color of vertical separation line - - protected String breakpointMarker = "<>"; // the text marker for highlighting breakpoints in the gutter - - protected String currentLineMarker = "->"; // the text marker for highlighting the current line in the gutter - - protected Map gutterText = new HashMap(); // maps line index to gutter text - - protected Map gutterTextColors = new HashMap(); // maps line index to gutter text color - - protected TextAreaPainter customPainter; - - protected ErrorCheckerService errorCheckerService; - - public TextArea(TextAreaDefaults defaults, DebugEditor editor) { - super(defaults); - this.editor = editor; - - // replace the painter: - // first save listeners, these are package-private in JEditTextArea, so not accessible - ComponentListener[] componentListeners = painter.getComponentListeners(); - mouseListeners = painter.getMouseListeners(); - MouseMotionListener[] mouseMotionListeners = painter - .getMouseMotionListeners(); - - remove(painter); - - // set new painter - customPainter = new TextAreaPainter(this, defaults); - painter = customPainter; - - // set listeners - for (ComponentListener cl : componentListeners) { - painter.addComponentListener(cl); - } - - for (MouseMotionListener mml : mouseMotionListeners) { - painter.addMouseMotionListener(mml); - } - - // use a custom mouse handler instead of directly using mouseListeners - MouseHandler mouseHandler = new MouseHandler(); - painter.addMouseListener(mouseHandler); - painter.addMouseMotionListener(mouseHandler); - addCompletionPopupListner(); - add(CENTER, painter); - - // load settings from theme.txt - ExperimentalMode theme = (ExperimentalMode) editor.getMode(); - gutterBgColor = theme.getThemeColor("gutter.bgcolor", gutterBgColor); - gutterLineColor = theme.getThemeColor("gutter.linecolor", gutterLineColor); - gutterPadding = theme.getInteger("gutter.padding"); - breakpointMarker = theme.loadThemeString("breakpoint.marker", - breakpointMarker); - currentLineMarker = theme.loadThemeString("currentline.marker", - currentLineMarker); - } - - /** - * Sets ErrorCheckerService and loads theme for TextArea(XQMode) - * - * @param ecs - * @param mode - */ - public void setECSandThemeforTextArea(ErrorCheckerService ecs, - ExperimentalMode mode) { - errorCheckerService = ecs; - customPainter.setECSandTheme(ecs, mode); - } - - public void processKeyEvent(KeyEvent evt) { - if (evt.getID() == KeyEvent.KEY_PRESSED) { - if (evt.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) { - if (suggestion.isVisible()) { - //System.out.println("KeyDown"); - suggestion.moveDown(); - return; - } - } else if (evt.getKeyCode() == KeyEvent.VK_UP && suggestion != null) { - if (suggestion.isVisible()) { - //System.out.println("KeyUp"); - suggestion.moveUp(); - return; - } - } - if (evt.getKeyChar() == KeyEvent.VK_ENTER) { - if (suggestion != null) { - if (suggestion.isVisible()){ - if (suggestion.insertSelection()) { - final int position = getCaretPosition(); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - try { - //getDocument().remove(position - 1, 1); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - return; - } - } - } - } else if (evt.getKeyChar() == KeyEvent.VK_BACK_SPACE) { - System.out.println("BK Key"); - } - } - - super.processKeyEvent(evt); - if (evt.getID() == KeyEvent.KEY_TYPED) { - errorCheckerService.textModified.incrementAndGet(); - System.out.println(" Typing: " + fetchPhrase(evt) + " " - + (evt.getKeyChar() == KeyEvent.VK_BACK_SPACE)); - - } - - } - - private String fetchPhrase(KeyEvent evt) { - int off = getCaretPosition(); - System.out.print("off " + off); - if (off < 0) - return null; - int line = getCaretLine(); - if (line < 0) - return null; - String s = getLineText(line); - System.out.print("lin " + line); - /* - * if (s == null) return null; else if (s.length() == 0) return null; - */ -// else { - //System.out.print(s + " len " + s.length()); - - int x = getCaretPosition() - getLineStartOffset(line) - 1, x2 = x + 1, x1 = x - 1; - if(x >= s.length() || x < 0) - return null; //TODO: Does this check cause problems? Verify. - System.out.print(" x char: " + s.charAt(x)); - //int xLS = off - getLineStartNonWhiteSpaceOffset(line); - char keyChar = evt.getKeyChar(); - if (keyChar == KeyEvent.VK_BACK_SPACE || keyChar == KeyEvent.VK_DELETE) - ; // accepted these keys - else if (keyChar == KeyEvent.CHAR_UNDEFINED) - - return null; - - String word = (x < s.length() ? s.charAt(x) : "") + ""; - if (s.trim().length() == 1) { -// word = "" -// + (keyChar == KeyEvent.CHAR_UNDEFINED ? s.charAt(x - 1) : keyChar); - //word = (x < s.length()?s.charAt(x):"") + ""; - word = word.trim(); - if (word.endsWith(".")) - word = word.substring(0, word.length() - 1); - errorCheckerService.astGenerator.updatePredictions(word, line - + errorCheckerService.mainClassOffset); - return word; - } -// if (keyChar == KeyEvent.VK_BACK_SPACE || keyChar == KeyEvent.VK_DELETE) -// ; // accepted these keys -// else if (!(Character.isLetterOrDigit(keyChar) || keyChar == '_' || keyChar == '$')) -// return null; - int i = 0; - int closeB = 0; - - while (true) { - i++; - //TODO: currently works on single line only. "a. b()" won't be detected - if (x1 >= 0) { -// if (s.charAt(x1) != ';' && s.charAt(x1) != ',' && s.charAt(x1) != '(') - if (Character.isLetterOrDigit(s.charAt(x1)) || s.charAt(x1) == '_' - || s.charAt(x1) == '.' || s.charAt(x1) == ')') { - - if (s.charAt(x1) == ')') { - word = s.charAt(x1--) + word; - closeB++; - while (x1 >= 0 && closeB > 0) { - word = s.charAt(x1) + word; - if (s.charAt(x1) == '(') - closeB--; - if (s.charAt(x1) == ')') - closeB++; - x1--; - } - } else { - word = s.charAt(x1--) + word; - } - } else { - break; - } - } else { - break; - } - -// if (x2 >= 0 && x2 < s.length()) { -// if (Character.isLetterOrDigit(s.charAt(x2)) || s.charAt(x2) == '_' -// || s.charAt(x2) == '$') -// word = word + s.charAt(x2++); -// else -// x2 = -1; -// } else -// x2 = -1; - -// if (x1 < 0 )//&& x2 < 0 -// break; - if (i > 200) { - // time out! - System.err.println("Whoopsy! :P"); - break; - } - } -// if (keyChar != KeyEvent.CHAR_UNDEFINED) - - if (Character.isDigit(word.charAt(0))) - return null; - word = word.trim(); -// if (word.endsWith(".")) -// word = word.substring(0, word.length() - 1); - errorCheckerService.astGenerator.updatePredictions(word, line - + errorCheckerService.mainClassOffset); - //showSuggestionLater(); - return word; - - //} - } - - /** - * Retrieve the total width of the gutter area. - * - * @return gutter width in pixels - */ - protected int getGutterWidth() { - FontMetrics fm = painter.getFontMetrics(); -// System.out.println("fm: " + (fm == null)); -// System.out.println("editor: " + (editor == null)); - //System.out.println("BPBPBPBPB: " + (editor.breakpointMarker == null)); - - int textWidth = Math.max(fm.stringWidth(breakpointMarker), - fm.stringWidth(currentLineMarker)); - return textWidth + 2 * gutterPadding; - } - - /** - * Retrieve the width of margins applied to the left and right of the gutter - * text. - * - * @return margins in pixels - */ - protected int getGutterMargins() { - return gutterPadding; - } - - /** - * Set the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - * @param text - * the text - */ - public void setGutterText(int lineIdx, String text) { - gutterText.put(lineIdx, text); - painter.invalidateLine(lineIdx); - } - - /** - * Set the gutter text and color of a specific line. - * - * @param lineIdx - * the line index (0-based) - * @param text - * the text - * @param textColor - * the text color - */ - public void setGutterText(int lineIdx, String text, Color textColor) { - gutterTextColors.put(lineIdx, textColor); - setGutterText(lineIdx, text); - } - - /** - * Clear the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - */ - public void clearGutterText(int lineIdx) { - gutterText.remove(lineIdx); - painter.invalidateLine(lineIdx); - } - - /** - * Clear all gutter text. - */ - public void clearGutterText() { - for (int lineIdx : gutterText.keySet()) { - painter.invalidateLine(lineIdx); - } - gutterText.clear(); - } - - /** - * Retrieve the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - * @return the gutter text - */ - public String getGutterText(int lineIdx) { - return gutterText.get(lineIdx); - } - - /** - * Retrieve the gutter text color for a specific line. - * - * @param lineIdx - * the line index - * @return the gutter text color - */ - public Color getGutterTextColor(int lineIdx) { - return gutterTextColors.get(lineIdx); - } - - /** - * Set the background color of a line. - * - * @param lineIdx - * 0-based line number - * @param col - * the background color to set - */ - public void setLineBgColor(int lineIdx, Color col) { - lineColors.put(lineIdx, col); - painter.invalidateLine(lineIdx); - } - - /** - * Clear the background color of a line. - * - * @param lineIdx - * 0-based line number - */ - public void clearLineBgColor(int lineIdx) { - lineColors.remove(lineIdx); - painter.invalidateLine(lineIdx); - } - - /** - * Clear all line background colors. - */ - public void clearLineBgColors() { - for (int lineIdx : lineColors.keySet()) { - painter.invalidateLine(lineIdx); - } - lineColors.clear(); - } - - /** - * Get a lines background color. - * - * @param lineIdx - * 0-based line number - * @return the color or null if no color was set for the specified line - */ - public Color getLineBgColor(int lineIdx) { - return lineColors.get(lineIdx); - } - - /** - * Convert a character offset to a horizontal pixel position inside the text - * area. Overridden to take gutter width into account. - * - * @param line - * the 0-based line number - * @param offset - * the character offset (0 is the first character on a line) - * @return the horizontal position - */ - @Override - public int _offsetToX(int line, int offset) { - return super._offsetToX(line, offset) + getGutterWidth(); - } - - /** - * Convert a horizontal pixel position to a character offset. Overridden to - * take gutter width into account. - * - * @param line - * the 0-based line number - * @param x - * the horizontal pixel position - * @return he character offset (0 is the first character on a line) - */ - @Override - public int xToOffset(int line, int x) { - return super.xToOffset(line, x - getGutterWidth()); - } - - /** - * Custom mouse handler. Implements double clicking in the gutter area to - * toggle breakpoints, sets default cursor (instead of text cursor) in the - * gutter area. - */ - protected class MouseHandler implements MouseListener, MouseMotionListener { - - protected int lastX; // previous horizontal positon of the mouse cursor - - @Override - public void mouseClicked(MouseEvent me) { - // forward to standard listeners - for (MouseListener ml : mouseListeners) { - ml.mouseClicked(me); - } - } - - @Override - public void mousePressed(MouseEvent me) { - // check if this happened in the gutter area - if (me.getX() < getGutterWidth()) { - if (me.getButton() == MouseEvent.BUTTON1 && me.getClickCount() == 2) { - int line = me.getY() / painter.getFontMetrics().getHeight() - + firstLine; - if (line >= 0 && line <= getLineCount() - 1) { - editor.gutterDblClicked(line); - } - } - } else { - // forward to standard listeners - for (MouseListener ml : mouseListeners) { - ml.mousePressed(me); - } - } - } - - @Override - public void mouseReleased(MouseEvent me) { - // forward to standard listeners - for (MouseListener ml : mouseListeners) { - ml.mouseReleased(me); - } - } - - @Override - public void mouseEntered(MouseEvent me) { - // forward to standard listeners - for (MouseListener ml : mouseListeners) { - ml.mouseEntered(me); - } - } - - @Override - public void mouseExited(MouseEvent me) { - // forward to standard listeners - for (MouseListener ml : mouseListeners) { - ml.mouseExited(me); - } - } - - @Override - public void mouseDragged(MouseEvent me) { - // No need to forward since the standard MouseMotionListeners are called anyway - // nop - } - - @Override - public void mouseMoved(MouseEvent me) { - // No need to forward since the standard MouseMotionListeners are called anyway - if (me.getX() < getGutterWidth()) { - if (lastX >= getGutterWidth()) { - painter.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } - } else { - if (lastX < getGutterWidth()) { - painter.setCursor(new Cursor(Cursor.TEXT_CURSOR)); - } - } - lastX = me.getX(); - } - } - - private CompletionPanel suggestion; - - //JEditTextArea textarea; - - private void addCompletionPopupListner() { - this.addKeyListener(new KeyListener() { - - @Override - public void keyTyped(KeyEvent e) { - - } - - @Override - public void keyReleased(KeyEvent e) { - if (Character.isLetterOrDigit(e.getKeyChar()) - || e.getKeyChar() == KeyEvent.VK_BACK_SPACE - || e.getKeyChar() == KeyEvent.VK_DELETE) { -// SwingUtilities.invokeLater(new Runnable() { -// @Override -// public void run() { -// showSuggestion(); -// } -// -// }); - } else if (Character.isWhitespace(e.getKeyChar())) { - hideSuggestion(); - } - } - - @Override - public void keyPressed(KeyEvent e) { - } - }); - } - - public void showSuggestionLater(final CompletionCandidate[] items) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - showSuggestion(items); - } - - }); - } - - protected void showSuggestion(CompletionCandidate[] items) { - hideSuggestion(); - final int position = getCaretPosition(); - Point location = new Point(); - try { - location.x = offsetToX(getCaretLine(), position - - getLineStartOffset(getCaretLine())); - location.y = lineToY(getCaretLine()) - + getPainter().getFontMetrics().getHeight(); - } catch (Exception e2) { - e2.printStackTrace(); - return; - } - String text = getText(); - int start = Math.max(0, position - 1); - while (start > 0) { - if (!Character.isWhitespace(text.charAt(start))) { - start--; - } else { - start++; - break; - } - } - if (start > position) { - return; - } - final String subWord = text.substring(start, position); - if (subWord.length() < 2) { - return; - } - suggestion = new CompletionPanel(this, position, subWord, items, location); -// requestFocusInWindow(); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - requestFocusInWindow(); - } - }); - } - - private void hideSuggestion() { - if (suggestion != null) { - suggestion.hide(); - } - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/TextAreaPainter.java b/pdex/experimental/src/processing/mode/experimental/TextAreaPainter.java deleted file mode 100644 index 9ee6b9539..000000000 --- a/pdex/experimental/src/processing/mode/experimental/TextAreaPainter.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Toolkit; -import java.awt.event.InputEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -import javax.swing.text.BadLocationException; -import javax.swing.text.Segment; -import javax.swing.text.Utilities; - -import processing.app.syntax.TextAreaDefaults; -import processing.app.syntax.TokenMarker; - -/** - * Customized line painter. Adds support for background colors, left hand gutter - * area with background color and text. - * - * @author Martin Leopold - */ -public class TextAreaPainter extends processing.app.syntax.TextAreaPainter { - - protected TextArea ta; // we need the subclassed textarea - - protected ErrorCheckerService errorCheckerService; - - /** - * Error line underline color - */ - public Color errorColor = new Color(0xED2630); - - /** - * Warning line underline color - */ - - public Color warningColor = new Color(0xFFC30E); - - /** - * Color of Error Marker - */ - public Color errorMarkerColor = new Color(0xED2630); - - /** - * Color of Warning Marker - */ - public Color warningMarkerColor = new Color(0xFFC30E); - - static int ctrlMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - - public TextAreaPainter(TextArea textArea, TextAreaDefaults defaults) { - super(textArea, defaults); - ta = textArea; - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent evt) { -// System.out.println( " Meta,Ctrl "+ (evt.getModifiers() & ctrlMask)); - if (evt.isControlDown()) - handleCtrlClick(evt); - } - }); - - } - -// public void processKeyEvent(KeyEvent evt) { -// System.out.println(evt); -// } - - void handleCtrlClick(MouseEvent evt) { - System.out.println("--handleCtrlClick--"); - int off = ta.xyToOffset(evt.getX(), evt.getY()); - if (off < 0) - return; - int line = ta.getLineOfOffset(off); - if (line < 0) - return; - String s = ta.getLineText(line); - if (s == null) - return; - else if (s.length() == 0) - return; - else { - int x = ta.xToOffset(line, evt.getX()), x2 = x + 1, x1 = x - 1; - int xLS = off - ta.getLineStartNonWhiteSpaceOffset(line); - if (x < 0 || x >= s.length()) - return; - String word = s.charAt(x) + ""; - if (s.charAt(x) == ' ') - return; - if (!(Character.isLetterOrDigit(s.charAt(x)) || s.charAt(x) == '_' || s - .charAt(x) == '$')) - return; - int i = 0; - while (true) { - i++; - if (x1 >= 0 && x1 < s.length()) { - if (Character.isLetter(s.charAt(x1)) || s.charAt(x1) == '_') { - word = s.charAt(x1--) + word; - } else - x1 = -1; - } else - x1 = -1; - - if (x2 >= 0 && x2 < s.length()) { - if (Character.isLetterOrDigit(s.charAt(x2)) || s.charAt(x2) == '_' - || s.charAt(x2) == '$') - word = word + s.charAt(x2++); - else - x2 = -1; - } else - x2 = -1; - - if (x1 < 0 && x2 < 0) - break; - if (i > 200) { - // time out! - System.err.println("Whoopsy! :P"); - break; - } - } - if (Character.isDigit(word.charAt(0))) - return; - - System.out.print(errorCheckerService.mainClassOffset + line); - System.out.print("|" + line + "| offset " + xLS + word + " <= \n"); - errorCheckerService.astGenerator.scrollToDeclaration(line - + errorCheckerService.mainClassOffset, word, xLS); - } - } - - private void loadTheme(ExperimentalMode mode) { - errorColor = mode.getThemeColor("editor.errorcolor", errorColor); - warningColor = mode.getThemeColor("editor.warningcolor", warningColor); - errorMarkerColor = mode.getThemeColor("editor.errormarkercolor", - errorMarkerColor); - warningMarkerColor = mode.getThemeColor("editor.warningmarkercolor", - warningMarkerColor); - } - - /** - * Paint a line. Paints the gutter (with background color and text) then the - * line (background color and text). - * - * @param gfx - * the graphics context - * @param tokenMarker - * @param line - * 0-based line number - * @param x - * horizontal position - */ - @Override - protected void paintLine(Graphics gfx, TokenMarker tokenMarker, int line, - int x) { - - // paint gutter - paintGutterBg(gfx, line, x); - - paintLineBgColor(gfx, line, x + ta.getGutterWidth()); - - paintGutterLine(gfx, line, x); - - // paint gutter symbol - paintGutterText(gfx, line, x); - - paintErrorLine(gfx, line, x); - - super.paintLine(gfx, tokenMarker, line, x + ta.getGutterWidth()); - } - - /** - * Paint the gutter background (solid color). - * - * @param gfx - * the graphics context - * @param line - * 0-based line number - * @param x - * horizontal position - */ - protected void paintGutterBg(Graphics gfx, int line, int x) { - gfx.setColor(ta.gutterBgColor); - int y = ta.lineToY(line) + fm.getLeading() + fm.getMaxDescent(); - gfx.fillRect(0, y, ta.getGutterWidth(), fm.getHeight()); - } - - /** - * Paint the vertical gutter separator line. - * - * @param gfx - * the graphics context - * @param line - * 0-based line number - * @param x - * horizontal position - */ - protected void paintGutterLine(Graphics gfx, int line, int x) { - int y = ta.lineToY(line) + fm.getLeading() + fm.getMaxDescent(); - gfx.setColor(ta.gutterLineColor); - gfx.drawLine(ta.getGutterWidth(), y, ta.getGutterWidth(), - y + fm.getHeight()); - } - - /** - * Paint the gutter text. - * - * @param gfx - * the graphics context - * @param line - * 0-based line number - * @param x - * horizontal position - */ - protected void paintGutterText(Graphics gfx, int line, int x) { - String text = ta.getGutterText(line); - if (text == null) { - return; - } - - gfx.setFont(getFont()); - Color textColor = ta.getGutterTextColor(line); - if (textColor == null) { - gfx.setColor(getForeground()); - } else { - gfx.setColor(textColor); - } - int y = ta.lineToY(line) + fm.getHeight(); - - // draw 4 times to make it appear bold, displaced 1px to the right, to the bottom and bottom right. - //int len = text.length() > ta.gutterChars ? ta.gutterChars : text.length(); - Utilities.drawTabbedText(new Segment(text.toCharArray(), 0, text.length()), - ta.getGutterMargins(), y, gfx, this, 0); - Utilities.drawTabbedText(new Segment(text.toCharArray(), 0, text.length()), - ta.getGutterMargins() + 1, y, gfx, this, 0); - Utilities.drawTabbedText(new Segment(text.toCharArray(), 0, text.length()), - ta.getGutterMargins(), y + 1, gfx, this, 0); - Utilities.drawTabbedText(new Segment(text.toCharArray(), 0, text.length()), - ta.getGutterMargins() + 1, y + 1, gfx, this, 0); - } - - /** - * Paint the background color of a line. - * - * @param gfx - * the graphics context - * @param line - * 0-based line number - * @param x - */ - protected void paintLineBgColor(Graphics gfx, int line, int x) { - int y = ta.lineToY(line); - y += fm.getLeading() + fm.getMaxDescent(); - int height = fm.getHeight(); - - // get the color - Color col = ta.getLineBgColor(line); - //System.out.print("bg line " + line + ": "); - // no need to paint anything - if (col == null) { - //System.out.println("none"); - return; - } - // paint line background - gfx.setColor(col); - gfx.fillRect(0, y, getWidth(), height); - } - - /** - * Paints the underline for an error/warning line - * - * @param gfx - * the graphics context - * @param tokenMarker - * @param line - * 0-based line number: NOTE - * @param x - */ - protected void paintErrorLine(Graphics gfx, int line, int x) { - - if (errorCheckerService == null) { - return; - } - - if (errorCheckerService.problemsList == null) { - return; - } - - boolean notFound = true; - boolean isWarning = false; - - // Check if current line contains an error. If it does, find if it's an - // error or warning - for (ErrorMarker emarker : errorCheckerService.getEditor().errorBar.errorPoints) { - if (emarker.problem.lineNumber == line + 1) { - notFound = false; - if (emarker.type == ErrorMarker.Warning) { - isWarning = true; - } - break; - } - } - - if (notFound) { - return; - } - - // Determine co-ordinates - // System.out.println("Hoff " + ta.getHorizontalOffset() + ", " + - // horizontalAdjustment); - int y = ta.lineToY(line); - y += fm.getLeading() + fm.getMaxDescent(); - int height = fm.getHeight(); - int start = ta.getLineStartOffset(line); - - try { - String linetext = null; - - try { - linetext = ta.getDocument().getText(start, - ta.getLineStopOffset(line) - start - - 1); - } catch (BadLocationException bl) { - // Error in the import statements or end of code. - // System.out.print("BL caught. " + ta.getLineCount() + " ," - // + line + " ,"); - // System.out.println((ta.getLineStopOffset(line) - start - 1)); - return; - } - - // Take care of offsets - int aw = fm.stringWidth(trimRight(linetext)) + ta.getHorizontalOffset(); // apparent width. Whitespaces - // to the left of line + text - // width - int rw = fm.stringWidth(linetext.trim()); // real width - int x1 = 0 + (aw - rw), y1 = y + fm.getHeight() - 2, x2 = x1 + rw; - // Adding offsets for the gutter - x1 += 20; - x2 += 20; - - // gfx.fillRect(x1, y, rw, height); - - // Let the painting begin! - gfx.setColor(errorMarkerColor); - if (isWarning) { - gfx.setColor(warningMarkerColor); - } - gfx.fillRect(1, y + 2, 3, height - 2); - - gfx.setColor(errorColor); - if (isWarning) { - gfx.setColor(warningColor); - } - int xx = x1; - - // Draw the jagged lines - while (xx < x2) { - gfx.drawLine(xx, y1, xx + 2, y1 + 1); - xx += 2; - gfx.drawLine(xx, y1 + 1, xx + 2, y1); - xx += 2; - } - } catch (Exception e) { - System.out - .println("Looks like I messed up! XQTextAreaPainter.paintLine() : " - + e); - //e.printStackTrace(); - } - - // Won't highlight the line. Select the text instead. - // gfx.setColor(Color.RED); - // gfx.fillRect(2, y, 3, height); - } - - /** - * Trims out trailing whitespaces (to the right) - * - * @param string - * @return - String - */ - private String trimRight(String string) { - String newString = ""; - for (int i = 0; i < string.length(); i++) { - if (string.charAt(i) != ' ') { - newString = string.substring(0, i) + string.trim(); - break; - } - } - return newString; - } - - /** - * Sets ErrorCheckerService and loads theme for TextAreaPainter(XQMode) - * - * @param ecs - * @param mode - */ - public void setECSandTheme(ErrorCheckerService ecs, ExperimentalMode mode) { - this.errorCheckerService = ecs; - loadTheme(mode); - } - - public String getToolTipText(java.awt.event.MouseEvent evt) { - int off = ta.xyToOffset(evt.getX(), evt.getY()); - if (off < 0) - return null; - int line = ta.getLineOfOffset(off); - if (line < 0) - return null; - String s = ta.getLineText(line); - if (s == null) - return evt.toString(); - else if (s.length() == 0) - return null; - else { - int x = ta.xToOffset(line, evt.getX()), x2 = x + 1, x1 = x - 1; - int xLS = off - ta.getLineStartNonWhiteSpaceOffset(line); - if (x < 0 || x >= s.length()) - return null; - String word = s.charAt(x) + ""; - if (s.charAt(x) == ' ') - return null; - if (!(Character.isLetterOrDigit(s.charAt(x)) || s.charAt(x) == '_' || s - .charAt(x) == '$')) - return null; - int i = 0; - while (true) { - i++; - if (x1 >= 0 && x1 < s.length()) { - if (Character.isLetter(s.charAt(x1)) || s.charAt(x1) == '_') { - word = s.charAt(x1--) + word; - } else - x1 = -1; - } else - x1 = -1; - - if (x2 >= 0 && x2 < s.length()) { - if (Character.isLetterOrDigit(s.charAt(x2)) || s.charAt(x2) == '_' - || s.charAt(x2) == '$') - word = word + s.charAt(x2++); - else - x2 = -1; - } else - x2 = -1; - - if (x1 < 0 && x2 < 0) - break; - if (i > 200) { - // time out! - System.err.println("Whoopsy! :P"); - break; - } - } - if (Character.isDigit(word.charAt(0))) - return null; - String tooltipText = errorCheckerService.astGenerator - .getLabelForASTNode(line + errorCheckerService.mainClassOffset, word, - xLS); - - System.out.print(errorCheckerService.mainClassOffset + " MCO "); - System.out.print("|" + line + "| offset " + xLS + word + " <= offf: "+off+ "\n"); - if (tooltipText != null) - return tooltipText; - return word; - } - - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/VMEventListener.java b/pdex/experimental/src/processing/mode/experimental/VMEventListener.java deleted file mode 100755 index 4cc648802..000000000 --- a/pdex/experimental/src/processing/mode/experimental/VMEventListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.event.EventSet; - -/** - * Interface for VM callbacks. - * - * @author Martin Leopold - */ -public interface VMEventListener { - - /** - * Receive an event from the VM. Events are sent in batches. See - * documentation of EventSet for more information. - * - * @param es Set of events - */ - void vmEvent(EventSet es); -} diff --git a/pdex/experimental/src/processing/mode/experimental/VMEventReader.java b/pdex/experimental/src/processing/mode/experimental/VMEventReader.java deleted file mode 100755 index c4d05ddf9..000000000 --- a/pdex/experimental/src/processing/mode/experimental/VMEventReader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.VMDisconnectedException; -import com.sun.jdi.event.EventQueue; -import com.sun.jdi.event.EventSet; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Reader Thread for VM Events. Constantly monitors a VMs EventQueue for new - * events and forwards them to an VMEventListener. - * - * @author Martin Leopold - */ -public class VMEventReader extends Thread { - - EventQueue eventQueue; - VMEventListener listener; - - /** - * Construct a VMEventReader. Needs to be kicked off with start() once - * constructed. - * - * @param eventQueue The queue to read events from. Can be obtained from a - * VirtualMachine via eventQueue(). - * @param listener the listener to forward events to. - */ - public VMEventReader(EventQueue eventQueue, VMEventListener listener) { - super("VM Event Thread"); - this.eventQueue = eventQueue; - this.listener = listener; - } - - @Override - public void run() { - try { - while (true) { - EventSet eventSet = eventQueue.remove(); - listener.vmEvent(eventSet); - /* - * for (Event e : eventSet) { System.out.println("VM Event: " + - * e.toString()); } - */ - } - } catch (VMDisconnectedException e) { - Logger.getLogger(VMEventReader.class.getName()).log(Level.INFO, "VMEventReader quit on VM disconnect"); - } catch (Exception e) { - Logger.getLogger(VMEventReader.class.getName()).log(Level.SEVERE, "VMEventReader quit", e); - } - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/VariableInspector.form b/pdex/experimental/src/processing/mode/experimental/VariableInspector.form deleted file mode 100755 index a5f40f1d3..000000000 --- a/pdex/experimental/src/processing/mode/experimental/VariableInspector.form +++ /dev/null @@ -1,53 +0,0 @@ - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    diff --git a/pdex/experimental/src/processing/mode/experimental/VariableInspector.java b/pdex/experimental/src/processing/mode/experimental/VariableInspector.java deleted file mode 100755 index a38c19a8f..000000000 --- a/pdex/experimental/src/processing/mode/experimental/VariableInspector.java +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.Value; -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.DefaultCellEditor; -import javax.swing.GrayFilter; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.UIDefaults; -import javax.swing.UIManager; -import javax.swing.event.TreeExpansionEvent; -import javax.swing.event.TreeExpansionListener; -import javax.swing.table.TableColumn; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.ExpandVetoException; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; -import org.netbeans.swing.outline.DefaultOutlineCellRenderer; -import org.netbeans.swing.outline.DefaultOutlineModel; -import org.netbeans.swing.outline.ExtTreeWillExpandListener; -import org.netbeans.swing.outline.OutlineModel; -import org.netbeans.swing.outline.RenderDataProvider; -import org.netbeans.swing.outline.RowModel; - -/** - * Variable Inspector window. - * - * @author Martin Leopold - */ -public class VariableInspector extends javax.swing.JFrame { - - protected DefaultMutableTreeNode rootNode; // the root node (invisible) - protected DefaultMutableTreeNode builtins; // node for Processing built-in variables - protected DefaultTreeModel treeModel; // data model for the tree column - protected OutlineModel model; // data model for the whole Outline (tree and other columns) - protected List callStack; // the call stack - protected List locals; // current local variables - protected List thisFields; // all fields of the current this-object - protected List declaredThisFields; // declared i.e. non-inherited fields of this - protected DebugEditor editor; // the editor - protected Debugger dbg; // the debugger - protected List expandedNodes = new ArrayList(); // list of expanded tree paths. (using list to maintain the order of expansion) - protected boolean p5mode = true; // processing / "advanced" mode flag (currently not used - - /** - * Creates new form VariableInspector - */ - public VariableInspector(DebugEditor editor) { - this.editor = editor; - this.dbg = editor.dbg(); - - initComponents(); - - // setup Outline - rootNode = new DefaultMutableTreeNode("root"); - builtins = new DefaultMutableTreeNode("Processing"); - treeModel = new DefaultTreeModel(rootNode); // model for the tree column - model = DefaultOutlineModel.createOutlineModel(treeModel, new VariableRowModel(), true, "Name"); // model for all columns - - ExpansionHandler expansionHandler = new ExpansionHandler(); - model.getTreePathSupport().addTreeWillExpandListener(expansionHandler); - model.getTreePathSupport().addTreeExpansionListener(expansionHandler); - tree.setModel(model); - tree.setRootVisible(false); - tree.setRenderDataProvider(new OutlineRenderer()); - tree.setColumnHidingAllowed(false); // disable visible columns button (shows by default when right scroll bar is visible) - tree.setAutoscrolls(false); - - // set custom renderer and editor for value column, since we are using a custom class for values (VariableNode) - TableColumn valueColumn = tree.getColumnModel().getColumn(1); - valueColumn.setCellRenderer(new ValueCellRenderer()); - valueColumn.setCellEditor(new ValueCellEditor()); - - //System.out.println("renderer: " + tree.getDefaultRenderer(String.class).getClass()); - //System.out.println("editor: " + tree.getDefaultEditor(String.class).getClass()); - - callStack = new ArrayList(); - locals = new ArrayList(); - thisFields = new ArrayList(); - declaredThisFields = new ArrayList(); - - this.setTitle(editor.getSketch().getName()); - -// for (Entry entry : UIManager.getDefaults().entrySet()) { -// System.out.println(entry.getKey()); -// } - } - - @Override - public void setTitle(String title) { - super.setTitle(title + " | Variable Inspector"); - } - - /** - * Model for a Outline Row (excluding the tree column). Column 0 is "Value". - * Column 1 is "Type". Handles setting and getting values. TODO: Maybe use a - * TableCellRenderer instead of this to also have a different icon based on - * expanded state. See: - * http://kickjava.com/src/org/netbeans/swing/outline/DefaultOutlineCellRenderer.java.htm - */ - protected class VariableRowModel implements RowModel { - - protected String[] columnNames = {"Value", "Type"}; - protected int[] editableTypes = {VariableNode.TYPE_BOOLEAN, VariableNode.TYPE_FLOAT, VariableNode.TYPE_INTEGER, VariableNode.TYPE_STRING, VariableNode.TYPE_FLOAT, VariableNode.TYPE_DOUBLE, VariableNode.TYPE_LONG, VariableNode.TYPE_SHORT, VariableNode.TYPE_CHAR}; - - @Override - public int getColumnCount() { - if (p5mode) { - return 1; // only show value in p5 mode - } else { - return 2; - } - } - - @Override - public Object getValueFor(Object o, int i) { - if (o instanceof VariableNode) { - VariableNode var = (VariableNode) o; - switch (i) { - case 0: - return var; // will be converted to an appropriate String by ValueCellRenderer - case 1: - return var.getTypeName(); - default: - return ""; - } - } else { - return ""; - } - } - - @Override - public Class getColumnClass(int i) { - if (i == 0) { - return VariableNode.class; - } - return String.class; - } - - @Override - public boolean isCellEditable(Object o, int i) { - if (i == 0 && o instanceof VariableNode) { - VariableNode var = (VariableNode) o; - //System.out.println("type: " + var.getTypeName()); - for (int type : editableTypes) { - if (var.getType() == type) { - return true; - } - } - } - return false; - } - - @Override - public void setValueFor(Object o, int i, Object o1) { - VariableNode var = (VariableNode) o; - String stringValue = (String) o1; - - Value value = null; - try { - switch (var.getType()) { - case VariableNode.TYPE_INTEGER: - value = dbg.vm().mirrorOf(Integer.parseInt(stringValue)); - break; - case VariableNode.TYPE_BOOLEAN: - value = dbg.vm().mirrorOf(Boolean.parseBoolean(stringValue)); - break; - case VariableNode.TYPE_FLOAT: - value = dbg.vm().mirrorOf(Float.parseFloat(stringValue)); - break; - case VariableNode.TYPE_STRING: - value = dbg.vm().mirrorOf(stringValue); - break; - case VariableNode.TYPE_LONG: - value = dbg.vm().mirrorOf(Long.parseLong(stringValue)); - break; - case VariableNode.TYPE_BYTE: - value = dbg.vm().mirrorOf(Byte.parseByte(stringValue)); - break; - case VariableNode.TYPE_DOUBLE: - value = dbg.vm().mirrorOf(Double.parseDouble(stringValue)); - break; - case VariableNode.TYPE_SHORT: - value = dbg.vm().mirrorOf(Short.parseShort(stringValue)); - break; - case VariableNode.TYPE_CHAR: - // TODO: better char support - if (stringValue.length() > 0) { - value = dbg.vm().mirrorOf(stringValue.charAt(0)); - } - break; - } - } catch (NumberFormatException ex) { - Logger.getLogger(VariableRowModel.class.getName()).log(Level.INFO, "invalid value entered for {0}: {1}", new Object[]{var.getName(), stringValue}); - } - if (value != null) { - var.setValue(value); - Logger.getLogger(VariableRowModel.class.getName()).log(Level.INFO, "new value set: {0}", var.getStringValue()); - } - } - - @Override - public String getColumnName(int i) { - return columnNames[i]; - } - } - - /** - * Renderer for the tree portion of the outline component. Handles icons, - * text color and tool tips. - */ - protected class OutlineRenderer implements RenderDataProvider { - - protected Icon[][] icons; - protected static final int ICON_SIZE = 16; // icon size (square, size=width=height) - - public OutlineRenderer() { - // load icons - icons = loadIcons("theme/var-icons.gif"); - } - - /** - * Load multiple icons (horizotal) with multiple states (vertical) from - * a single file. - * - * @param fileName file path in the mode folder. - * @return a nested array (first index: icon, second index: state) or - * null if the file wasn't found. - */ - protected ImageIcon[][] loadIcons(String fileName) { - ExperimentalMode mode = editor.mode(); - File file = mode.getContentFile(fileName); - if (!file.exists()) { - Logger.getLogger(OutlineRenderer.class.getName()).log(Level.SEVERE, "icon file not found: {0}", file.getAbsolutePath()); - return null; - } - Image allIcons = mode.loadImage(fileName); - int cols = allIcons.getWidth(null) / ICON_SIZE; - int rows = allIcons.getHeight(null) / ICON_SIZE; - ImageIcon[][] iconImages = new ImageIcon[cols][rows]; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - //Image image = createImage(ICON_SIZE, ICON_SIZE); - Image image = new BufferedImage(ICON_SIZE, ICON_SIZE, BufferedImage.TYPE_INT_ARGB); - Graphics g = image.getGraphics(); - g.drawImage(allIcons, -i * ICON_SIZE, -j * ICON_SIZE, null); - iconImages[i][j] = new ImageIcon(image); - } - } - return iconImages; - } - - protected Icon getIcon(int type, int state) { - if (type < 0 || type > icons.length - 1) { - return null; - } - return icons[type][state]; - } - - protected VariableNode toVariableNode(Object o) { - if (o instanceof VariableNode) { - return (VariableNode) o; - } else { - return null; - } - } - - protected Icon toGray(Icon icon) { - if (icon instanceof ImageIcon) { - Image grayImage = GrayFilter.createDisabledImage(((ImageIcon) icon).getImage()); - return new ImageIcon(grayImage); - } - // Cannot convert - return icon; - } - - @Override - public String getDisplayName(Object o) { - return o.toString(); // VariableNode.toString() returns name; (for sorting) -// VariableNode var = toVariableNode(o); -// if (var != null) { -// return var.getName(); -// } else { -// return o.toString(); -// } - } - - @Override - public boolean isHtmlDisplayName(Object o) { - return false; - } - - @Override - public Color getBackground(Object o) { - return null; - } - - @Override - public Color getForeground(Object o) { - if (tree.isEnabled()) { - return null; // default - } else { - return Color.GRAY; - } - } - - @Override - public String getTooltipText(Object o) { - VariableNode var = toVariableNode(o); - if (var != null) { - return var.getDescription(); - } else { - return ""; - } - } - - @Override - public Icon getIcon(Object o) { - VariableNode var = toVariableNode(o); - if (var != null) { - if (tree.isEnabled()) { - return getIcon(var.getType(), 0); - } else { - return getIcon(var.getType(), 1); - } - } else { - if (o instanceof TreeNode) { -// TreeNode node = (TreeNode) o; -// AbstractLayoutCache layout = tree.getLayoutCache(); - UIDefaults defaults = UIManager.getDefaults(); - - boolean isLeaf = model.isLeaf(o); - Icon icon; - if (isLeaf) { - icon = defaults.getIcon("Tree.leafIcon"); - } else { - icon = defaults.getIcon("Tree.closedIcon"); - } - - if (!tree.isEnabled()) { - return toGray(icon); - } - return icon; - } - } - return null; // use standard icon - //UIManager.getIcon(o); - } - } - - // TODO: could probably extend the simpler javax.swing.table.DefaultTableCellRenderer here - /** - * Renderer for the value column. Uses an italic font for null values and - * Object values ("instance of ..."). Uses a gray color when tree is not - * enabled. - */ - protected class ValueCellRenderer extends DefaultOutlineCellRenderer { - - public ValueCellRenderer() { - super(); - } - - protected void setItalic(boolean on) { - if (on) { - setFont(new Font(getFont().getName(), Font.ITALIC, getFont().getSize())); - } else { - setFont(new Font(getFont().getName(), Font.PLAIN, getFont().getSize())); - } - } - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - - if (!tree.isEnabled()) { - setForeground(Color.GRAY); - } else { - setForeground(Color.BLACK); - } - - if (value instanceof VariableNode) { - VariableNode var = (VariableNode) value; - - if (var.getValue() == null || var.getType() == VariableNode.TYPE_OBJECT) { - setItalic(true); - } else { - setItalic(false); - } - value = var.getStringValue(); - } - - setValue(value); - return c; - } - } - - /** - * Editor for the value column. Will show an empty string when editing - * String values that are null. - */ - protected class ValueCellEditor extends DefaultCellEditor { - - public ValueCellEditor() { - super(new JTextField()); - } - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { - if (!(value instanceof VariableNode)) { - return super.getTableCellEditorComponent(table, value, isSelected, row, column); - } - VariableNode var = (VariableNode) value; - if (var.getType() == VariableNode.TYPE_STRING && var.getValue() == null) { - return super.getTableCellEditorComponent(table, "", isSelected, row, column); - } else { - return super.getTableCellEditorComponent(table, var.getStringValue(), isSelected, row, column); - } - } - } - - /** - * Handler for expanding and collapsing tree nodes. Implements lazy loading - * of tree data (on expand). - */ - protected class ExpansionHandler implements ExtTreeWillExpandListener, TreeExpansionListener { - - @Override - public void treeWillExpand(TreeExpansionEvent tee) throws ExpandVetoException { - //System.out.println("will expand"); - Object last = tee.getPath().getLastPathComponent(); - if (!(last instanceof VariableNode)) { - return; - } - VariableNode var = (VariableNode) last; - // load children -// if (!dbg.isPaused()) { -// System.out.println("throwing veto"); -// //throw new ExpandVetoException(tee, "Debugger busy"); -// } else { - var.removeAllChildren(); // TODO: should we only load it once? - // TODO: don't filter in advanced mode - //System.out.println("loading children for: " + var); - // true means include inherited - var.addChildren(filterNodes(dbg.getFields(var.getValue(), 0, true), new ThisFilter())); -// } - } - - @Override - public void treeWillCollapse(TreeExpansionEvent tee) throws ExpandVetoException { - //throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void treeExpanded(TreeExpansionEvent tee) { - //System.out.println("expanded: " + tee.getPath()); - if (!expandedNodes.contains(tee.getPath())) { - expandedNodes.add(tee.getPath()); - } - -// TreePath newPath = tee.getPath(); -// if (expandedLast != null) { -// // test each node of the path for equality -// for (int i = 0; i < expandedLast.getPathCount(); i++) { -// if (i < newPath.getPathCount()) { -// Object last = expandedLast.getPathComponent(i); -// Object cur = newPath.getPathComponent(i); -// System.out.println(last + " =? " + cur + ": " + last.equals(cur) + "/" + (last.hashCode() == cur.hashCode())); -// } -// } -// } -// System.out.println("path equality: " + newPath.equals(expandedLast)); -// expandedLast = newPath; - } - - @Override - public void treeCollapsed(TreeExpansionEvent tee) { - //System.out.println("collapsed: " + tee.getPath()); - - // first remove all children of collapsed path - // this makes sure children do not appear before parents in the list. - // (children can't be expanded before their parents) - List removalList = new ArrayList(); - for (TreePath path : expandedNodes) { - if (path.getParentPath().equals(tee.getPath())) { - removalList.add(path); - } - } - for (TreePath path : removalList) { - expandedNodes.remove(path); - } - // remove collapsed path - expandedNodes.remove(tee.getPath()); - } - - @Override - public void treeExpansionVetoed(TreeExpansionEvent tee, ExpandVetoException eve) { - //System.out.println("expansion vetoed"); - // nop - } - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - scrollPane = new javax.swing.JScrollPane(); - tree = new org.netbeans.swing.outline.Outline(); - - scrollPane.setViewportView(tree); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)) - ); - - pack(); - }// //GEN-END:initComponents - -// /** -// * @param args the command line arguments -// */ -// public static void main(String args[]) { -// /* -// * Set the Nimbus look and feel -// */ -// // -// /* -// * If Nimbus (introduced in Java SE 6) is not available, stay with the -// * default look and feel. For details see -// * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html -// */ -// try { -// javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName()); -// } catch (ClassNotFoundException ex) { -// java.util.logging.Logger.getLogger(VariableInspector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); -// } catch (InstantiationException ex) { -// java.util.logging.Logger.getLogger(VariableInspector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); -// } catch (IllegalAccessException ex) { -// java.util.logging.Logger.getLogger(VariableInspector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); -// } catch (javax.swing.UnsupportedLookAndFeelException ex) { -// java.util.logging.Logger.getLogger(VariableInspector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); -// } -// // -// -// /* -// * Create and display the form -// */ -// run(new VariableInspector()); -// } - protected static void run(final VariableInspector vi) { - /* - * Create and display the form - */ - java.awt.EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - vi.setVisible(true); - } - }); - } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JScrollPane scrollPane; - protected org.netbeans.swing.outline.Outline tree; - // End of variables declaration//GEN-END:variables - - /** - * Access the root node of the tree. - * - * @return the root node - */ - public DefaultMutableTreeNode getRootNode() { - return rootNode; - } - - /** - * Unlock the inspector window. Rebuild after this to avoid ... dots in the - * trees labels - */ - public void unlock() { - tree.setEnabled(true); - } - - /** - * Lock the inspector window. Cancels open edits. - */ - public void lock() { - if (tree.getCellEditor() != null) { - //tree.getCellEditor().stopCellEditing(); // force quit open edit - tree.getCellEditor().cancelCellEditing(); // cancel an open edit - } - tree.setEnabled(false); - } - - /** - * Reset the inspector windows data. Rebuild after this to make changes - * visible. - */ - public void reset() { - rootNode.removeAllChildren(); - // clear local data for good measure (in case someone rebuilds) - callStack.clear(); - locals.clear(); - thisFields.clear(); - declaredThisFields.clear(); - expandedNodes.clear(); - // update - treeModel.nodeStructureChanged(rootNode); - } - -// public void setAdvancedMode() { -// p5mode = false; -// } -// -// public void setP5Mode() { -// p5mode = true; -// } -// -// public void toggleMode() { -// if (p5mode) { -// setAdvancedMode(); -// } else { -// setP5Mode(); -// } -// } - /** - * Update call stack data. - * - * @param nodes a list of nodes that represent the call stack. - * @param title the title to be used when labeling or otherwise grouping - * call stack data. - */ - public void updateCallStack(List nodes, String title) { - callStack = nodes; - } - - /** - * Update locals data. - * - * @param nodes a list of {@link VariableNode} to be shown as local - * variables in the inspector. - * @param title the title to be used when labeling or otherwise grouping - * locals data. - */ - public void updateLocals(List nodes, String title) { - locals = nodes; - } - - /** - * Update this-fields data. - * - * @param nodes a list of {@link VariableNode}s to be shown as this-fields - * in the inspector. - * @param title the title to be used when labeling or otherwise grouping - * this-fields data. - */ - public void updateThisFields(List nodes, String title) { - thisFields = nodes; - } - - /** - * Update declared (non-inherited) this-fields data. - * - * @param nodes a list of {@link VariableNode}s to be shown as declared - * this-fields in the inspector. - * @param title the title to be used when labeling or otherwise grouping - * declared this-fields data. - */ - public void updateDeclaredThisFields(List nodes, String title) { - declaredThisFields = nodes; - } - - /** - * Rebuild the outline tree from current data. Uses the data provided by - * {@link #updateCallStack}, {@link #updateLocals}, {@link #updateThisFields} - * and {@link #updateDeclaredThisFields} - */ - public void rebuild() { - rootNode.removeAllChildren(); - if (p5mode) { - // add all locals to root - addAllNodes(rootNode, locals); - - // add non-inherited this fields - addAllNodes(rootNode, filterNodes(declaredThisFields, new LocalHidesThisFilter(locals, LocalHidesThisFilter.MODE_PREFIX))); - - // add p5 builtins in a new folder - builtins.removeAllChildren(); - addAllNodes(builtins, filterNodes(thisFields, new P5BuiltinsFilter())); - if (builtins.getChildCount() > 0) { // skip builtins in certain situations e.g. in pure java tabs. - rootNode.add(builtins); - } - - // notify tree (using model) changed a node and its children - // http://stackoverflow.com/questions/2730851/how-to-update-jtree-elements - // needs to be done before expanding paths! - treeModel.nodeStructureChanged(rootNode); - - // handle node expansions - for (TreePath path : expandedNodes) { - //System.out.println("re-expanding: " + path); - path = synthesizePath(path); - if (path != null) { - tree.expandPath(path); - } else { - //System.out.println("couldn't synthesize path"); - } - } - - // this expansion causes problems when sorted and stepping - //tree.expandPath(new TreePath(new Object[]{rootNode, builtins})); - - } else { - // TODO: implement advanced mode here - } - } - - /** - * Re-build a {@link TreePath} from a previous path using equals-checks - * starting at the root node. This is used to use paths from previous trees - * for use on the current tree. - * - * @param path the path to synthesize. - * @return the rebuilt path, usable on the current tree. - */ - protected TreePath synthesizePath(TreePath path) { - //System.out.println("synthesizing: " + path); - if (path.getPathCount() == 0 || !rootNode.equals(path.getPathComponent(0))) { - return null; - } - Object[] newPath = new Object[path.getPathCount()]; - newPath[0] = rootNode; - TreeNode currentNode = rootNode; - for (int i = 0; i < path.getPathCount() - 1; i++) { - // get next node - for (int j = 0; j < currentNode.getChildCount(); j++) { - TreeNode nextNode = currentNode.getChildAt(j); - if (nextNode.equals(path.getPathComponent(i + 1))) { - currentNode = nextNode; - newPath[i + 1] = nextNode; - //System.out.println("found node " + (i+1) + ": " + nextNode); - break; - } - } - if (newPath[i + 1] == null) { - //System.out.println("didn't find node"); - return null; - } - } - return new TreePath(newPath); - } - - /** - * Filter a list of nodes using a {@link VariableNodeFilter}. - * - * @param nodes the list of nodes to filter. - * @param filter the filter to be used. - * @return the filtered list. - */ - protected List filterNodes(List nodes, VariableNodeFilter filter) { - List filtered = new ArrayList(); - for (VariableNode node : nodes) { - if (filter.accept(node)) { - filtered.add(node); - } - } - return filtered; - } - - /** - * Add all nodes in a list to a root node. - * - * @param root the root node to add to. - * @param nodes the list of nodes to add. - */ - protected void addAllNodes(DefaultMutableTreeNode root, List nodes) { - for (MutableTreeNode node : nodes) { - root.add(node); - } - } - - /** - * A filter for {@link VariableNode}s. - */ - public interface VariableNodeFilter { - - /** - * Check whether the filter accepts a {@link VariableNode}. - * - * @param var the input node - * @return true when the filter accepts the input node otherwise false. - */ - public boolean accept(VariableNode var); - } - - /** - * A {@link VariableNodeFilter} that accepts Processing built-in variable - * names. - */ - public class P5BuiltinsFilter implements VariableNodeFilter { - - protected String[] p5Builtins = { - "focused", - "frameCount", - "frameRate", - "height", - "online", - "screen", - "width", - "mouseX", - "mouseY", - "pmouseX", - "pmouseY", - "key", - "keyCode", - "keyPressed" - }; - - @Override - public boolean accept(VariableNode var) { - return Arrays.asList(p5Builtins).contains(var.getName()); - } - } - - /** - * A {@link VariableNodeFilter} that rejects implicit this references. - * (Names starting with "this$") - */ - public class ThisFilter implements VariableNodeFilter { - - @Override - public boolean accept(VariableNode var) { - return !var.getName().startsWith("this$"); - } - } - - /** - * A {@link VariableNodeFilter} that either rejects this-fields if hidden by - * a local, or prefixes its name with "this." - */ - public class LocalHidesThisFilter implements VariableNodeFilter { - - /** - * Reject a this-field if hidden by a local. - */ - public static final int MODE_HIDE = 0; // don't show hidden this fields - /** - * Prefix a this-fields name with "this." if hidden by a local. - */ - public static final int MODE_PREFIX = 1; // prefix hidden this fields with "this." - protected List locals; - protected int mode; - - /** - * Construct a {@link LocalHidesThisFilter}. - * - * @param locals a list of locals to check against - * @param mode either {@link #MODE_HIDE} or {@link #MODE_PREFIX} - */ - public LocalHidesThisFilter(List locals, int mode) { - this.locals = locals; - this.mode = mode; - } - - @Override - public boolean accept(VariableNode var) { - // check if the same name appears in the list of locals i.e. the local hides the field - for (VariableNode local : locals) { - if (var.getName().equals(local.getName())) { - switch (mode) { - case MODE_PREFIX: - var.setName("this." + var.getName()); - return true; - case MODE_HIDE: - return false; - } - } - } - return true; - } - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/VariableNode.java b/pdex/experimental/src/processing/mode/experimental/VariableNode.java deleted file mode 100755 index 66b0575d7..000000000 --- a/pdex/experimental/src/processing/mode/experimental/VariableNode.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2012 Martin Leopold - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - */ -package processing.mode.experimental; - -import com.sun.jdi.ArrayReference; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; -import com.sun.jdi.Value; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeNode; - -/** - * Model for a variable in the variable inspector. Has a type and name and - * optionally a value. Can have sub-variables (as is the case for objects, and - * arrays). - * - * @author Martin Leopold - */ -public class VariableNode implements MutableTreeNode { - - public static final int TYPE_UNKNOWN = -1; - public static final int TYPE_OBJECT = 0; - public static final int TYPE_ARRAY = 1; - public static final int TYPE_INTEGER = 2; - public static final int TYPE_FLOAT = 3; - public static final int TYPE_BOOLEAN = 4; - public static final int TYPE_CHAR = 5; - public static final int TYPE_STRING = 6; - public static final int TYPE_LONG = 7; - public static final int TYPE_DOUBLE = 8; - public static final int TYPE_BYTE = 9; - public static final int TYPE_SHORT = 10; - public static final int TYPE_VOID = 11; - protected String type; - protected String name; - protected Value value; - protected List children = new ArrayList(); - protected MutableTreeNode parent; - - /** - * Construct a {@link VariableNode}. - * @param name the name - * @param type the type - * @param value the value - */ - public VariableNode(String name, String type, Value value) { - this.name = name; - this.type = type; - this.value = value; - } - - public void setValue(Value value) { - this.value = value; - } - - public Value getValue() { - return value; - } - - /** - * Get a String representation of this variable nodes value. - * - * @return a String representing the value. - */ - public String getStringValue() { - String str; - if (value != null) { - if (getType() == TYPE_OBJECT) { - str = "instance of " + type; - } else if (getType() == TYPE_ARRAY) { - //instance of int[5] (id=998) --> instance of int[5] - str = value.toString().substring(0, value.toString().lastIndexOf(" ")); - } else if (getType() == TYPE_STRING) { - str = ((StringReference) value).value(); // use original string value (without quotes) - } else { - str = value.toString(); - } - } else { - str = "null"; - } - return str; - } - - public String getTypeName() { - return type; - } - - public int getType() { - if (type == null) { - return TYPE_UNKNOWN; - } - if (type.endsWith("[]")) { - return TYPE_ARRAY; - } - if (type.equals("int")) { - return TYPE_INTEGER; - } - if (type.equals("long")) { - return TYPE_LONG; - } - if (type.equals("byte")) { - return TYPE_BYTE; - } - if (type.equals("short")) { - return TYPE_SHORT; - } - if (type.equals("float")) { - return TYPE_FLOAT; - } - if (type.equals("double")) { - return TYPE_DOUBLE; - } - if (type.equals("char")) { - return TYPE_CHAR; - } - if (type.equals("java.lang.String")) { - return TYPE_STRING; - } - if (type.equals("boolean")) { - return TYPE_BOOLEAN; - } - if (type.equals("void")) { - return TYPE_VOID; //TODO: check if this is correct - } - return TYPE_OBJECT; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - /** - * Add a {@link VariableNode} as child. - * - * @param c the {@link VariableNode} to add. - */ - public void addChild(VariableNode c) { - children.add(c); - c.setParent(this); - } - - /** - * Add multiple {@link VariableNode}s as children. - * - * @param children the list of {@link VariableNode}s to add. - */ - public void addChildren(List children) { - for (VariableNode child : children) { - addChild(child); - } - } - - @Override - public TreeNode getChildAt(int i) { - return children.get(i); - } - - @Override - public int getChildCount() { - return children.size(); - } - - @Override - public TreeNode getParent() { - return parent; - } - - @Override - public int getIndex(TreeNode tn) { - return children.indexOf(tn); - } - - @Override - public boolean getAllowsChildren() { - if (value == null) { - return false; - } - - // handle strings - if (getType() == TYPE_STRING) { - return false; - } - - // handle arrays - if (getType() == TYPE_ARRAY) { - ArrayReference array = (ArrayReference) value; - return array.length() > 0; - } - // handle objects - if (getType() == TYPE_OBJECT) { // this also rules out null - // check if this object has any fields - ObjectReference obj = (ObjectReference) value; - return !obj.referenceType().visibleFields().isEmpty(); - } - - return false; - } - - /** - * This controls the default icon and disclosure triangle. - * - * @return true, will show "folder" icon and disclosure triangle. - */ - @Override - public boolean isLeaf() { - //return children.size() == 0; - return !getAllowsChildren(); - } - - @Override - public Enumeration children() { - return Collections.enumeration(children); - } - - /** - * Get a String representation of this {@link VariableNode}. - * - * @return the name of the variable (for sorting to work). - */ - @Override - public String toString() { - return getName(); // for sorting - } - - /** - * Get a String description of this {@link VariableNode}. Contains the type, - * name and value. - * - * @return the description - */ - public String getDescription() { - String str = ""; - if (type != null) { - str += type + " "; - } - str += name; - str += " = " + getStringValue(); - return str; - } - - @Override - public void insert(MutableTreeNode mtn, int i) { - children.add(i, this); - } - - @Override - public void remove(int i) { - MutableTreeNode mtn = children.remove(i); - if (mtn != null) { - mtn.setParent(null); - } - } - - @Override - public void remove(MutableTreeNode mtn) { - children.remove(mtn); - mtn.setParent(null); - } - - /** - * Remove all children from this {@link VariableNode}. - */ - public void removeAllChildren() { - for (MutableTreeNode mtn : children) { - mtn.setParent(null); - } - children.clear(); - } - - @Override - public void setUserObject(Object o) { - if (o instanceof Value) { - value = (Value) o; - } - } - - @Override - public void removeFromParent() { - parent.remove(this); - this.parent = null; - } - - @Override - public void setParent(MutableTreeNode mtn) { - parent = mtn; - } - - /** - * Test for equality. To be equal, two {@link VariableNode}s need to have - * equal type, name and value. - * - * @param obj the object to test for equality with this {@link VariableNode} - * @return true if the given object is equal to this {@link VariableNode} - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final VariableNode other = (VariableNode) obj; - if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) { - //System.out.println("type not equal"); - return false; - } - if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { - //System.out.println("name not equal"); - return false; - } - if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) { - //System.out.println("value not equal"); - return false; - } -// if (this.parent != other.parent && (this.parent == null || !this.parent.equals(other.parent))) { -// System.out.println("parent not equal: " + this.parent + "/" + other.parent); -// return false; -// } - return true; - } - - /** - * Returns a hash code based on type, name and value. - */ - @Override - public int hashCode() { - int hash = 3; - hash = 97 * hash + (this.type != null ? this.type.hashCode() : 0); - hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); - hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0); -// hash = 97 * hash + (this.parent != null ? this.parent.hashCode() : 0); - return hash; - } -} diff --git a/pdex/experimental/src/processing/mode/experimental/XQConsoleToggle.java b/pdex/experimental/src/processing/mode/experimental/XQConsoleToggle.java deleted file mode 100755 index 7d4ea9032..000000000 --- a/pdex/experimental/src/processing/mode/experimental/XQConsoleToggle.java +++ /dev/null @@ -1,131 +0,0 @@ -package processing.mode.experimental; - -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -import javax.swing.JPanel; - -/** - * Toggle Button displayed in the editor line status panel for toggling bewtween - * console and problems list. Glorified JPanel. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ - -public class XQConsoleToggle extends JPanel implements MouseListener { - public static final String[] text = { "Console", "Errors" }; - - private boolean toggleText = true; - private boolean toggleBG = true; - - /** - * Height of the component - */ - protected int height; - protected DebugEditor editor; - protected String buttonName; - - public XQConsoleToggle(DebugEditor editor, String buttonName, int height) { - this.editor = editor; - this.height = height; - this.buttonName = buttonName; - } - - public Dimension getPreferredSize() { - return new Dimension(70, height); - } - - public Dimension getMinimumSize() { - return getPreferredSize(); - } - - public Dimension getMaximumSize() { - return getPreferredSize(); - } - - public void paintComponent(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - - // On mouse hover, text and background color are changed. - if (toggleBG) { - g.setColor(new Color(0xff9DA7B0)); - g.fillRect(0, 0, this.getWidth(), this.getHeight()); - g.setColor(new Color(0xff29333D)); - g.fillRect(0, 0, 4, this.getHeight()); - g.setColor(Color.BLACK); - } else { - g.setColor(Color.DARK_GRAY); - g.fillRect(0, 0, this.getWidth(), this.getHeight()); - g.setColor(new Color(0xff29333D)); - g.fillRect(0, 0, 4, this.getHeight()); - g.setColor(Color.WHITE); - } - - g.drawString(buttonName, getWidth() / 2 + 2 // + 2 is a offset - - getFontMetrics(getFont()).stringWidth(buttonName) / 2, - this.getHeight() - 6); - } - - @Override - public void mouseClicked(MouseEvent arg0) { - - this.repaint(); - try { - editor.toggleView(buttonName); - } catch (Exception e) { - System.out.println(e); - // e.printStackTrace(); - } - toggleText = !toggleText; - } - - @Override - public void mouseEntered(MouseEvent arg0) { - toggleBG = !toggleBG; - this.repaint(); - } - - @Override - public void mouseExited(MouseEvent arg0) { - toggleBG = !toggleBG; - this.repaint(); - } - - @Override - public void mousePressed(MouseEvent arg0) { - } - - @Override - public void mouseReleased(MouseEvent arg0) { - } -} \ No newline at end of file diff --git a/pdex/experimental/src/processing/mode/experimental/XQErrorTable.java b/pdex/experimental/src/processing/mode/experimental/XQErrorTable.java deleted file mode 100755 index e64cf2c4b..000000000 --- a/pdex/experimental/src/processing/mode/experimental/XQErrorTable.java +++ /dev/null @@ -1,166 +0,0 @@ -package processing.mode.experimental; - -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - -import javax.swing.JTable; -import javax.swing.SwingWorker; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableModel; - -/** - * Custom JTable implementation for XQMode. Minor tweaks and addtions. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class XQErrorTable extends JTable { - - /** - * Column Names of JTable - */ - public static final String[] columnNames = { "Problem", "Tab", "Line" }; - - /** - * Column Widths of JTable. - */ - public int[] columnWidths = { 600, 100, 50 }; // Default Values - - /** - * Is the column being resized? - */ - private boolean columnResizing = false; - - /** - * ErrorCheckerService instance - */ - protected ErrorCheckerService errorCheckerService; - - @Override - public boolean isCellEditable(int rowIndex, int colIndex) { - return false; // Disallow the editing of any cell - } - - public XQErrorTable(final ErrorCheckerService errorCheckerService) { - this.errorCheckerService = errorCheckerService; - for (int i = 0; i < this.getColumnModel().getColumnCount(); i++) { - this.getColumnModel().getColumn(i) - .setPreferredWidth(columnWidths[i]); - } - - this.getTableHeader().setReorderingAllowed(false); - - this.addMouseListener(new MouseAdapter() { - @Override - synchronized public void mouseReleased(MouseEvent e) { - try { - errorCheckerService.scrollToErrorLine(((XQErrorTable) e - .getSource()).getSelectedRow()); - // System.out.print("Row clicked: " - // + ((XQErrorTable) e.getSource()).getSelectedRow()); - } catch (Exception e1) { - System.out.println("Exception XQErrorTable mouseReleased " - + e); - } - } - }); - - // Handles the resizing of columns. When mouse press is detected on - // table header, Stop updating the table, store new values of column - // widths,and resume updating. Updating is disabled as long as - // columnResizing is true - this.getTableHeader().addMouseListener(new MouseAdapter() { - - @Override - public void mousePressed(MouseEvent e) { - columnResizing = true; - } - - @Override - public void mouseReleased(MouseEvent e) { - columnResizing = false; - for (int i = 0; i < ((JTableHeader) e.getSource()) - .getColumnModel().getColumnCount(); i++) { - columnWidths[i] = ((JTableHeader) e.getSource()) - .getColumnModel().getColumn(i).getWidth(); - // System.out.println("nw " + columnWidths[i]); - } - } - }); - } - - - /** - * Updates table contents with new data - * @param tableModel - TableModel - * @return boolean - If table data was updated - */ - @SuppressWarnings("rawtypes") - synchronized public boolean updateTable(final TableModel tableModel) { - - // If problems list is not visible, no need to update - if (!this.isVisible()) { - return false; - } - - SwingWorker worker = new SwingWorker() { - - protected Object doInBackground() throws Exception { - return null; - } - - protected void done() { - - try { - setModel(tableModel); - - // Set column widths to user defined widths - for (int i = 0; i < getColumnModel().getColumnCount(); i++) { - getColumnModel().getColumn(i).setPreferredWidth( - columnWidths[i]); - } - getTableHeader().setReorderingAllowed(false); - validate(); - repaint(); - } catch (Exception e) { - System.out.println("Exception at XQErrorTable.updateTable " + e); - // e.printStackTrace(); - } - } - }; - - try { - if (!columnResizing) { - worker.execute(); - } - } catch (Exception e) { - System.out.println("ErrorTable updateTable Worker's slacking." - + e.getMessage()); - // e.printStackTrace(); - } - return true; - } - -} diff --git a/pdex/experimental/src/processing/mode/experimental/XQPreprocessor.java b/pdex/experimental/src/processing/mode/experimental/XQPreprocessor.java deleted file mode 100755 index 34ee2a9a2..000000000 --- a/pdex/experimental/src/processing/mode/experimental/XQPreprocessor.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - Part of the XQMode project - https://github.com/Manindra29/XQMode - - Under Google Summer of Code 2012 - - http://www.google-melange.com/gsoc/homepage/google/gsoc2012 - - Copyright (C) 2012 Manindra Moharana - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package processing.mode.experimental; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTParser; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.Modifier; -import org.eclipse.jdt.core.dom.NumberLiteral; -import org.eclipse.jdt.core.dom.SimpleType; -import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.text.edits.MalformedTreeException; -import org.eclipse.text.edits.TextEdit; - -import processing.mode.java.preproc.PdePreprocessor; - -/** - * My implementation of P5 preprocessor. Uses Eclipse JDT features instead of - * ANTLR. Performance gains mostly and full control over debug output. But needs - * lots and lots of testing. There will always an option to switch back to PDE - * preproc. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ -public class XQPreprocessor { - - private ASTRewrite rewrite = null; - private ArrayList imports; - private ArrayList extraImports; - - private String[] coreImports, defaultImports; - - public XQPreprocessor() { - PdePreprocessor p = new PdePreprocessor(null); - defaultImports = p.getDefaultImports(); - coreImports = p.getCoreImports(); - } - - /** - * The main method that performs preprocessing. Converts code into compilable java. - * @param source - String - * @param programImports - List of import statements - * @return String - Compile ready java code - */ - public String doYourThing(String source, - ArrayList programImports) { - this.extraImports = programImports; - //source = prepareImports() + source; - Document doc = new Document(source); - - ASTParser parser = ASTParser.newParser(AST.JLS4); - parser.setSource(doc.get().toCharArray()); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - - @SuppressWarnings("unchecked") - Map options = JavaCore.getOptions(); - - // Ben has decided to move on to 1.6. Yay! - JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); - options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); - parser.setCompilerOptions(options); - CompilationUnit cu = (CompilationUnit) parser.createAST(null); - cu.recordModifications(); - rewrite = ASTRewrite.create(cu.getAST()); - cu.accept(new XQASTVisitor()); - - TextEdit edits = cu.rewrite(doc, null); - try { - edits.apply(doc); - } catch (MalformedTreeException e) { - e.printStackTrace(); - } catch (BadLocationException e) { - e.printStackTrace(); - } - // System.out.println("------------XQPreProc-----------------"); - // System.out.println(doc.get()); - // System.out.println("------------XQPreProc End-----------------"); - - // Calculate main class offset - int position = doc.get().indexOf("{") + 1; - int lines = 0; - for (int i = 0; i < position; i++) { - if (doc.get().charAt(i) == '\n') { - lines++; - } - } - lines += 2; - // System.out.println("Lines: " + lines); - - return doc.get(); - } - - /** - * Returns all import statements as lines of code - * - * @return String - All import statements combined. Each import in a separate line. - */ - public String prepareImports() { - imports = new ArrayList(); - for (int i = 0; i < extraImports.size(); i++) { - imports.add(new String(extraImports.get(i).importName)); - } - imports.add(new String("// Default Imports")); - for (int i = 0; i < coreImports.length; i++) { - imports.add(new String("import " + coreImports[i] + ";")); - } - for (int i = 0; i < defaultImports.length; i++) { - imports.add(new String("import " + defaultImports[i] + ";")); - } - String totalImports = ""; - for (int i = 0; i < imports.size(); i++) { - totalImports += imports.get(i) + "\n"; - } - totalImports += "\n"; - return totalImports; - } - - public String prepareImports(ArrayList programImports) { - this.extraImports = programImports; - return prepareImports(); - } - - /** - * Visitor implementation that does all the substitution dirty work.
    - *
  • Any function not specified as being protected or private will be made - * 'public'. This means that void setup() becomes - * public void setup(). - * - *
  • Converts doubles into floats, i.e. 12.3 becomes 12.3f so that people - * don't have to add f after their numbers all the time since it's confusing - * for beginners. Also, most functions of p5 core deal with floats only. - * - * @author Manindra Moharana - * - */ - private class XQASTVisitor extends ASTVisitor { - @SuppressWarnings({ "unchecked", "rawtypes" }) - public boolean visit(MethodDeclaration node) { - if (node.getReturnType2() != null) { - // if return type is color, make it int - // if (node.getReturnType2().toString().equals("color")) { - // System.err.println("color type detected!"); - // node.setReturnType2(rewrite.getAST().newPrimitiveType( - // PrimitiveType.INT)); - // } - - // The return type is not void, no need to make it public - // if (!node.getReturnType2().toString().equals("void")) - // return true; - } - - // Simple method, make it public - if (node.modifiers().size() == 0 && !node.isConstructor()) { - // rewrite.set(node, node.getModifiersProperty(), - // Modifier.PUBLIC, - // null); - // rewrite.getListRewrite(node, - // node.getModifiersProperty()).insertLast(Modifier., null) - List newMod = rewrite.getAST().newModifiers(Modifier.PUBLIC); - node.modifiers().add(newMod.get(0)); - } - - return true; - } - - public boolean visit(NumberLiteral node) { - if (!node.getToken().endsWith("f") - && !node.getToken().endsWith("d")) { - for (int i = 0; i < node.getToken().length(); i++) { - if (node.getToken().charAt(i) == '.') { - - String s = node.getToken() + "f"; - node.setToken(s); - break; - } - } - } - return true; - } - - // public boolean visit(FieldDeclaration node) { - // if (node.getType().toString().equals("color")){ - // System.err.println("color type detected!"); - // node.setType(rewrite.getAST().newPrimitiveType( - // PrimitiveType.INT)); - // } - // return true; - // } - // - // public boolean visit(VariableDeclarationStatement node) { - // if (node.getType().toString().equals("color")){ - // System.err.println("color type detected!"); - // node.setType(rewrite.getAST().newPrimitiveType( - // PrimitiveType.INT)); - // } - // return true; - // } - - /** - * This is added just for debugging purposes - to make sure that all - * instances of color type have been substituded as in by the regex - * search in ErrorCheckerService.preprocessCode(). - */ - public boolean visit(SimpleType node) { - if (node.toString().equals("color")) { - System.err - .println("color type detected! \nThis shouldn't be happening! Please report this as an issue."); - } - return true; - - } - - } - -} diff --git a/pdex/experimental/theme/theme.txt b/pdex/experimental/theme/theme.txt deleted file mode 100755 index 1a6179f5c..000000000 --- a/pdex/experimental/theme/theme.txt +++ /dev/null @@ -1,34 +0,0 @@ -# DEBUGGER - -# breakpointed line background color -breakpoint.bgcolor = #f0f0f0 -# marker for breakpointed lines in left hand gutter (2 ascii characters) -breakpoint.marker = <> -breakpoint.marker.color = #4a545e - -# current line background color -currentline.bgcolor = #ffff96 -# marker for the current line in left hand gutter (2 ascii characters) -currentline.marker = -> -currentline.marker.color = #e27500 - -# left hand gutter background color -gutter.bgcolor = #fcfcfc -# color of vertical separation line -gutter.linecolor = #e9e9e9 -# space (in px) added to left and right of gutter markers -gutter.padding = 3 - - -# XQMODE - -# underline colors -editor.errorcolor = #ed2630 -editor.warningcolor = #ffc30e -editor.errormarkercolor = #ed2630 -editor.warningmarkercolor = #ffc30e - -# ERROR BAR - error bar on the right that shows the markers -errorbar.errorcolor = #ed2630 -errorbar.warningcolor = #ffc30e -errorbar.backgroundcolor = #2c343d diff --git a/pdex/experimental/theme/var-icons.gif b/pdex/experimental/theme/var-icons.gif deleted file mode 100755 index 1d0086a38..000000000 Binary files a/pdex/experimental/theme/var-icons.gif and /dev/null differ