javascript.devtools/src/org/netbeans/modules/javascript/devtools/astbrowser/AstViewer.java
author Petr Hejl <phejl@netbeans.org>
Thu, 14 Jun 2012 14:39:46 +0200
changeset 17839 8eb66949294b
parent 17733 d8fc903a7e22
child 17876 85dacebf4fb0
permissions -rw-r--r--
Fixing NPE.
ppisl@17686
     1
/*
ppisl@17686
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
ppisl@17686
     3
 *
ppisl@17686
     4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
ppisl@17686
     5
 *
ppisl@17686
     6
 * The contents of this file are subject to the terms of either the GNU
ppisl@17686
     7
 * General Public License Version 2 only ("GPL") or the Common
ppisl@17686
     8
 * Development and Distribution License("CDDL") (collectively, the
ppisl@17686
     9
 * "License"). You may not use this file except in compliance with the
ppisl@17686
    10
 * License. You can obtain a copy of the License at
ppisl@17686
    11
 * http://www.netbeans.org/cddl-gplv2.html
ppisl@17686
    12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
ppisl@17686
    13
 * specific language governing permissions and limitations under the
ppisl@17686
    14
 * License.  When distributing the software, include this License Header
ppisl@17686
    15
 * Notice in each file and include the License file at
ppisl@17686
    16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
ppisl@17686
    17
 * particular file as subject to the "Classpath" exception as provided
ppisl@17686
    18
 * by Sun in the GPL Version 2 section of the License file that
ppisl@17686
    19
 * accompanied this code. If applicable, add the following below the
ppisl@17686
    20
 * License Header, with the fields enclosed by brackets [] replaced by
ppisl@17686
    21
 * your own identifying information:
ppisl@17686
    22
 * "Portions Copyrighted [year] [name of copyright owner]"
ppisl@17686
    23
 *
ppisl@17686
    24
 * Contributor(s):
ppisl@17686
    25
 *
ppisl@17686
    26
 * The Original Software is NetBeans. The Initial Developer of the Original
ppisl@17686
    27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
ppisl@17686
    28
 * Microsystems, Inc. All Rights Reserved.
ppisl@17686
    29
 *
ppisl@17686
    30
 * If you wish your version of this file to be governed by only the CDDL
ppisl@17686
    31
 * or only the GPL Version 2, indicate your decision by adding
ppisl@17686
    32
 * "[Contributor] elects to include this software in this distribution
ppisl@17686
    33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
ppisl@17686
    34
 * single choice of license, a recipient has the option to distribute
ppisl@17686
    35
 * your version of this file under either the CDDL, the GPL Version 2 or
ppisl@17686
    36
 * to extend the choice of license to its licensees as provided above.
ppisl@17686
    37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
ppisl@17686
    38
 * Version 2 license, then the option applies only if the new code is
ppisl@17686
    39
 * made subject to such option by the copyright holder.
ppisl@17686
    40
 */
ppisl@17686
    41
package org.netbeans.modules.javascript.devtools.astbrowser;
ppisl@17686
    42
ppisl@17686
    43
import com.oracle.nashorn.ir.FunctionNode;
ppisl@17686
    44
ppisl@17686
    45
import java.awt.*;
ppisl@17686
    46
import java.io.File;
ppisl@17686
    47
import java.io.Serializable;
ppisl@17686
    48
import java.util.ArrayList;
ppisl@17686
    49
import java.util.Enumeration;
ppisl@17686
    50
import java.util.List;
ppisl@17686
    51
import java.util.Vector;
ppisl@17686
    52
import javax.swing.*;
ppisl@17686
    53
import javax.swing.event.CaretEvent;
ppisl@17686
    54
import javax.swing.event.CaretListener;
ppisl@17686
    55
import javax.swing.event.TreeSelectionEvent;
ppisl@17686
    56
import javax.swing.event.TreeSelectionListener;
ppisl@17686
    57
import javax.swing.text.Document;
ppisl@17686
    58
import javax.swing.tree.DefaultTreeCellRenderer;
ppisl@17686
    59
import javax.swing.tree.DefaultTreeModel;
ppisl@17686
    60
import javax.swing.tree.TreeNode;
ppisl@17686
    61
import javax.swing.tree.TreePath;
ppisl@17686
    62
//import org.netbeans.api.gsf.CompilationInfo;
ppisl@17686
    63
//import org.netbeans.api.gsf.Error;
ppisl@17686
    64
//import org.netbeans.api.gsf.ParseEvent;
ppisl@17686
    65
//import org.netbeans.api.gsf.ParseListener;
ppisl@17686
    66
//import org.netbeans.api.gsf.Parser;
ppisl@17686
    67
//import org.netbeans.api.gsf.ParserFile;
ppisl@17686
    68
//import org.netbeans.api.gsf.ParserResult;
ppisl@17686
    69
//import org.netbeans.api.gsf.SourceFileReader;
ppisl@17686
    70
ppisl@17686
    71
//import org.netbeans.modules.csl.core.Language;
ppisl@17686
    72
//import org.netbeans.modules.csl.core.LanguageRegistry;
ppisl@17686
    73
import org.netbeans.modules.editor.NbEditorDocument;
ppisl@17686
    74
//import org.netbeans.modules.gsf.Language;
ppisl@17686
    75
//import org.netbeans.modules.gsf.LanguageRegistry;
ppisl@17686
    76
//import org.netbeans.modules.ruby.AstUtilities;
ppisl@17686
    77
//import org.netbeans.spi.gsf.DefaultParserFile;
ppisl@17686
    78
ppisl@17686
    79
ppisl@17686
    80
import org.netbeans.modules.javascript.devtools.astbrowser.TreeCreator;
ppisl@17686
    81
ppisl@17686
    82
import org.netbeans.modules.parsing.api.Snapshot;
ppisl@17686
    83
import org.netbeans.modules.parsing.api.Source;
ppisl@17686
    84
import org.openide.ErrorManager;
ppisl@17686
    85
import org.openide.cookies.EditorCookie;
ppisl@17686
    86
import org.openide.filesystems.FileObject;
ppisl@17686
    87
import org.openide.filesystems.FileUtil;
ppisl@17686
    88
import org.openide.loaders.DataObject;
ppisl@17686
    89
ppisl@17686
    90
import org.openide.nodes.Node;
ppisl@17686
    91
import org.openide.util.NbBundle;
ppisl@17686
    92
ppisl@17686
    93
import org.openide.windows.TopComponent;
ppisl@17686
    94
import org.openide.windows.WindowManager;
ppisl@17686
    95
ppisl@17686
    96
ppisl@17686
    97
/**
ppisl@17686
    98
 * This class is based on
ppisl@17686
    99
 *
ppisl@17686
   100
 * @author Petr Pisl
ppisl@17686
   101
 */
ppisl@17686
   102
public class AstViewer extends TopComponent {
ppisl@17686
   103
    private static final long serialVersionUID = 1L;
ppisl@17686
   104
    private static AstViewer instance;
ppisl@17686
   105
ppisl@17686
   106
    /** path to the icon used by the component and its open action */
ppisl@17686
   107
ppisl@17686
   108
    private static final String PREFERRED_ID = "PHPAstViewer";
ppisl@17686
   109
    private JTree tree;
ppisl@17686
   110
ppisl@17686
   111
    private boolean listen = true;
ppisl@17686
   112
    private CaretListener caretListener;
ppisl@17686
   113
    private JEditorPane lastPane;
ppisl@17686
   114
    private FunctionNode lastResult;
ppisl@17686
   115
ppisl@17686
   116
ppisl@17686
   117
    private Document highlightedDocument = null;
ppisl@17686
   118
    private TreeCreator.TreeASTNodeAdapter highlighted = null;
ppisl@17686
   119
    private JEditorPane highlightedEditor = null;
ppisl@17686
   120
    private NbEditorDocument lastDocument = null;
ppisl@17686
   121
    
ppisl@17686
   122
    private BrowserButtons browserButtons;
ppisl@17686
   123
ppisl@17686
   124
    public static final String JAVASCRIPT_MIME_TYPE = "text/javascript"; // NOI18N
ppisl@17686
   125
    
ppisl@17686
   126
    private AstViewer() {
ppisl@17686
   127
        initComponents();
ppisl@17686
   128
        setLayout(new BorderLayout());
ppisl@17686
   129
        tree = new JTree();
ppisl@17686
   130
//        tree.setCellRenderer(new Renderer());
ppisl@17686
   131
        ToolTipManager.sharedInstance().registerComponent(tree);
ppisl@17686
   132
        tree.setCellRenderer(new TreeCreator.TreeNodeCellRenderer());
ppisl@17686
   133
        tree.addTreeSelectionListener(new TreeSelectionListener() {
ppisl@17686
   134
                public void valueChanged(TreeSelectionEvent e) {
ppisl@17686
   135
                    if (!listen) {
ppisl@17686
   136
                        return;
ppisl@17686
   137
                    }
ppisl@17686
   138
ppisl@17686
   139
                    listen = false;
ppisl@17686
   140
                    selectionChanged();
ppisl@17686
   141
                    listen = true;
ppisl@17686
   142
                }
ppisl@17686
   143
            });
ppisl@17686
   144
        add(new JScrollPane(tree), BorderLayout.CENTER);
ppisl@17686
   145
        browserButtons = new BrowserButtons(this);
ppisl@17686
   146
        add(browserButtons, BorderLayout.SOUTH);
ppisl@17686
   147
        setName(NbBundle.getMessage(AstViewer.class, "CTL_AstViewer"));
ppisl@17686
   148
ppisl@17686
   149
        //setIcon(Utilities.loadImage(ICON_PATH, true));
ppisl@17686
   150
    }
ppisl@17686
   151
ppisl@17686
   152
    private void initComponents() {
ppisl@17686
   153
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
ppisl@17686
   154
        this.setLayout(layout);
ppisl@17686
   155
        layout.setHorizontalGroup(layout.createParallelGroup(
ppisl@17686
   156
                javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE));
ppisl@17686
   157
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
ppisl@17686
   158
                                      .addGap(0, 300, Short.MAX_VALUE));
ppisl@17686
   159
    }
ppisl@17686
   160
ppisl@17686
   161
    /**
ppisl@17686
   162
     * Gets default instance. Do not use directly: reserved for *.settings files only,
ppisl@17686
   163
     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
ppisl@17686
   164
     * To obtain the singleton instance, use {@link findInstance}.
ppisl@17686
   165
     */
ppisl@17686
   166
    public static synchronized AstViewer getDefault() {
ppisl@17686
   167
        if (instance == null) {
ppisl@17686
   168
            instance = new AstViewer();
ppisl@17686
   169
        }
ppisl@17686
   170
ppisl@17686
   171
        return instance;
ppisl@17686
   172
    }
ppisl@17686
   173
ppisl@17686
   174
    /**
ppisl@17686
   175
     * Obtain the AstViewer instance. Never call {@link #getDefault} directly!
ppisl@17686
   176
     */
ppisl@17686
   177
    public static synchronized AstViewer findInstance() {
ppisl@17686
   178
        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
ppisl@17686
   179
ppisl@17686
   180
        if (win == null) {
ppisl@17686
   181
            ErrorManager.getDefault()
ppisl@17686
   182
                        .log(ErrorManager.WARNING,
ppisl@17686
   183
                "Cannot find ASTBrowser component. It will not be located properly in the window system.");
ppisl@17686
   184
ppisl@17686
   185
            return getDefault();
ppisl@17686
   186
        }
ppisl@17686
   187
ppisl@17686
   188
        if (win instanceof AstViewer) {
ppisl@17686
   189
            return (AstViewer)win;
ppisl@17686
   190
        }
ppisl@17686
   191
ppisl@17686
   192
        ErrorManager.getDefault()
ppisl@17686
   193
                    .log(ErrorManager.WARNING,
ppisl@17686
   194
            "There seem to be multiple components with the '" + PREFERRED_ID +
ppisl@17686
   195
            "' ID. That is a potential source of errors and unexpected behavior.");
ppisl@17686
   196
ppisl@17686
   197
        return getDefault();
ppisl@17686
   198
    }
ppisl@17686
   199
ppisl@17686
   200
    public int getPersistenceType() {
ppisl@17686
   201
        return TopComponent.PERSISTENCE_ALWAYS;
ppisl@17686
   202
    }
ppisl@17686
   203
ppisl@17686
   204
    public void componentOpened() {
ppisl@17686
   205
    }
ppisl@17686
   206
ppisl@17686
   207
    public void componentShowing() {
ppisl@17686
   208
        super.componentShowing();
ppisl@17686
   209
ppisl@17686
   210
        // TODO add custom code on component opening
ppisl@17686
   211
        refresh();
ppisl@17686
   212
ppisl@17686
   213
        //
ppisl@17686
   214
        //        if (listener == null) {
ppisl@17686
   215
        //            listener = new Listener(this);
ppisl@17686
   216
        //        }
ppisl@17686
   217
    }
ppisl@17686
   218
ppisl@17686
   219
    public void componentHidden() {
ppisl@17686
   220
        super.componentHidden();
ppisl@17686
   221
ppisl@17686
   222
        // TODO add custom code on component closing
ppisl@17686
   223
        //        if (listener != null) {
ppisl@17686
   224
        //            listener.remove();
ppisl@17686
   225
        //            listener = null;
ppisl@17686
   226
        //        }
ppisl@17686
   227
    }
ppisl@17686
   228
ppisl@17686
   229
    public void componentClosed() {
ppisl@17686
   230
        if (lastPane != null) {
ppisl@17686
   231
            lastPane.removeCaretListener(caretListener);
ppisl@17686
   232
            lastPane = null;
ppisl@17686
   233
            lastDocument = null;
ppisl@17686
   234
            org.openide.awt.StatusDisplayer.getDefault().setStatusText("");
ppisl@17686
   235
        }
ppisl@17686
   236
    }
ppisl@17686
   237
ppisl@17686
   238
    /** replaces this in object stream */
ppisl@17686
   239
    public Object writeReplace() {
ppisl@17686
   240
        return new ResolvableHelper();
ppisl@17686
   241
    }
ppisl@17686
   242
ppisl@17686
   243
    protected String preferredID() {
ppisl@17686
   244
        return PREFERRED_ID;
ppisl@17686
   245
    }
ppisl@17686
   246
ppisl@17686
   247
    /*public void refresh(FileObject fo, ParserResult result) {
ppisl@17686
   248
        if ((result == null) || (result.getAst() == null)) {
ppisl@17686
   249
            DefaultTreeModel model = new EmptyTreeModel();
ppisl@17686
   250
            tree.setModel(model);
ppisl@17686
   251
        } else {
ppisl@17686
   252
            DefaultTreeModel model = new DefaultTreeModel(result.getAst());
ppisl@17686
   253
            tree.setModel(model);
ppisl@17686
   254
        }
ppisl@17686
   255
ppisl@17686
   256
        // Update caret listener
ppisl@17686
   257
        DataObject dobj;
ppisl@17686
   258
ppisl@17686
   259
        try {
ppisl@17686
   260
            dobj = DataObject.find(fo);
ppisl@17686
   261
        } catch (DataObjectNotFoundException ex) {
ppisl@17686
   262
            return;
ppisl@17686
   263
        }
ppisl@17686
   264
ppisl@17686
   265
        EditorCookie editorCookie = (EditorCookie)dobj.getCookie(EditorCookie.class);
ppisl@17686
   266
ppisl@17686
   267
        if (editorCookie == null) {
ppisl@17686
   268
            return;
ppisl@17686
   269
        }
ppisl@17686
   270
ppisl@17686
   271
        JEditorPane[] panes = editorCookie.getOpenedPanes();
ppisl@17686
   272
ppisl@17686
   273
        if ((panes == null) || (panes.length == 0)) {
ppisl@17686
   274
            return;
ppisl@17686
   275
        }
ppisl@17686
   276
ppisl@17686
   277
        JEditorPane pane = panes[0];
ppisl@17686
   278
ppisl@17686
   279
        if (caretListener == null) {
ppisl@17686
   280
            caretListener = new CListener();
ppisl@17686
   281
        }
ppisl@17686
   282
ppisl@17686
   283
        if ((lastPane != null) && (lastPane != pane)) {
ppisl@17686
   284
            lastPane.removeCaretListener(caretListener);
ppisl@17686
   285
            lastPane = null;
ppisl@17686
   286
            lastDocument = null;
ppisl@17686
   287
        }
ppisl@17686
   288
ppisl@17686
   289
        if (lastPane == null) {
ppisl@17686
   290
            pane.addCaretListener(caretListener);
ppisl@17686
   291
            lastPane = pane;
ppisl@17686
   292
            lastDocument = (NbEditorDocument)pane.getDocument();
ppisl@17686
   293
        }
ppisl@17686
   294
ppisl@17686
   295
        lastResult = result;
ppisl@17686
   296
ppisl@17686
   297
        int pos = pane.getCaret().getDot();
ppisl@17686
   298
        String mimeType = (String)pane.getDocument().getProperty("mimeType");
ppisl@17686
   299
        Language l = LanguageRegistry.getInstance().getLanguageByMimeType(mimeType);
ppisl@17686
   300
        pos = l.getParser().getPositionManager().getAstOffset(result, pos);
ppisl@17686
   301
        showPosition(pos);
ppisl@17686
   302
    }
ppisl@17686
   303
*/
ppisl@17686
   304
    protected void refresh() {
ppisl@17686
   305
        Node[] ns = TopComponent.getRegistry().getActivatedNodes();
ppisl@17686
   306
ppisl@17686
   307
        if (ns.length != 1) {
ppisl@17686
   308
            return;
ppisl@17686
   309
        }
ppisl@17686
   310
ppisl@17686
   311
        DataObject dataObject = (DataObject)ns[0].getLookup().lookup(DataObject.class);
ppisl@17686
   312
        EditorCookie editorCookie = (EditorCookie)ns[0].getLookup().lookup(EditorCookie.class);
ppisl@17686
   313
ppisl@17686
   314
        if (editorCookie == null) {
ppisl@17686
   315
            return;
ppisl@17686
   316
        }
ppisl@17686
   317
ppisl@17686
   318
        if (editorCookie.getOpenedPanes() == null) {
ppisl@17686
   319
            return;
ppisl@17686
   320
        }
ppisl@17686
   321
ppisl@17686
   322
        if (editorCookie.getOpenedPanes().length < 1) {
ppisl@17686
   323
            return;
ppisl@17686
   324
        }
ppisl@17686
   325
ppisl@17686
   326
        JEditorPane pane = editorCookie.getOpenedPanes()[0];
ppisl@17686
   327
ppisl@17686
   328
        if (caretListener == null) {
ppisl@17686
   329
            caretListener = new CListener();
ppisl@17686
   330
        }
ppisl@17686
   331
ppisl@17686
   332
        if ((lastPane != null) && (lastPane != pane)) {
ppisl@17686
   333
            lastPane.removeCaretListener(caretListener);
ppisl@17686
   334
            lastPane = null;
ppisl@17686
   335
            lastDocument = null;
ppisl@17686
   336
        }
ppisl@17686
   337
ppisl@17686
   338
        if (lastPane == null) {
ppisl@17686
   339
            pane.addCaretListener(caretListener);
ppisl@17686
   340
            lastPane = pane;
ppisl@17686
   341
            lastDocument = (NbEditorDocument)pane.getDocument();
ppisl@17686
   342
        }
ppisl@17686
   343
ppisl@17686
   344
        final Document doc = editorCookie.getDocument();
ppisl@17686
   345
ppisl@17686
   346
        if ((doc == null) || !(doc instanceof NbEditorDocument)) {
ppisl@17686
   347
            return;
ppisl@17686
   348
        }
ppisl@17686
   349
ppisl@17686
   350
        String mimeType = (String)doc.getProperty("mimeType");
ppisl@17686
   351
ppisl@17686
   352
        if (mimeType == null || !mimeType.equals(JAVASCRIPT_MIME_TYPE)) {
ppisl@17686
   353
            DefaultTreeModel model = new EmptyTreeModel();
ppisl@17686
   354
            tree.setModel(model);
ppisl@17686
   355
ppisl@17686
   356
            return;
ppisl@17686
   357
        }
ppisl@17686
   358
            
ppisl@17686
   359
        try {
ppisl@17686
   360
//            Language l = LanguageRegistry.getInstance().getLanguageByMimeType(mimeType);
ppisl@17686
   361
//            if (l == null) {
ppisl@17686
   362
//                DefaultTreeModel model = new EmptyTreeModel();
ppisl@17686
   363
//                tree.setModel(model);
ppisl@17686
   364
//
ppisl@17686
   365
//                return;
ppisl@17686
   366
//            }
ppisl@17686
   367
ppisl@17686
   368
            TreeNode astNode = null;
ppisl@17686
   369
ppisl@17686
   370
            DataObject dobj = (DataObject)doc.getProperty(doc.StreamDescriptionProperty);
ppisl@17686
   371
            FileObject file = dobj.getPrimaryFile();
ppisl@17686
   372
ppisl@17686
   373
            //Iterable<? extends ComFile> iterable = l.getParser().parse(file, doc.getText(0, doc.getLength()), errorHandler);
ppisl@17686
   374
            //ParserResult result =
ppisl@17686
   375
            //    l.getParser().parseFiles(file, doc.getText(0, doc.getLength()), errorHandler);
ppisl@17686
   376
            
ppisl@17686
   377
            
ppisl@17686
   378
            FunctionNode fn = parseNashron(doc.getText(0, doc.getLength()));
ppisl@17686
   379
//            Parser parser = l.getParser();
ppisl@17686
   380
//            
ppisl@17686
   381
//            final ParserResult[] resultHolder = new ParserResult[1];
ppisl@17686
   382
//            ParseListener listener =
ppisl@17686
   383
//                new ParseListener() {
ppisl@17686
   384
//                    public void started(ParseEvent e) {
ppisl@17686
   385
//                    }
ppisl@17686
   386
//
ppisl@17686
   387
//                    public void error(org.netbeans.modules.gsf.api.Error e) {
ppisl@17686
   388
//                    }
ppisl@17686
   389
//
ppisl@17686
   390
//                    public void exception(Exception e) {
ppisl@17686
   391
//                    }
ppisl@17686
   392
//
ppisl@17686
   393
//                    public void finished(ParseEvent e) {
ppisl@17686
   394
//                        // TODO - check state
ppisl@17686
   395
//                        if (e.getKind() == ParseEvent.Kind.PARSE) {
ppisl@17686
   396
//                            resultHolder[0] = e.getResult();
ppisl@17686
   397
//                        }
ppisl@17686
   398
//                    }
ppisl@17686
   399
//                                 
ppisl@17686
   400
//                };
ppisl@17686
   401
//
ppisl@17686
   402
//            List<ParserFile> sourceFiles = new ArrayList<ParserFile>(1);
ppisl@17686
   403
//            sourceFiles.add(new DefaultParserFile(file, null, false));
ppisl@17686
   404
//
ppisl@17686
   405
//            SourceFileReader reader =
ppisl@17686
   406
//                new SourceFileReader() {
ppisl@17686
   407
//                    public CharSequence read(ParserFile fileObject)
ppisl@17686
   408
//                        throws IOException {
ppisl@17686
   409
//                        try {
ppisl@17686
   410
//                            return doc.getText(0, doc.getLength());
ppisl@17686
   411
//                        } catch (BadLocationException ex) {
ppisl@17686
   412
//                            return "";
ppisl@17686
   413
//                        }
ppisl@17686
   414
//                    }
ppisl@17686
   415
//                
ppisl@17686
   416
//                public int getCaretOffset(ParserFile file) {
ppisl@17686
   417
//                    return -1;
ppisl@17686
   418
//                }
ppisl@17686
   419
//            };
ppisl@17686
   420
//            
ppisl@17686
   421
//            parser.parseFiles(new Parser.Job (sourceFiles, listener, reader, null));
ppisl@17686
   422
//
ppisl@17686
   423
//            ParserResult result = resultHolder[0];
ppisl@17686
   424
            lastResult = fn;
ppisl@17686
   425
            
phejl@17839
   426
            astNode = fn == null ? null : (new TreeCreator()).createTree(fn, browserButtons.isDetailView());
ppisl@17686
   427
ppisl@17686
   428
            if (astNode == null) {
ppisl@17686
   429
                return;
ppisl@17686
   430
            }
ppisl@17686
   431
ppisl@17686
   432
            DefaultTreeModel model = new DefaultTreeModel(astNode);
ppisl@17686
   433
            tree.setModel(model);
ppisl@17686
   434
        } catch (Exception ex) {
ppisl@17686
   435
            ErrorManager.getDefault().notify(ex);
ppisl@17686
   436
        }
ppisl@17686
   437
    }
ppisl@17686
   438
ppisl@17686
   439
    private static final boolean SCRIPTING =
ppisl@17686
   440
            Boolean.valueOf(System.getProperty("parsertest.scripting"));
ppisl@17686
   441
    
ppisl@17686
   442
    protected com.oracle.nashorn.ir.FunctionNode parseNashron(String text) {
ppisl@17686
   443
        long start = System.currentTimeMillis();
ppisl@17686
   444
        com.oracle.nashorn.runtime.Source source = new com.oracle.nashorn.runtime.Source("test", text);
ppisl@17686
   445
        long end = System.currentTimeMillis();
ppisl@17686
   446
//        System.out.println("Nashron creating source: " + (end - start));
ppisl@17686
   447
        start = System.currentTimeMillis();
ppisl@17733
   448
        com.oracle.nashorn.runtime.options.Options options = new com.oracle.nashorn.runtime.options.Options("nashorn");
ppisl@17686
   449
        options.process(new String[]{
ppisl@17686
   450
            "--parse-only=true", 
ppisl@17686
   451
            //"--print-parse=true",    
ppisl@17686
   452
            "--debug-lines=false",
ppisl@17686
   453
            "--print-symbols=true", 
ppisl@17686
   454
            "--dump-ir-graph=true", 
ppisl@17686
   455
            "--print-symbols=true"});
ppisl@17686
   456
        end = System.currentTimeMillis();
ppisl@17686
   457
//        System.out.println("Nashron creating options: " + (end - start));
ppisl@17686
   458
        //options._scripting = SCRIPTING;
ppisl@17686
   459
        
ppisl@17686
   460
        start = System.currentTimeMillis();
ppisl@17686
   461
        com.oracle.nashorn.runtime.ErrorManager errors = new IdeErrorManager();
ppisl@17686
   462
        errors.setLimit(100);
ppisl@17686
   463
        end = System.currentTimeMillis();
ppisl@17686
   464
//        System.out.println("Nashron creating errors: " + (end - start));
ppisl@17686
   465
        
ppisl@17686
   466
        start = System.currentTimeMillis();
ppisl@17686
   467
        com.oracle.nashorn.runtime.Context contextN = new com.oracle.nashorn.runtime.Context(options, errors);
ppisl@17686
   468
        com.oracle.nashorn.runtime.Context.setContext(contextN);
ppisl@17686
   469
        //contextN.setGlobal(new com.oracle.nashorn.objects.Global(contextN));
ppisl@17686
   470
        end = System.currentTimeMillis();
ppisl@17686
   471
//        System.out.println("Nashron creating context: " + (end - start));
ppisl@17686
   472
        start = System.currentTimeMillis();
ppisl@17686
   473
ppisl@17686
   474
        com.oracle.nashorn.codegen.Compiler compiler = new com.oracle.nashorn.codegen.Compiler(source, contextN);
ppisl@17686
   475
        
ppisl@17686
   476
        end = System.currentTimeMillis();
ppisl@17686
   477
//        System.out.println("Nashron creating compiler: " + (end - start));
ppisl@17686
   478
        start = System.currentTimeMillis();
ppisl@17686
   479
        com.oracle.nashorn.parser.Parser parser = new com.oracle.nashorn.parser.Parser(compiler);
ppisl@17686
   480
        com.oracle.nashorn.ir.FunctionNode node = parser.parse(com.oracle.nashorn.codegen.CompilerConstants.runScriptName);
ppisl@17686
   481
        //node.accept(new com.oracle.nashorn.codegen.Lower(compiler));
ppisl@17686
   482
        end = System.currentTimeMillis();
ppisl@17686
   483
        System.out.println("Nashron parsing: " + (end - start) + "ms");
ppisl@17686
   484
        System.out.println("Errors: " + errors.getNumErrors());
ppisl@17686
   485
        System.out.println("Warnings: " + errors.getNumWarnings());
ppisl@17686
   486
        
ppisl@17686
   487
        
ppisl@17686
   488
        return node;
ppisl@17686
   489
    }
ppisl@17686
   490
    
ppisl@17686
   491
    private TreeNode findNode(TreeNode parent, int index) {
ppisl@17686
   492
        if (parent instanceof TreeCreator.TreeASTNodeAdapter) {
ppisl@17686
   493
            int begin = ((TreeCreator.TreeASTNodeAdapter)parent).getStartOffset();
ppisl@17686
   494
            int end = ((TreeCreator.TreeASTNodeAdapter)parent).getEndOffset();
ppisl@17686
   495
ppisl@17686
   496
            if ((index >= begin) && (index <= end) && begin > 0) {
ppisl@17686
   497
                TreeNode candidate = parent;
ppisl@17686
   498
ppisl@17686
   499
                for (int i = 0; i < parent.getChildCount(); i++) {
ppisl@17686
   500
                    TreeNode child = parent.getChildAt(i);
ppisl@17686
   501
                    TreeNode found = findNode(child, index);
ppisl@17686
   502
ppisl@17686
   503
                    if (found != null) {
ppisl@17686
   504
                        return found;
ppisl@17686
   505
ppisl@17686
   506
                        //                            if (candidate == null) {
ppisl@17686
   507
                        //                                candidate = found;
ppisl@17686
   508
                        //                            } else {
ppisl@17686
   509
                        //                                // See which one is better - further away.
ppisl@17686
   510
                        //                                // Another fitness test could be the size of the range...
ppisl@17686
   511
                        //                                int depth1 = 0;
ppisl@17686
   512
                        //
ppisl@17686
   513
                        //                                // See which one is better - further away.
ppisl@17686
   514
                        //                                // Another fitness test could be the size of the range...
ppisl@17686
   515
                        //                                int depth2 = 0;
ppisl@17686
   516
                        //                                TreeNode n = candidate;
ppisl@17686
   517
                        //
ppisl@17686
   518
                        //                                while ((n != null) && (n != child)) {
ppisl@17686
   519
                        //                                    n = n.getParent();
ppisl@17686
   520
                        //                                    depth1++;
ppisl@17686
   521
                        //                                }
ppisl@17686
   522
                        //
ppisl@17686
   523
                        //                                n = found;
ppisl@17686
   524
                        //
ppisl@17686
   525
                        //                                while ((n != null) && (n != child)) {
ppisl@17686
   526
                        //                                    n = n.getParent();
ppisl@17686
   527
                        //                                    depth2++;
ppisl@17686
   528
                        //                                }
ppisl@17686
   529
                        //
ppisl@17686
   530
                        //                                if (depth2 < depth1) {
ppisl@17686
   531
                        //                                    candidate = found;
ppisl@17686
   532
                        //                                }
ppisl@17686
   533
                        //                            }
ppisl@17686
   534
                    }
ppisl@17686
   535
                }
ppisl@17686
   536
ppisl@17686
   537
                return candidate;
ppisl@17686
   538
            } else {
ppisl@17686
   539
                TreeNode candidate = null;
ppisl@17686
   540
ppisl@17686
   541
                for (int i = 0; i < parent.getChildCount(); i++) {
ppisl@17686
   542
                    TreeNode child = parent.getChildAt(i);
ppisl@17686
   543
                    TreeNode found = findNode(child, index);
ppisl@17686
   544
ppisl@17686
   545
                    if (found != null) {
ppisl@17686
   546
                        return found;
ppisl@17686
   547
                    }
ppisl@17686
   548
                }
ppisl@17686
   549
ppisl@17686
   550
                return null;
ppisl@17686
   551
            }
ppisl@17686
   552
        } else {
ppisl@17686
   553
            return null;
ppisl@17686
   554
        }
ppisl@17686
   555
        //return null;
ppisl@17686
   556
    }
ppisl@17686
   557
ppisl@17686
   558
    private void showPosition(int position) {
ppisl@17686
   559
        TreeNode root = (TreeNode)tree.getModel().getRoot();
ppisl@17686
   560
        TreeNode closest = findNode(root, position);
ppisl@17686
   561
        List<TreeNode> path = new ArrayList<TreeNode>();
ppisl@17686
   562
ppisl@17686
   563
        while (closest != null) {
ppisl@17686
   564
            path.add(0, closest);
ppisl@17686
   565
            closest = closest.getParent();
ppisl@17686
   566
        }
ppisl@17686
   567
        
ppisl@17686
   568
        if (path.size() == 0) {
ppisl@17686
   569
            return;
ppisl@17686
   570
        }
ppisl@17686
   571
ppisl@17686
   572
        try {
ppisl@17686
   573
            TreePath treePath = new TreePath(path.toArray());
ppisl@17686
   574
            listen = false;
ppisl@17686
   575
            tree.setSelectionPath(treePath);
ppisl@17686
   576
            tree.expandPath(treePath);
ppisl@17686
   577
            tree.scrollPathToVisible(treePath);
ppisl@17686
   578
            org.openide.awt.StatusDisplayer.getDefault()
ppisl@17686
   579
                                           .setStatusText("Caret position : " + position);
ppisl@17686
   580
            listen = true;
ppisl@17686
   581
        } catch (Exception ex) {
ppisl@17686
   582
            // XXX TODO debug
ppisl@17686
   583
            ex.printStackTrace();
ppisl@17686
   584
        }
ppisl@17686
   585
    }
ppisl@17686
   586
ppisl@17686
   587
    private void selectionChanged() {
ppisl@17686
   588
        System.out.println("selection changed");
ppisl@17686
   589
        removeHighlight();
ppisl@17686
   590
ppisl@17686
   591
        if (!tree.hasFocus()) {
ppisl@17686
   592
            return;
ppisl@17686
   593
        }
ppisl@17686
   594
ppisl@17686
   595
        TreePath selPath = tree.getSelectionPath();
ppisl@17686
   596
ppisl@17686
   597
        if (selPath == null) {
ppisl@17686
   598
            return;
ppisl@17686
   599
        }
ppisl@17686
   600
ppisl@17686
   601
        //NavigatorNode node = (NavigatorNode) selPath.getLastPathComponent ();
ppisl@17686
   602
       TreeCreator.TreeASTNodeAdapter node =
ppisl@17686
   603
            (TreeCreator.TreeASTNodeAdapter)tree.getLastSelectedPathComponent();
ppisl@17686
   604
ppisl@17686
   605
        if (node == null) {
ppisl@17686
   606
            return;
ppisl@17686
   607
        }
ppisl@17686
   608
        
ppisl@17686
   609
       if (node.getStartOffset() == -1) {
ppisl@17686
   610
           return;
ppisl@17686
   611
       }
ppisl@17686
   612
       
ppisl@17686
   613
        highlighted = node;
ppisl@17686
   614
        HighlightSections highlighter = (HighlightSections) lastDocument.getProperty(HighlightSections.class);
ppisl@17686
   615
        highlightedDocument = lastDocument;
ppisl@17686
   616
        
ppisl@17686
   617
        highlighter.setSelectedNode(highlightedDocument, node);
ppisl@17686
   618
        if (browserButtons.showLocationToken()) {
ppisl@17686
   619
            highlighter.addLocationToken(lastResult);
ppisl@17686
   620
        }
ppisl@17686
   621
        lastPane.setCaretPosition(node.getStartOffset());
ppisl@17686
   622
        System.out.println("carret possition nastaveno: " + node.getStartOffset());
ppisl@17686
   623
        highlightedEditor = lastPane;
ppisl@17686
   624
        highlightedEditor.repaint();
ppisl@17686
   625
    }
ppisl@17686
   626
ppisl@17686
   627
    private void removeHighlight() {
ppisl@17686
   628
        if (highlighted == null) {
ppisl@17686
   629
            return;
ppisl@17686
   630
        }
ppisl@17686
   631
        HighlightSections highlighter = (HighlightSections) highlightedDocument.getProperty(HighlightSections.class);
ppisl@17686
   632
        highlighter.setSelectedNode(highlightedDocument, null);
ppisl@17686
   633
        highlightedEditor.repaint();
ppisl@17686
   634
        highlighted = null;
ppisl@17686
   635
        highlightedDocument = null;
ppisl@17686
   636
        highlightedEditor = null;
ppisl@17686
   637
    }
ppisl@17686
   638
ppisl@17686
   639
    class CListener implements CaretListener {
ppisl@17686
   640
        public void caretUpdate(CaretEvent e) {
ppisl@17686
   641
            if (!listen) {
ppisl@17686
   642
                return;
ppisl@17686
   643
            }
ppisl@17686
   644
ppisl@17686
   645
            int position = e.getDot();
ppisl@17686
   646
            //String mimeType = (String)lastPane.getDocument().getProperty("mimeType");
ppisl@17686
   647
            //Language l = LanguageRegistry.getInstance().getLanguageByMimeType(mimeType);
ppisl@17686
   648
            //position = l.getParser().getPositionManager().getAstOffset(lastResult, position);
ppisl@17686
   649
            showPosition(position);
ppisl@17686
   650
        }
ppisl@17686
   651
    }
ppisl@17686
   652
ppisl@17686
   653
    private static class Renderer extends DefaultTreeCellRenderer {
ppisl@17686
   654
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,
ppisl@17686
   655
            boolean expanded, boolean leaf, int row, boolean hasFocus) {
ppisl@17686
   656
            return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
ppisl@17686
   657
                hasFocus);
ppisl@17686
   658
        }
ppisl@17686
   659
    }
ppisl@17686
   660
ppisl@17686
   661
    static final class ResolvableHelper implements Serializable {
ppisl@17686
   662
        private static final long serialVersionUID = 1L;
ppisl@17686
   663
ppisl@17686
   664
        public Object readResolve() {
ppisl@17686
   665
            return AstViewer.getDefault();
ppisl@17686
   666
        }
ppisl@17686
   667
    }
ppisl@17686
   668
ppisl@17686
   669
    
ppisl@17686
   670
    private static TreeNode EMPTY_ROOT = new TreeNode() {
ppisl@17686
   671
        public TreeNode getChildAt(int arg0) {
ppisl@17686
   672
            throw new UnsupportedOperationException("Not supported yet.");
ppisl@17686
   673
        }
ppisl@17686
   674
ppisl@17686
   675
        public int getChildCount() {
ppisl@17686
   676
            return 0;
ppisl@17686
   677
        }
ppisl@17686
   678
ppisl@17686
   679
        public TreeNode getParent() {
ppisl@17686
   680
            return null;
ppisl@17686
   681
        }
ppisl@17686
   682
ppisl@17686
   683
        public int getIndex(TreeNode arg0) {
ppisl@17686
   684
            return -1;
ppisl@17686
   685
        }
ppisl@17686
   686
ppisl@17686
   687
        public boolean getAllowsChildren() {
ppisl@17686
   688
            return false;
ppisl@17686
   689
        }
ppisl@17686
   690
ppisl@17686
   691
        public boolean isLeaf() {
ppisl@17686
   692
            return true;
ppisl@17686
   693
        }
ppisl@17686
   694
ppisl@17686
   695
        public Enumeration children() {
ppisl@17686
   696
            return new Vector().elements();
ppisl@17686
   697
        }
ppisl@17686
   698
    };
ppisl@17686
   699
    
ppisl@17686
   700
    private class EmptyTreeModel extends DefaultTreeModel {
ppisl@17686
   701
        
ppisl@17686
   702
        EmptyTreeModel() {
ppisl@17686
   703
            super(EMPTY_ROOT);
ppisl@17686
   704
        }
ppisl@17686
   705
        
ppisl@17686
   706
    }
ppisl@17686
   707
    
ppisl@17686
   708
    protected void checkOffsets() {
ppisl@17686
   709
        CheckOffsetIntegrityVisitor visitor = new CheckOffsetIntegrityVisitor();
ppisl@17686
   710
        int offset = visitor.checkOffset(lastResult);
ppisl@17686
   711
        System.out.println("offset: " + offset);
ppisl@17686
   712
        if (offset > -1) {
ppisl@17686
   713
            lastPane.setCaretPosition(offset);
ppisl@17686
   714
        }
ppisl@17686
   715
    }
ppisl@17686
   716
    
ppisl@17686
   717
    protected void runPerformanceTest(File file) {
ppisl@17686
   718
ppisl@17686
   719
        if (!file.isDirectory()) {
ppisl@17686
   720
            System.out.println("Running performance test for: " + file.getAbsolutePath());
ppisl@17686
   721
            Source source = Source.create(FileUtil.toFileObject(file));
ppisl@17686
   722
            Snapshot snapshot = source.createSnapshot();
ppisl@17686
   723
            long nTime = parseNashronPerformance(snapshot);
ppisl@17686
   724
//            long rTime = parseRhinoPerformance(snapshot);
ppisl@17686
   725
            System.out.println("Nashorn: " + nTime);
ppisl@17686
   726
//            System.out.println("Rhino: " + rTime);
ppisl@17686
   727
        } else {
ppisl@17686
   728
            System.out.println("Running performance test for folder: " + file.getAbsolutePath());
ppisl@17686
   729
            FileObject folder = FileUtil.toFileObject(file);
ppisl@17686
   730
            Enumeration<? extends FileObject> en = folder.getChildren(true);
ppisl@17686
   731
            int count = 0;
ppisl@17686
   732
            long nTime = 0;
ppisl@17686
   733
            long rTime = 0;
ppisl@17686
   734
            while(en.hasMoreElements()) {
ppisl@17686
   735
                FileObject fo = en.nextElement();
ppisl@17686
   736
                if ("js".equals(fo.getExt())) {
ppisl@17686
   737
                    count++;
ppisl@17686
   738
                    Source source = Source.create(fo);
ppisl@17686
   739
                    Snapshot snapshot = source.createSnapshot();
ppisl@17686
   740
                    nTime = nTime + parseNashronPerformance(snapshot);
ppisl@17686
   741
//                    rTime = rTime + parseRhinoPerformance(snapshot);
ppisl@17686
   742
                }
ppisl@17686
   743
            }
ppisl@17686
   744
            System.out.println("Parsed " + count + " .js files:");
ppisl@17686
   745
            System.out.println("Nashorn: " + nTime);
ppisl@17686
   746
//            System.out.println("Rhino: " + rTime);
ppisl@17686
   747
        }
ppisl@17686
   748
    }
ppisl@17686
   749
    
ppisl@17686
   750
    
ppisl@17686
   751
    protected long parseNashronPerformance(Snapshot snapshot) {
ppisl@17686
   752
        long start = System.currentTimeMillis();
ppisl@17686
   753
        com.oracle.nashorn.runtime.Source source = new com.oracle.nashorn.runtime.Source("test", snapshot.getText().toString());
ppisl@17686
   754
        start = System.currentTimeMillis();
ppisl@17733
   755
        com.oracle.nashorn.runtime.options.Options options = new com.oracle.nashorn.runtime.options.Options("nashorn");
ppisl@17686
   756
        options.process(new String[]{
ppisl@17686
   757
            "--parse-only=true", 
ppisl@17686
   758
            //"--print-parse=true",    
ppisl@17686
   759
            "--debug-lines=false",
ppisl@17686
   760
            "--print-symbols=true", 
ppisl@17686
   761
            "--dump-ir-graph=true", 
ppisl@17686
   762
            "--print-symbols=true"});
ppisl@17686
   763
ppisl@17686
   764
        com.oracle.nashorn.runtime.ErrorManager errors = new IdeErrorManager();
ppisl@17686
   765
        errors.setLimit(100);
ppisl@17686
   766
        com.oracle.nashorn.runtime.Context contextN = new com.oracle.nashorn.runtime.Context(options, errors);
ppisl@17686
   767
        com.oracle.nashorn.runtime.Context.setContext(contextN);
ppisl@17686
   768
ppisl@17686
   769
        com.oracle.nashorn.codegen.Compiler compiler = new com.oracle.nashorn.codegen.Compiler(source, contextN);
ppisl@17686
   770
        com.oracle.nashorn.parser.Parser parser = new com.oracle.nashorn.parser.Parser(compiler);
ppisl@17686
   771
        com.oracle.nashorn.ir.FunctionNode node = parser.parse(com.oracle.nashorn.codegen.CompilerConstants.runScriptName);
ppisl@17686
   772
ppisl@17686
   773
        long end = System.currentTimeMillis();
ppisl@17686
   774
        return end - start;
ppisl@17686
   775
    }
ppisl@17686
   776
    
ppisl@17686
   777
//    protected long parseRhinoPerformance(Snapshot snapshot) {
ppisl@17686
   778
//        long start = System.currentTimeMillis();
ppisl@17686
   779
//        JsParser jsParser  = new JsParser();
ppisl@17686
   780
//        JsParser.Context context = new JsParser.Context(snapshot, null);
ppisl@17686
   781
//        jsParser.parseBuffer(context, JsParser.Sanitize.NEVER);
ppisl@17686
   782
//        long end = System.currentTimeMillis();
ppisl@17686
   783
//        return end - start;
ppisl@17686
   784
//    }
ppisl@17686
   785
}