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

📄 pydevbuilder.java

📁 Python Development Environment (Python IDE plugin for Eclipse). Features editor, code completion, re
💻 JAVA
字号:
/*
 * Created on Oct 25, 2004
 *
 * @author Fabio Zadrozny
 */
package org.python.pydev.builder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.python.pydev.builder.pycremover.PycRemoverBuilderVisitor;
import org.python.pydev.builder.pylint.PyLintVisitor;
import org.python.pydev.builder.todo.PyTodoVisitor;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.IPythonPathNature;
import org.python.pydev.core.REF;
import org.python.pydev.editor.codecompletion.revisited.PyCodeCompletionVisitor;
import org.python.pydev.editor.codecompletion.revisited.PythonPathHelper;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.plugin.nature.PythonNature;

/**
 * This builder only passes through python files
 * 
 * @author Fabio Zadrozny
 */
public class PyDevBuilder extends IncrementalProjectBuilder {

    private static final boolean DEBUG = false;

	/**
     * 
     * @return a list of visitors for building the application.
     */
    @SuppressWarnings("unchecked")
    public List<PyDevBuilderVisitor> getVisitors() {
        List<PyDevBuilderVisitor> list = new ArrayList<PyDevBuilderVisitor>();
        list.add(new PyTodoVisitor());
        list.add(new PyLintVisitor());
        list.add(new PyCodeCompletionVisitor());
        list.add(new PycRemoverBuilderVisitor());

        list.addAll(ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_BUILDER));
        return list;
    }




    /**
     * Builds the project.
     * 
     * @see org.eclipse.core.internal.events InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
     */
    protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {

        if (PyDevBuilderPrefPage.usePydevBuilders() == false)
            return null;

        if (kind == IncrementalProjectBuilder.FULL_BUILD) {
            // Do a Full Build: Use a ResourceVisitor to process the tree.
            performFullBuild(monitor);

        } else {
            // Build it with a delta
            IResourceDelta delta = getDelta(getProject());

            if (delta == null) {
                //no delta (unspecified changes?... let's do a full build...)
                performFullBuild(monitor);
                
            } else {
                // ok, we have a delta
                // first step is just counting them
                PyDevDeltaCounter counterVisitor = new PyDevDeltaCounter();
                delta.accept(counterVisitor);
                
                List<PyDevBuilderVisitor> visitors = getVisitors();
                
                //sort by priority
                Collections.sort(visitors); 

                PydevGrouperVisitor grouperVisitor = new PydevGrouperVisitor(visitors, monitor, counterVisitor.getNVisited());
                notifyVisitingWillStart(visitors, monitor, false, null);
                delta.accept(grouperVisitor);
                notifyVisitingEnded(visitors, monitor);
                
            }
        }
        return null;
    }

    /**
     * Processes all python files.
     * 
     * @param monitor
     */
    private void performFullBuild(IProgressMonitor monitor) throws CoreException {
        IProject project = getProject();

        //we need the project...
        if (project != null) {
            IPythonNature nature = PythonNature.getPythonNature(project);
            
            //and the nature...
            if (nature != null && nature.startRequests()){
                
            	try{
            	    IPythonPathNature pythonPathNature = nature.getPythonPathNature();
            	    pythonPathNature.getProjectSourcePath(); //this is just to update the paths (in case the project name has just changed)
            	    
	                List<IFile> resourcesToParse = new ArrayList<IFile>();
	    
	                List<PyDevBuilderVisitor> visitors = getVisitors();
	                notifyVisitingWillStart(visitors, monitor, true, nature);
	    
	                monitor.beginTask("Building...", (visitors.size() * 100) + 30);
	    
	                IResource[] members = project.members();
	    
	                if (members != null) {
	                    // get all the python files to get information.
	                    for (int i = 0; i < members.length; i++) {
	                        try {
	                            IResource member = members[i];
	                            if (member == null) {
	                                continue;
	                            }
	    
	                            if (member.getType() == IResource.FILE) {
	                                addToResourcesToParse(resourcesToParse, (IFile)member, nature);
	                                
	                            } else if (member.getType() == IResource.FOLDER) {
	                                //if it is a folder, let's get all python files that are beneath it
	                                //the heuristics to know if we have to analyze them are the same we have
	                                //for a single file
	                                List<IFile> l = PydevPlugin.getAllIFilesBelow((IFolder) member);
	                                
	                                for (Iterator<IFile> iter = l.iterator(); iter.hasNext();) {
	                                    IFile element = iter.next();
	                                    if (element != null) {
	                                        addToResourcesToParse(resourcesToParse, element, nature);
	                                    }
	                                }
	                            } else {
	                            	if (DEBUG){
	                            		System.out.println("Unknown type: "+member.getType());
	                            	}
	                            }
	                        } catch (Exception e) {
	                            // that's ok...
	                        }
	                    }
	                    monitor.worked(30);
	                    buildResources(resourcesToParse, monitor, visitors);
	                }
	                notifyVisitingEnded(visitors, monitor);
            	}finally{
            		nature.endRequests();
            	}
            }
        }
        monitor.done();

    }

    private void notifyVisitingWillStart(List<PyDevBuilderVisitor> visitors, IProgressMonitor monitor, boolean isFullBuild, IPythonNature nature) {
        for (PyDevBuilderVisitor visitor : visitors) {
            visitor.visitingWillStart(monitor, isFullBuild, nature);
        }
    }

    private void notifyVisitingEnded(List<PyDevBuilderVisitor> visitors, IProgressMonitor monitor) {
        for (PyDevBuilderVisitor visitor : visitors) {
            visitor.visitingEnded(monitor);
        }
    }
    



    /**
     * @param resourcesToParse the list where the resource may be added
     * @param member the resource we are adding
     * @param nature the nature associated to the resource
     */
    private void addToResourcesToParse(List<IFile> resourcesToParse, IFile member, IPythonNature nature) {
        //analyze it only if it is a valid source file 
        String fileExtension = member.getFileExtension();
        if(DEBUG){
        	System.out.println("Checking name:'"+member.getName()+"' projPath:'"+member.getProjectRelativePath()+ "' ext:'"+fileExtension+"'");
        	System.out.println("loc:'"+member.getLocation()+"' rawLoc:'"+member.getRawLocation()+"'");
        	
        }
        if (fileExtension != null && PythonPathHelper.isValidSourceFile("."+fileExtension)) {
        	if(DEBUG){
        		System.out.println("Adding resource to parse:"+member.getProjectRelativePath());
        	}
            resourcesToParse.add(member);
        }
    }


    /**
     * Default implementation. Visits each resource once at a time. May be overriden if a better implementation is needed.
     * 
     * @param resourcesToParse list of resources from project that are python files.
     * @param monitor
     * @param visitors
     */
    public void buildResources(List<IFile> resourcesToParse, IProgressMonitor monitor, List visitors) {

        // we have 100 units here
        double inc = (visitors.size() * 100) / (double) resourcesToParse.size();

        double total = 0;
        int totalResources = resourcesToParse.size();
        int i = 0;

        for (Iterator<IFile> iter = resourcesToParse.iterator(); iter.hasNext() && monitor.isCanceled() == false;) {
            i += 1;
            total += inc;
            IFile r = iter.next();
            IPythonNature nature = PythonNature.getPythonNature(r);
            if (nature == null){
            	continue;
            }
            if(!nature.startRequests()){
            	continue;
            }
            try{
	            if(!nature.isResourceInPythonpath(r)){
	            	continue; // we only analyze resources that are in the pythonpath
	            }
	            IDocument doc = REF.getDocFromResource(r);
	            
	            HashMap<String, Object> memo = new HashMap<String, Object>();
	            memo.put(PyDevBuilderVisitor.IS_FULL_BUILD, true); //mark it as full build
	            
	            if(doc != null){ //might be out of synch
	                for (Iterator it = visitors.iterator(); it.hasNext() && monitor.isCanceled() == false;) {
	
	                    PyDevBuilderVisitor visitor = (PyDevBuilderVisitor) it.next();
	                    visitor.memo = memo; //setting the memo must be the first thing.
	    
	                    communicateProgress(monitor, totalResources, i, r, visitor);
	                    
	                    //on a full build, all visits are as some add...
	                    visitor.visitAddedResource(r, doc, monitor);
	                }
	    
	                if (total > 1) {
	                    monitor.worked((int) total);
	                    total -= (int) total;
	                }
	            }
            }finally{
            	nature.endRequests();
            }
        }
    }

    /**
     * Used so that we can communicate the progress to the user
     */
    public static void communicateProgress(IProgressMonitor monitor, int totalResources, int i, IResource r, PyDevBuilderVisitor visitor) {
        if(monitor != null){
            StringBuffer msgBuf = new StringBuffer();
            msgBuf.append("Pydev: Analyzing ");
            msgBuf.append(i);
            msgBuf.append(" of ");
            msgBuf.append(totalResources);
            msgBuf.append(" (");
            msgBuf.append(r.getName());
            msgBuf.append(")");
       
            //in this case the visitor does not have the progress and therefore does not communicate the progress
            String name = msgBuf.toString();
            monitor.subTask(name);
        }
    }

}

⌨️ 快捷键说明

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