ada.editor/src/org/netbeans/modules/ada/editor/navigator/NavUtils.java
author Andrea Lucarelli <raster@netbeans.org>
Sun, 22 Aug 2010 23:37:11 +0200
branchrelease68
changeset 16367 d2820c029d3a
parent 15779 367c7fdb5d23
permissions -rw-r--r--
Add JVM compiler support.
raster@14539
     1
/*
raster@14539
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
raster@14539
     3
 *
raster@14539
     4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
raster@14539
     5
 *
raster@14539
     6
 * The contents of this file are subject to the terms of either the GNU
raster@14539
     7
 * General Public License Version 2 only ("GPL") or the Common
raster@14539
     8
 * Development and Distribution License("CDDL") (collectively, the
raster@14539
     9
 * "License"). You may not use this file except in compliance with the
raster@14539
    10
 * License. You can obtain a copy of the License at
raster@14539
    11
 * http://www.netbeans.org/cddl-gplv2.html
raster@14539
    12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
raster@14539
    13
 * specific language governing permissions and limitations under the
raster@14539
    14
 * License.  When distributing the software, include this License Header
raster@14539
    15
 * Notice in each file and include the License file at
raster@14539
    16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
raster@14539
    17
 * particular file as subject to the "Classpath" exception as provided
raster@14539
    18
 * by Sun in the GPL Version 2 section of the License file that
raster@14539
    19
 * accompanied this code. If applicable, add the following below the
raster@14539
    20
 * License Header, with the fields enclosed by brackets [] replaced by
raster@14539
    21
 * your own identifying information:
raster@14539
    22
 * "Portions Copyrighted [year] [name of copyright owner]"
raster@14539
    23
 *
raster@14539
    24
 * If you wish your version of this file to be governed by only the CDDL
raster@14539
    25
 * or only the GPL Version 2, indicate your decision by adding
raster@14539
    26
 * "[Contributor] elects to include this software in this distribution
raster@14539
    27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
raster@14539
    28
 * single choice of license, a recipient has the option to distribute
raster@14539
    29
 * your version of this file under either the CDDL, the GPL Version 2 or
raster@14539
    30
 * to extend the choice of license to its licensees as provided above.
raster@14539
    31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
raster@14539
    32
 * Version 2 license, then the option applies only if the new code is
raster@14539
    33
 * made subject to such option by the copyright holder.
raster@14539
    34
 *
raster@14539
    35
 * Contributor(s):
raster@14539
    36
 *
raster@14539
    37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
raster@14539
    38
 */
raster@14539
    39
package org.netbeans.modules.ada.editor.navigator;
raster@14539
    40
raster@14539
    41
import java.util.Collections;
raster@14539
    42
import java.util.LinkedList;
raster@14539
    43
import java.util.List;
raster@14539
    44
import java.util.Stack;
raster@14539
    45
import javax.swing.text.Document;
raster@14539
    46
import org.netbeans.modules.ada.editor.ast.ASTNode;
raster@14539
    47
import org.netbeans.modules.ada.editor.ast.ASTUtils;
raster@14695
    48
import org.netbeans.modules.ada.editor.ast.nodes.FormalParameter;
raster@14539
    49
import org.netbeans.modules.ada.editor.ast.nodes.PackageBody;
raster@15779
    50
import org.netbeans.modules.ada.editor.ast.nodes.PackageName;
raster@14539
    51
import org.netbeans.modules.ada.editor.ast.nodes.PackageSpecification;
raster@15779
    52
import org.netbeans.modules.ada.editor.ast.nodes.Scalar;
raster@15779
    53
import org.netbeans.modules.ada.editor.ast.nodes.SubprogramBody;
raster@15779
    54
import org.netbeans.modules.ada.editor.ast.nodes.SubprogramSpecification;
raster@15779
    55
import org.netbeans.modules.ada.editor.ast.nodes.TypeDeclaration;
raster@16367
    56
import org.netbeans.modules.ada.editor.ast.nodes.TypeName;
raster@14539
    57
import org.netbeans.modules.ada.editor.ast.nodes.Variable;
raster@14539
    58
import org.netbeans.modules.ada.editor.ast.nodes.With;
raster@14539
    59
import org.netbeans.modules.ada.editor.ast.nodes.visitors.DefaultVisitor;
raster@14539
    60
import org.netbeans.modules.ada.editor.navigator.SemiAttribute.AttributedElement;
raster@15779
    61
import org.netbeans.modules.csl.spi.ParserResult;
raster@14539
    62
import org.openide.filesystems.FileObject;
raster@14539
    63
import org.openide.loaders.DataObject;
raster@14539
    64
raster@14539
    65
/**
raster@15779
    66
 * Based on org.netbeans.modules.php.editor.nav.NavUtils
raster@14539
    67
 *
raster@15779
    68
 * @author Andrea Lucarelli
raster@14539
    69
 */
raster@14539
    70
public class NavUtils {
raster@14539
    71
raster@15779
    72
    public static List<ASTNode> underCaret(ParserResult info, final int offset) {
raster@14539
    73
        class Result extends Error {
raster@14539
    74
raster@14539
    75
            private Stack<ASTNode> result;
raster@14539
    76
raster@14539
    77
            public Result(Stack<ASTNode> result) {
raster@14539
    78
                this.result = result;
raster@14539
    79
            }
raster@14539
    80
raster@14539
    81
            @Override
raster@14539
    82
            public Throwable fillInStackTrace() {
raster@14539
    83
                return this;
raster@14539
    84
            }
raster@14539
    85
        }
raster@14539
    86
        try {
raster@14539
    87
            new DefaultVisitor() {
raster@14539
    88
raster@14539
    89
                private Stack<ASTNode> s = new Stack<ASTNode>();
raster@14539
    90
raster@14539
    91
                @Override
raster@14539
    92
                public void scan(ASTNode node) {
raster@14539
    93
                    if (node == null) {
raster@14539
    94
                        return;
raster@14539
    95
                    }
raster@14539
    96
raster@14539
    97
                    if (node.getStartOffset() <= offset && offset <= node.getEndOffset()) {
raster@14539
    98
                        s.push(node);
raster@14539
    99
                        super.scan(node);
raster@14539
   100
                        throw new Result(s);
raster@14539
   101
                    }
raster@14539
   102
                }
raster@14539
   103
            }.scan(ASTUtils.getRoot(info));
raster@14539
   104
        } catch (Result r) {
raster@14539
   105
            return new LinkedList<ASTNode>(r.result);
raster@14539
   106
        }
raster@14539
   107
raster@14539
   108
        return Collections.emptyList();
raster@14539
   109
    }
raster@14539
   110
raster@15779
   111
    public static AttributedElement findElement(ParserResult info, List<ASTNode> path, int offset, SemiAttribute a) {
raster@14539
   112
        if (path.size() == 0) {
raster@14539
   113
            return null;
raster@14539
   114
        }
raster@14539
   115
raster@14539
   116
        path = new LinkedList<ASTNode>(path);
raster@14539
   117
raster@14539
   118
        Collections.reverse(path);
raster@14539
   119
raster@14539
   120
        AttributedElement result = null;
raster@14539
   121
        ASTNode previous = null;
raster@14539
   122
raster@14539
   123
        for (ASTNode leaf : path) {
raster@14539
   124
raster@15779
   125
            if (leaf instanceof FormalParameter) {
raster@15779
   126
                FormalParameter param = (FormalParameter) leaf;
raster@15779
   127
                Variable name = param.getParameterName();
raster@15779
   128
                if (name != null && offset < name.getEndOffset()) {
raster@15779
   129
                    return a.getElement(name);
raster@15779
   130
                }
raster@15779
   131
            }
raster@15779
   132
            
raster@14539
   133
            if (leaf instanceof Variable) {
raster@14539
   134
                result = a.getElement(leaf);
raster@14539
   135
                previous = leaf;
raster@14539
   136
                continue;
raster@14539
   137
            }
raster@14539
   138
raster@15779
   139
            if (leaf instanceof TypeDeclaration) {
raster@15779
   140
                result = a.getElement(leaf);
raster@15779
   141
                previous = leaf;
raster@15779
   142
                continue;
raster@15779
   143
            }
raster@15779
   144
raster@16367
   145
            if (leaf instanceof TypeName) {
raster@16367
   146
                result = a.getElement(leaf);
raster@16367
   147
                previous = leaf;
raster@16367
   148
                continue;
raster@16367
   149
            }
raster@16367
   150
raster@15779
   151
            if (leaf instanceof Scalar) {
raster@15779
   152
                AttributedElement e = a.getElement(leaf);
raster@15779
   153
raster@15779
   154
                if (e != null) {
raster@15779
   155
                    return e;
raster@15779
   156
                }
raster@15779
   157
            }
raster@15779
   158
raster@15779
   159
            if (leaf instanceof SubprogramSpecification && ((SubprogramSpecification) leaf).getSubprogramName() == previous) {
raster@15779
   160
                return a.getElement(leaf);
raster@15779
   161
            }
raster@15779
   162
raster@15779
   163
            if (leaf instanceof SubprogramBody && ((SubprogramBody) leaf).getSubprogramSpecification().getSubprogramName() == previous) {
raster@15779
   164
                return a.getElement(leaf);
raster@15779
   165
            }
raster@15779
   166
raster@14539
   167
            if (leaf instanceof PackageSpecification) {
raster@14539
   168
                PackageSpecification cDeclaration = (PackageSpecification) leaf;
raster@16367
   169
                //package specification declaration
raster@14539
   170
                if (cDeclaration.getName() == previous) {
raster@14539
   171
                    return a.getElement(leaf);
raster@14539
   172
                }
raster@14539
   173
            } else if (leaf instanceof PackageBody) {
raster@14539
   174
                PackageBody iDeclaration = (PackageBody) leaf;
raster@16367
   175
                //package body declaration
raster@14539
   176
                if (iDeclaration.getName() == previous) {
raster@14539
   177
                    return a.getElement(leaf);
raster@14539
   178
                }
raster@14539
   179
            }
raster@14539
   180
raster@14539
   181
            if (result != null) {
raster@14539
   182
                return result;
raster@14539
   183
            }
raster@14539
   184
raster@14539
   185
            previous = leaf;
raster@14539
   186
        }
raster@14539
   187
raster@14539
   188
        return null;
raster@14539
   189
    }
raster@14539
   190
raster@14539
   191
    public static boolean isQuoted(String value) {
raster@14539
   192
        return value.length() >= 2 &&
raster@14539
   193
                (value.startsWith("\"") || value.startsWith("'")) &&
raster@14539
   194
                (value.endsWith("\"") || value.endsWith("'"));
raster@14539
   195
    }
raster@14539
   196
raster@14539
   197
    public static String dequote(String value) {
raster@14539
   198
        assert isQuoted(value);
raster@14539
   199
raster@14539
   200
        return value.substring(1, value.length() - 1);
raster@14539
   201
    }
raster@14539
   202
raster@15779
   203
    public static FileObject resolveInclude(ParserResult info, With with) {
raster@15779
   204
        List<PackageName> packages = with.getPackages();
raster@14627
   205
raster@14627
   206
        // TODO: resolve packagename with file
raster@14695
   207
raster@14627
   208
        return null;
raster@14627
   209
    }
raster@14627
   210
raster@14539
   211
    public static FileObject getFile(Document doc) {
raster@14539
   212
        Object o = doc.getProperty(Document.StreamDescriptionProperty);
raster@14539
   213
raster@14539
   214
        if (o instanceof DataObject) {
raster@14539
   215
            DataObject od = (DataObject) o;
raster@14539
   216
raster@14539
   217
            return od.getPrimaryFile();
raster@14539
   218
        }
raster@14539
   219
raster@14539
   220
        return null;
raster@14539
   221
    }
raster@14539
   222
}