All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.rsta.ac.js.tree.JavaScriptOutlineTree Maven / Gradle / Ivy

Go to download

A library adding code completion and other advanced features for Java, JavaScript, Perl, and other languages to RSyntaxTextArea.

There is a newer version: 3.3.0
Show newest version
/*
 * 01/28/2012
 *
 * Copyright (C) 2012 Robert Futrell
 * robert_futrell at users.sourceforge.net
 * http://fifesoft.com/rsyntaxtextarea
 *
 * This library is distributed under a modified BSD license.  See the included
 * RSTALanguageSupport.License.txt file for details.
 */
package org.fife.rsta.ac.js.tree;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.BadLocationException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import org.fife.rsta.ac.AbstractSourceTree;
import org.fife.rsta.ac.LanguageSupport;
import org.fife.rsta.ac.LanguageSupportFactory;
import org.fife.rsta.ac.js.IconFactory;
import org.fife.rsta.ac.js.JavaScriptLanguageSupport;
import org.fife.rsta.ac.js.JavaScriptParser;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;

import org.mozilla.javascript.Node;
import org.mozilla.javascript.Token;
import org.mozilla.javascript.ast.AstNode;
import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.FunctionNode;
import org.mozilla.javascript.ast.Name;
import org.mozilla.javascript.ast.VariableDeclaration;
import org.mozilla.javascript.ast.VariableInitializer;


/**
 * A tree view showing the outline of JavaScript source, similar to the
 * "Outline" view in the Eclipse JDT.  It also uses Eclipse's icons, just like
 * the rest of this code completion library.

* * You can get this tree automatically updating in response to edits in an * RSyntaxTextArea with {@link JavaScriptLanguageSupport} * installed by calling {@link #listenTo(RSyntaxTextArea)}. Note that, if you * have an application with multiple RSTA editors, you would want to call this * method each time a new editor is focused. * * @author Robert Futrell * @version 1.0 */ public class JavaScriptOutlineTree extends AbstractSourceTree { private DefaultTreeModel model; private RSyntaxTextArea textArea; private JavaScriptParser parser; private Listener listener; private static final int PRIORITY_FUNCTION = 1; private static final int PRIORITY_VARIABLE = 2; /** * Constructor. The tree created will not have its elements sorted * alphabetically. */ public JavaScriptOutlineTree() { this(false); } /** * Constructor. * * @param sorted Whether the tree should sort its elements alphabetically. * Note that outline trees will likely group nodes by type before * sorting (i.e. methods will be sorted in one group, fields in * another group, etc.). */ public JavaScriptOutlineTree(boolean sorted) { setSorted(sorted); setBorder(BorderFactory.createEmptyBorder(0,8,0,8)); setRootVisible(false); setCellRenderer(new JavaScriptTreeCellRenderer()); model = new DefaultTreeModel(new DefaultMutableTreeNode("Nothing")); setModel(model); listener = new Listener(); addTreeSelectionListener(listener); } /** * Refreshes listeners on the text area when its syntax style changes. */ private void checkForJavaScriptParsing() { // Remove possible listener on old Java parser (in case they're just // changing syntax style AWAY from Java) if (parser!=null) { parser.removePropertyChangeListener( JavaScriptParser.PROPERTY_AST, listener); parser = null; } // Get the Java language support (shared by all RSTA instances editing // Java that were registered with the LanguageSupportFactory). LanguageSupportFactory lsf = LanguageSupportFactory.get(); LanguageSupport support = lsf.getSupportFor(SyntaxConstants. SYNTAX_STYLE_JAVASCRIPT); JavaScriptLanguageSupport jls = (JavaScriptLanguageSupport)support; // Listen for re-parsing of the editor, and update the tree accordingly parser = jls.getParser(textArea); if (parser!=null) { // Should always be true parser.addPropertyChangeListener( JavaScriptParser.PROPERTY_AST, listener); // Populate with any already-existing AST AstRoot ast = parser.getAstRoot(); update(ast); } else { update((AstRoot)null); // Clear the tree } } /** * {@inheritDoc} */ public void expandInitialNodes() { // First, collapse all rows. int j=0; while (j-1) { // Should always be true int offs = jstn.getOffset(); textArea.select(offs, offs+len); } } } /** * {@inheritDoc} */ public boolean gotoSelectedElement() { TreePath path = getLeadSelectionPath();//e.getNewLeadSelectionPath(); if (path != null) { gotoElementAtPath(path); return true; } return false; } /** * {@inheritDoc} */ public void listenTo(RSyntaxTextArea textArea) { if (this.textArea!=null) { uninstall(); } // Nothing new to listen to if (textArea==null) { return; } // Listen for future language changes in the text editor this.textArea = textArea; textArea.addPropertyChangeListener( RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, listener); // Check whether we're currently editing JavaScript checkForJavaScriptParsing(); } /** * {@inheritDoc} */ public void uninstall() { if (parser!=null) { parser.removePropertyChangeListener( JavaScriptParser.PROPERTY_AST, listener); parser = null; } if (textArea!=null) { textArea.removePropertyChangeListener( RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, listener); textArea = null; } } /** * Refreshes this tree. * * @param ast The AST. If this is null then the tree is * cleared. */ private void update(AstRoot ast) { JavaScriptTreeNode root = new JavaScriptTreeNode(null); if (ast==null) { model.setRoot(root); return; } // Loop through all children and add tree nodes for functions and // variables Node child = ast.getFirstChild(); while (child!=null) { switch (child.getType()) { case Token.FUNCTION: FunctionNode fn = (FunctionNode)child; StringBuffer sb = new StringBuffer(fn.getName()).append('('); int paramCount = fn.getParamCount(); if (paramCount>0) { List fnParams = fn.getParams(); for (int i=0; i





© 2015 - 2024 Weber Informatics LLC | Privacy Policy