⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pycodecompletion.java

📁 Python Development Environment (Python IDE plugin for Eclipse). Features editor, code completion, re
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Created on Aug 11, 2004
 *
 * @author Fabio Zadrozny
 */
package org.python.pydev.editor.codecompletion;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.FullRepIterable;
import org.python.pydev.core.ICallback;
import org.python.pydev.core.ICodeCompletionASTManager;
import org.python.pydev.core.ICompletionState;
import org.python.pydev.core.ILocalScope;
import org.python.pydev.core.IModule;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.IToken;
import org.python.pydev.core.ICodeCompletionASTManager.ImportInfo;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.log.Log;
import org.python.pydev.core.structure.CompletionRecursionException;
import org.python.pydev.editor.codecompletion.revisited.ASTManager;
import org.python.pydev.editor.codecompletion.revisited.AssignAnalysis;
import org.python.pydev.editor.codecompletion.revisited.CompletionState;
import org.python.pydev.editor.codecompletion.revisited.modules.AbstractModule;
import org.python.pydev.editor.codecompletion.revisited.modules.CompiledModule;
import org.python.pydev.editor.codecompletion.revisited.visitors.FindScopeVisitor;
import org.python.pydev.editor.codecompletion.shell.AbstractShell;
import org.python.pydev.parser.PyParser;
import org.python.pydev.parser.jython.SimpleNode;
import org.python.pydev.parser.jython.ast.ClassDef;
import org.python.pydev.parser.jython.ast.Name;
import org.python.pydev.parser.jython.ast.NameTok;
import org.python.pydev.parser.visitors.NodeUtils;

/**
 * @author Dmoore
 * @author Fabio Zadrozny
 */
public class PyCodeCompletion extends AbstractPyCodeCompletion {

    
    /**
     * This constant is used to debug the code-completion process on a production environment,
     * so that we gather enough information about what's happening and the possible reasons
     * for some bug (at this moment this is being specifically added because of a halting bug
     * for pydev in linux: https://sourceforge.net/tracker/index.php?func=detail&aid=1509582&group_id=85796&atid=577329)
     * 
     * It is kept updated from the Preferences Page
     */
    public static volatile boolean DEBUG_CODE_COMPLETION = PyCodeCompletionPreferencesPage.isToDebugCodeCompletion();
    
    /**
     * Called when a recursion exception is detected.
     */
    public static ICallback<Object, CompletionRecursionException> onCompletionRecursionException;
    
    /* (non-Javadoc)
     * @see org.python.pydev.editor.codecompletion.IPyCodeCompletion#getCodeCompletionProposals(org.eclipse.jface.text.ITextViewer, org.python.pydev.editor.codecompletion.CompletionRequest)
     */
    public List getCodeCompletionProposals(ITextViewer viewer, CompletionRequest request) throws CoreException, BadLocationException {
    	if(request.getPySelection().getCursorLineContents().trim().startsWith("#")){
    		//this may happen if the context is still not correctly computed in python
    		return new PyStringCodeCompletion().getCodeCompletionProposals(viewer, request);
    	}
        if(DEBUG_CODE_COMPLETION){
            Log.toLogFile(this,"Starting getCodeCompletionProposals");
            Log.addLogLevel();
            Log.toLogFile(this,"Request:"+request);
        }
        
        ArrayList<ICompletionProposal> ret = new ArrayList<ICompletionProposal>();
        
        //let's see if we should do a code-completion in the current scope...
        if(!isValidCompletionContext(request)){
            request.showTemplates = false;
            return ret;
        }
        
        try {
            IPythonNature pythonNature = request.nature;
            checkPythonNature(pythonNature);
            
            ICodeCompletionASTManager astManager = pythonNature.getAstManager();
            if (astManager == null) { 
                //we're probably still loading it.
                return ret;
            }
            
            //list of Object[], IToken or ICompletionProposal
            List<Object> tokensList = new ArrayList<Object>();
            lazyStartShell(request);

            String trimmed = request.activationToken.replace('.', ' ').trim();

            ImportInfo importsTipper = getImportsTipperStr(request);

            int line = request.doc.getLineOfOffset(request.documentOffset);
            IRegion region = request.doc.getLineInformation(line);

            ICompletionState state = new CompletionState(line, request.documentOffset - region.getOffset(), null, request.nature, request.qualifier);
            state.setIsInCalltip(request.isInCalltip);

            boolean importsTip = false;
            
            if (importsTipper.importsTipperStr.length() != 0) {
                //code completion in imports 
                request.isInCalltip = false; //if found after (, but in an import, it is not a calltip!
                importsTip = doImportCompletion(request, astManager, tokensList, importsTipper);

            } else if (trimmed.length() > 0 && request.activationToken.indexOf('.') != -1) {
                //code completion for a token
                doTokenCompletion(request, astManager, tokensList, trimmed, state);

            } else { 
                //go to globals
                doGlobalsCompletion(request, astManager, tokensList, state);
            }

            Map<String, IToken> alreadyChecked = new HashMap<String, IToken>();
            
            String lowerCaseQual = request.qualifier.toLowerCase();
            if(lowerCaseQual.length() >= PyCodeCompletionPreferencesPage.getArgumentsDeepAnalysisNChars()){
                //this can take some time on the analysis, so, let's let the user choose on how many chars does he
                //want to do the analysis...
                state.pushFindResolveImportMemoryCtx();
                try{
                    for(ListIterator it=tokensList.listIterator(); it.hasNext();){
                        Object o = it.next();
                        if(o instanceof IToken){
                            it.remove(); // always remove the tokens from the list (they'll be re-added later once they are filtered)
                            
                            IToken initialToken = (IToken) o;
                            
                            IToken token = initialToken;
                            String strRep = token.getRepresentation();
                            IToken prev = alreadyChecked.get(strRep);
                            
                            if(prev != null){
                                if(prev.getArgs().length() != 0){
                                    continue; // we already have a version with args... just keep going
                                }
                            }
                            
                            if(!strRep.toLowerCase().startsWith(lowerCaseQual)){
                                //just re-add it if we're going to actually use it (depending on the qualifier)
                                continue;
                            }
                            
                            while(token.isImportFrom()){
                                //we'll only add it here if it is an import from (so, set the flag to false for the outer add)
                                
                                if(token.getArgs().length() > 0){
                                    //if we already have the args, there's also no reason to do it (that's what we'll do here)
                                    break;
                                }
                                ICompletionState s = state.getCopyForResolveImportWithActTok(token.getRepresentation());
                                s.checkFindResolveImportMemory(token);
                                
                                IToken token2 = astManager.resolveImport(s, token);
                                if(token2 != null && initialToken != token2){
                                    String args = token2.getArgs();
                                    if(args.length() > 0){
                                        //put it into the map (may override previous if it didn't have args)
                                        initialToken.setArgs(args);
                                        initialToken.setDocStr(token2.getDocStr());
                                        break;
                                    }
                                    if(token2 == null || 
                                    	   (token2.equals(token) && 
                                    		token2.getArgs().equals(token.getArgs()) && 
                                    		token2.getParentPackage().equals(token.getParentPackage()))){
                                    	
                                    	token2.equals(token);
                                    	break;
                                    }
                                    token = token2;
                                }else{
                                    break;
                                }
                            }
                            
                            alreadyChecked.put(strRep, initialToken);
                        }
                    }
    
                }finally{
                    state.popFindResolveImportMemoryCtx();
                }
            }
            
            tokensList.addAll(alreadyChecked.values());
            changeItokenToCompletionPropostal(viewer, request, ret, tokensList, importsTip, state);
        } catch (CompletionRecursionException e) {
        	if(onCompletionRecursionException != null){
        		onCompletionRecursionException.call(e);
        	}
        	if(DEBUG_CODE_COMPLETION){
        		Log.toLogFile(e);
        	}
            //PydevPlugin.log(e);
            //ret.add(new CompletionProposal("",request.documentOffset,0,0,null,e.getMessage(), null,null));
        }
        
        if(DEBUG_CODE_COMPLETION){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -