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

📄 pycontextinformationvalidator.java

📁 Python Development Environment (Python IDE plugin for Eclipse). Features editor, code completion, re
💻 JAVA
字号:
/*
 * Created on Jul 1, 2006
 * @author Fabio
 */
package org.python.pydev.editor.codecompletion;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.python.pydev.core.docutils.ParsingUtils;
import org.python.pydev.plugin.PydevPlugin;

/**
 * Based on JavaParameterListValidator
 * 
 * @author Fabio
 */
public class PyContextInformationValidator implements IContextInformationValidator, IContextInformationPresenter{

    public PyCalltipsContextInformation fInformation;
    public int fPosition;
    public IDocument doc;
    public int fCurrentParameter;
    public boolean returnedFalseOnce;

    public PyContextInformationValidator() {
    }

    //--- interface from IContextInformationValidator
    public void install(IContextInformation info, IDocument doc, int offset) {
    	this.returnedFalseOnce = false;
        this.fInformation = (PyCalltipsContextInformation) info;
        this.doc = doc;
        
        this.fPosition =offset;
        fCurrentParameter= -1;
        //update the offset to the first parentesis
        while(offset > 0){
            try {
                char c = doc.getChar(offset);
                if(c == '('){
                    offset++;
                    break;
                }
                
                if(c == '\r' || c == '\n'){
                    return;
                }
            } catch (BadLocationException e) {
                //just ignore it -- and go with offset-1, as we did get a char > than the doc len
            }
            offset--;
        }
        if(offset != 0){
            this.fPosition =offset;
        }
    }
    
    public void install(IContextInformation info, ITextViewer viewer, int offset) {
        install(info, viewer.getDocument(), offset);
    }

    public int getCharCount(IDocument document, final int start, final int end, String increments, String decrements, boolean considerNesting) throws BadLocationException {

        Assert.isTrue((increments.length() != 0 || decrements.length() != 0) && !increments.equals(decrements));
        
        final int NONE= 0;
        final int BRACKET= 1;
        final int BRACE= 2;
        final int PAREN= 3;
        final int ANGLE= 4;

        int nestingMode= NONE;
        int nestingLevel= 0;

        int charCount= 0;
        int offset= start;
        while (offset < end) {
            char curr= document.getChar(offset++);
            switch (curr) {
                case '#':
                    if (offset < end) {
                        // '#' comment: nothing to do anymore on this line
                        offset= end;
                    }
                    break;
                case '"':
                case '\'':
                	int eaten = ParsingUtils.eatLiterals(document, new StringBuffer(), offset-1)+1;
                	if (eaten > offset){
                		offset= eaten;
                	}
                    break;
                case '[':
                    if (considerNesting) {
                        if (nestingMode == BRACKET || nestingMode == NONE) {
                            nestingMode= BRACKET;
                            nestingLevel++;
                        }
                        break;
                    }
                case ']':
                    if (considerNesting) {
                        if (nestingMode == BRACKET)
                            if (--nestingLevel == 0)
                                nestingMode= NONE;
                        break;
                    }
                case '(':
                    if (considerNesting) {
                        if (nestingMode == ANGLE) {
                            // generics heuristic failed
                            nestingMode=PAREN;
                            nestingLevel= 1;
                        }
                        if (nestingMode == PAREN || nestingMode == NONE) {
                            nestingMode= PAREN;
                            nestingLevel++;
                        }
                        break;
                    }
                case ')':
                    if (considerNesting) {
                        if (nestingMode == PAREN)
                            if (--nestingLevel == 0)
                                nestingMode= NONE;
                        break;
                    }
                case '{':
                    if (considerNesting) {
                        if (nestingMode == ANGLE) {
                            // generics heuristic failed
                            nestingMode=BRACE;
                            nestingLevel= 1;
                        }
                        if (nestingMode == BRACE || nestingMode == NONE) {
                            nestingMode= BRACE;
                            nestingLevel++;
                        }
                        break;
                    }
                case '}':
                    if (considerNesting) {
                        if (nestingMode == BRACE)
                            if (--nestingLevel == 0)
                                nestingMode= NONE;
                        break;
                    }

                default:
                    if (nestingLevel != 0)
                        continue;

                    if (increments.indexOf(curr) >= 0) {
                        ++ charCount;
                    }

                    if (decrements.indexOf(curr) >= 0) {
                        -- charCount;
                    }
            }
        }

        return charCount;
    }


    /**
     * @see IContextInformationValidator#isContextInformationValid(int)
     */
    public boolean isContextInformationValid(int position) {
    	//System.out.println("isContextInformationValid:"+position);
    	if(doc == null){
    		this.returnedFalseOnce = true;
    		return false;
    	}

        try {
            if (position < fPosition){
            	this.returnedFalseOnce = true;
                return false;
            }

            IDocument document= doc;
            IRegion line= document.getLineInformationOfOffset(fPosition);

            if (position < line.getOffset() || position >= document.getLength()){
            	this.returnedFalseOnce = true;
                return false;
            }

            boolean ret = getCharCount(document, fPosition, position, "(", ")", false) >= 0; //$NON-NLS-1$ //$NON-NLS-2$
            if(ret == false){
            	returnedFalseOnce = true;
            }
            return ret;

        } catch (BadLocationException x) {
        	this.returnedFalseOnce = true;
            return false;
        } catch (Exception x) {
        	this.returnedFalseOnce = true;
        	PydevPlugin.log(x);
        	return false;
        }
    }

    //--- interface from IContextInformationPresenter

    /**
     * @see IContextInformationPresenter#updatePresentation(int, TextPresentation)
     */
    public boolean updatePresentation(int position, TextPresentation presentation) {

        int currentParameter= -1;

        try {
            currentParameter= getCharCount(doc, fPosition, position, ",", "", true); 
        } catch (BadLocationException x) {
            return false;
        }

        if (fCurrentParameter != -1) {
            if (currentParameter == fCurrentParameter)
                return false;
        }

        presentation.clear();
        fCurrentParameter= currentParameter;

        String s= fInformation.getInformationDisplayString();
        int[] commas= computeCommaPositions(s);

        if (commas.length - 2 < fCurrentParameter) {
            presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL));
            return true;
        }
        
        int start= commas[fCurrentParameter] + 1;
        int end= commas[fCurrentParameter + 1];
        if (start > 0){
            presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL));
        }

        if (end > start){
            presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD));
        }

        if (end < s.length()){
            presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL));
        }

        return true;
    }
    
    private int[] computeCommaPositions(String code) {
        final int length= code.length();
        int pos= 0;
        List<Integer> positions= new ArrayList<Integer>();
        positions.add(new Integer(-1));
        while (pos < length && pos != -1) {
            char ch= code.charAt(pos);
            switch (ch) {
                case ',':
                    positions.add(new Integer(pos));
                    break;
                default:
                    break;
            }
            if (pos != -1)
                pos++;
        }
        positions.add(new Integer(length));
        
        int[] fields= new int[positions.size()];
        for (int i= 0; i < fields.length; i++){
            fields[i]= ((Integer) positions.get(i)).intValue();
        }
        return fields;
    }

}

⌨️ 快捷键说明

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