context free completion
authorMarek Fukala <mfukala@netbeans.org>
Tue, 15 Jan 2013 12:30:44 +0100
changeset 179331d4753c844aa
parent 17932 3d72cd56ee0e
child 17934 da3589bc745b
context free completion
o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrCompletionHandler.java
o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrCslLanguage.java
o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrElementHandle.java
o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/NbAntlrParserResult.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrCompletionHandler.java	Tue Jan 15 12:30:44 2013 +0100
     1.3 @@ -0,0 +1,171 @@
     1.4 +/*
     1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 + *
     1.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
     1.8 + *
     1.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    1.10 + * Other names may be trademarks of their respective owners.
    1.11 + *
    1.12 + * The contents of this file are subject to the terms of either the GNU
    1.13 + * General Public License Version 2 only ("GPL") or the Common
    1.14 + * Development and Distribution License("CDDL") (collectively, the
    1.15 + * "License"). You may not use this file except in compliance with the
    1.16 + * License. You can obtain a copy of the License at
    1.17 + * http://www.netbeans.org/cddl-gplv2.html
    1.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    1.19 + * specific language governing permissions and limitations under the
    1.20 + * License.  When distributing the software, include this License Header
    1.21 + * Notice in each file and include the License file at
    1.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    1.23 + * particular file as subject to the "Classpath" exception as provided
    1.24 + * by Oracle in the GPL Version 2 section of the License file that
    1.25 + * accompanied this code. If applicable, add the following below the
    1.26 + * License Header, with the fields enclosed by brackets [] replaced by
    1.27 + * your own identifying information:
    1.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    1.29 + *
    1.30 + * If you wish your version of this file to be governed by only the CDDL
    1.31 + * or only the GPL Version 2, indicate your decision by adding
    1.32 + * "[Contributor] elects to include this software in this distribution
    1.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    1.34 + * single choice of license, a recipient has the option to distribute
    1.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    1.36 + * to extend the choice of license to its licensees as provided above.
    1.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    1.38 + * Version 2 license, then the option applies only if the new code is
    1.39 + * made subject to such option by the copyright holder.
    1.40 + *
    1.41 + * Contributor(s):
    1.42 + *
    1.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
    1.44 + */
    1.45 +package org.netbeans.modules.antlr.editor;
    1.46 +
    1.47 +import java.util.ArrayList;
    1.48 +import java.util.Collections;
    1.49 +import java.util.List;
    1.50 +import java.util.Map;
    1.51 +import java.util.Set;
    1.52 +import javax.swing.ImageIcon;
    1.53 +import javax.swing.text.Document;
    1.54 +import javax.swing.text.JTextComponent;
    1.55 +import org.netbeans.api.lexer.Token;
    1.56 +import org.netbeans.api.lexer.TokenHierarchy;
    1.57 +import org.netbeans.api.lexer.TokenSequence;
    1.58 +import org.netbeans.modules.csl.api.CodeCompletionContext;
    1.59 +import org.netbeans.modules.csl.api.CodeCompletionHandler;
    1.60 +import org.netbeans.modules.csl.api.CodeCompletionResult;
    1.61 +import org.netbeans.modules.csl.api.CompletionProposal;
    1.62 +import org.netbeans.modules.csl.api.ElementHandle;
    1.63 +import org.netbeans.modules.csl.api.ElementKind;
    1.64 +import org.netbeans.modules.csl.api.HtmlFormatter;
    1.65 +import org.netbeans.modules.csl.api.Modifier;
    1.66 +import org.netbeans.modules.csl.api.OffsetRange;
    1.67 +import org.netbeans.modules.csl.api.ParameterInfo;
    1.68 +import org.netbeans.modules.csl.spi.DefaultCompletionProposal;
    1.69 +import org.netbeans.modules.csl.spi.DefaultCompletionResult;
    1.70 +import org.netbeans.modules.csl.spi.ParserResult;
    1.71 +import org.openide.filesystems.FileObject;
    1.72 +
    1.73 +/**
    1.74 + *
    1.75 + * @author marekfukala
    1.76 + */
    1.77 +public class AntlrCompletionHandler implements CodeCompletionHandler {
    1.78 +
    1.79 +    @Override
    1.80 +    public CodeCompletionResult complete(final CodeCompletionContext context) {
    1.81 +        List<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
    1.82 +        NbAntlrParserResult result = (NbAntlrParserResult) context.getParserResult();
    1.83 +        final FileObject fileObject = result.getSnapshot().getSource().getFileObject();
    1.84 +        for(final String ruleName : result.getRuleNames()) {
    1.85 +            if(ruleName.toLowerCase().startsWith(context.getPrefix().toLowerCase())) {
    1.86 +                final AntlrElementHandle handle = new AntlrElementHandle(fileObject, ruleName, OffsetRange.NONE);
    1.87 +                proposals.add(new DefaultCompletionProposal() {
    1.88 +
    1.89 +                    @Override
    1.90 +                    public int getAnchorOffset() {
    1.91 +                        return context.getCaretOffset() - context.getPrefix().length();
    1.92 +                    }
    1.93 +
    1.94 +                    @Override
    1.95 +                    public String getName() {
    1.96 +                        return ruleName;
    1.97 +                    }
    1.98 +
    1.99 +                    @Override
   1.100 +                    public ElementKind getKind() {
   1.101 +                        return handle.getKind();
   1.102 +                    }
   1.103 +                    
   1.104 +                    @Override
   1.105 +                    public ElementHandle getElement() {
   1.106 +                        return handle;
   1.107 +                    }
   1.108 +                });
   1.109 +            }
   1.110 +        }
   1.111 +        
   1.112 +        
   1.113 +        return new DefaultCompletionResult(proposals, false);
   1.114 +    }
   1.115 +
   1.116 +    @Override
   1.117 +    public String getPrefix(ParserResult info, int caretOffset, boolean upToOffset) {
   1.118 +        NbAntlrParserResult result = (NbAntlrParserResult) info;
   1.119 +        TokenHierarchy<?> th = result.getSnapshot().getTokenHierarchy();
   1.120 +        TokenSequence<AntlrTokenId> ts = th.tokenSequence(AntlrTokenId.language());
   1.121 +        int diff = ts.move(caretOffset);
   1.122 +        if (diff == 0) {
   1.123 +            if (!ts.movePrevious()) {
   1.124 +                return null;
   1.125 +            }
   1.126 +        } else {
   1.127 +            if (!ts.moveNext()) {
   1.128 +                return null;
   1.129 +            }
   1.130 +        }
   1.131 +        Token<AntlrTokenId> curr = ts.token();
   1.132 +        switch(curr.id()) {
   1.133 +            case RULE_REF:
   1.134 +            case TOKEN_REF:
   1.135 +                return diff == 0 
   1.136 +                        ? curr.text().toString() 
   1.137 +                        : ts.token().text().toString().substring(0, diff);
   1.138 +        }
   1.139 +        
   1.140 +        return "";
   1.141 +    }
   1.142 +
   1.143 +    @Override
   1.144 +    public String document(ParserResult info, ElementHandle element) {
   1.145 +        return null;
   1.146 +    }
   1.147 +
   1.148 +    @Override
   1.149 +    public ElementHandle resolveLink(String link, ElementHandle originalHandle) {
   1.150 +        return null;
   1.151 +    }
   1.152 +
   1.153 +    @Override
   1.154 +    public QueryType getAutoQuery(JTextComponent component, String typedText) {
   1.155 +        return QueryType.NONE;
   1.156 +    }
   1.157 +
   1.158 +    @Override
   1.159 +    public String resolveTemplateVariable(String variable, ParserResult info, int caretOffset, String name, Map parameters) {
   1.160 +        return null;
   1.161 +    }
   1.162 +
   1.163 +    @Override
   1.164 +    public Set<String> getApplicableTemplates(Document doc, int selectionBegin, int selectionEnd) {
   1.165 +        return Collections.emptySet();
   1.166 +    }
   1.167 +
   1.168 +    @Override
   1.169 +    public ParameterInfo parameters(ParserResult info, int caretOffset, CompletionProposal proposal) {
   1.170 +        return ParameterInfo.NONE;
   1.171 +    }
   1.172 +    
   1.173 +    
   1.174 +}
     2.1 --- a/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrCslLanguage.java	Tue Jan 15 11:45:41 2013 +0100
     2.2 +++ b/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrCslLanguage.java	Tue Jan 15 12:30:44 2013 +0100
     2.3 @@ -43,6 +43,7 @@
     2.4  
     2.5  import org.netbeans.core.spi.multiview.MultiViewElement;
     2.6  import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
     2.7 +import org.netbeans.modules.csl.api.CodeCompletionHandler;
     2.8  import org.netbeans.modules.csl.api.DeclarationFinder;
     2.9  import org.netbeans.modules.csl.api.OccurrencesFinder;
    2.10  import org.netbeans.modules.csl.api.SemanticAnalyzer;
    2.11 @@ -128,5 +129,17 @@
    2.12      public DeclarationFinder getDeclarationFinder() {
    2.13          return new AntlrDeclarationFinder();
    2.14      }
    2.15 +
    2.16 +    @Override
    2.17 +    public String getLineCommentPrefix() {
    2.18 +        return "//"; //NOI18N
    2.19 +    }
    2.20 +
    2.21 +    @Override
    2.22 +    public CodeCompletionHandler getCompletionHandler() {
    2.23 +        return new AntlrCompletionHandler();
    2.24 +    }
    2.25 +    
    2.26 +    
    2.27      
    2.28  }
     3.1 --- a/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrElementHandle.java	Tue Jan 15 11:45:41 2013 +0100
     3.2 +++ b/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/AntlrElementHandle.java	Tue Jan 15 12:30:44 2013 +0100
     3.3 @@ -59,7 +59,7 @@
     3.4      private FileObject file;
     3.5      private CharSequence name;
     3.6      private OffsetRange range;
     3.7 -
     3.8 +    
     3.9      public AntlrElementHandle(FileObject file, CharSequence name, OffsetRange range) {
    3.10          this.file = file;
    3.11          this.name = name;
    3.12 @@ -88,7 +88,7 @@
    3.13  
    3.14      @Override
    3.15      public ElementKind getKind() {
    3.16 -        return ElementKind.RULE;
    3.17 +        return Character.isUpperCase(getName().charAt(0)) ? ElementKind.FIELD : ElementKind.METHOD; //XXX fix the gr.rule vs token ref recognition !!!
    3.18      }
    3.19  
    3.20      @Override
     4.1 --- a/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/NbAntlrParserResult.java	Tue Jan 15 11:45:41 2013 +0100
     4.2 +++ b/o.n.antlr.editor/src/org/netbeans/modules/antlr/editor/NbAntlrParserResult.java	Tue Jan 15 12:30:44 2013 +0100
     4.3 @@ -41,10 +41,17 @@
     4.4   */
     4.5  package org.netbeans.modules.antlr.editor;
     4.6  
     4.7 +import java.util.ArrayList;
     4.8  import java.util.Collections;
     4.9  import java.util.List;
    4.10 +import org.antlr.runtime.CommonToken;
    4.11  import org.antlr.runtime.tree.CommonTree;
    4.12 +import org.antlr.runtime.tree.TreeVisitor;
    4.13 +import org.antlr.runtime.tree.TreeVisitorAction;
    4.14 +import org.netbeans.modules.antlr.editor.gen.ANTLRv3Parser;
    4.15 +import org.netbeans.modules.csl.api.ColoringAttributes;
    4.16  import org.netbeans.modules.csl.api.Error;
    4.17 +import org.netbeans.modules.csl.api.OffsetRange;
    4.18  import org.netbeans.modules.csl.spi.ParserResult;
    4.19  import org.netbeans.modules.parsing.api.Snapshot;
    4.20  
    4.21 @@ -55,9 +62,9 @@
    4.22  public class NbAntlrParserResult extends ParserResult {
    4.23  
    4.24      public static boolean IN_UNIT_TESTS = false;
    4.25 -    
    4.26      private CommonTree parseTree;
    4.27 -    
    4.28 +    private List<String> ruleNames;
    4.29 +
    4.30      public NbAntlrParserResult(Snapshot snapshot, CommonTree parseTree /*, List<ProblemDescription> diagnostics*/) {
    4.31          super(snapshot);
    4.32          assert parseTree != null;
    4.33 @@ -74,12 +81,46 @@
    4.34      }
    4.35  
    4.36      public CommonTree getParseTree() {
    4.37 -        if(parseTree == null) {
    4.38 +        if (parseTree == null) {
    4.39              throw new IllegalStateException("Already invalidated parser result, you are likely trying to use it outside of the parsing task runnable!"); //NOI18N
    4.40          }
    4.41          return parseTree;
    4.42      }
    4.43 -    
    4.44 +
    4.45 +    public List<String> getRuleNames() {
    4.46 +        if (ruleNames == null) {
    4.47 +            ruleNames = new ArrayList<String>();
    4.48 +
    4.49 +            TreeVisitor visitor = new TreeVisitor();
    4.50 +            visitor.visit(getParseTree(), new TreeVisitorAction() {
    4.51 +                @Override
    4.52 +                public Object pre(Object o) {
    4.53 +                    CommonTree t = (CommonTree) o;
    4.54 +                    switch (t.getType()) {
    4.55 +                        case ANTLRv3Parser.RULE:
    4.56 +                            //get next ID rule
    4.57 +                            CommonTree id = (CommonTree) t.getChild(0);
    4.58 +                            assert id.getType() == ANTLRv3Parser.ID;
    4.59 +
    4.60 +                            CommonToken ct = (CommonToken) id.getToken();
    4.61 +                            ruleNames.add(ct.getText());
    4.62 +                            break;
    4.63 +                    }
    4.64 +                    return t;
    4.65 +                }
    4.66 +
    4.67 +                @Override
    4.68 +                public Object post(Object o) {
    4.69 +                    CommonTree t = (CommonTree) o;
    4.70 +                    return t;
    4.71 +                }
    4.72 +            });
    4.73 +
    4.74 +
    4.75 +        }
    4.76 +        return ruleNames;
    4.77 +    }
    4.78 +
    4.79  //    /**
    4.80  //     * Gets lexer / parser diagnostics w/o additional issues 
    4.81  //     * possibly added by {@link ExtendedDiagnosticsProvider}.
    4.82 @@ -87,13 +128,11 @@
    4.83  //    public List<ProblemDescription> getParserDiagnostics() {
    4.84  //        return diagnostics;
    4.85  //    }
    4.86 -
    4.87      @Override
    4.88      public List<? extends Error> getDiagnostics() {
    4.89  //        return ErrorsProviderQuery.getExtendedDiagnostics(this);
    4.90          return Collections.emptyList();
    4.91      }
    4.92 -    
    4.93  //    public <T> T getProperty(Class<T> type) {
    4.94  //        if(properties == null) {
    4.95  //            return null;
    4.96 @@ -108,5 +147,4 @@
    4.97  //        }
    4.98  //        properties.put(type, value);
    4.99  //    }
   4.100 -    
   4.101  }