/* * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.eclipse.quickfix.processors; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.eclipse.quickfix.proposals.GroovyQuickFixResolverRegistry; import org.codehaus.groovy.eclipse.quickfix.proposals.IQuickFixResolver; import org.codehaus.groovy.eclipse.quickfix.proposals.ProblemDescriptor; import org.codehaus.groovy.eclipse.quickfix.proposals.ProblemType; import org.codehaus.groovy.eclipse.quickfix.proposals.QuickFixProblemContext; import org.codehaus.jdt.groovy.model.GroovyNature; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.ui.text.java.IInvocationContext; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.IProblemLocation; import org.eclipse.jdt.ui.text.java.IQuickFixProcessor; /** * Integrates Groovy proposals into JDT quick fix framework. * * @author Nieraj Singh */ public class GroovyQuickFixProcessor implements IQuickFixProcessor { public boolean hasCorrections(ICompilationUnit unit, int problemId) { return isProblemInGroovyProject(unit) && ProblemType.isRecognizedProblemId(problemId); } public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IProblemLocation[] locations) throws CoreException { // The problem must be in a Groovy project. Otherwise do not handle it // as the proposals should not appear if the problem is in any other // type of project if (isProblemInGroovyProject(context, locations)) { QuickFixProblemContext problemContext = getQuickFixProblemContext(context, locations); if (problemContext != null) { List<IQuickFixResolver> resolvers = new GroovyQuickFixResolverRegistry(problemContext).getQuickFixResolvers(); if (resolvers != null) { List<IJavaCompletionProposal> proposals = new ArrayList<IJavaCompletionProposal>(); for (IQuickFixResolver resolver : resolvers) { List<IJavaCompletionProposal> foundProposals = resolver.getQuickFixProposals(); if (foundProposals != null) { proposals.addAll(foundProposals); } } return proposals.toArray(new IJavaCompletionProposal[proposals.size()]); } } } return new IJavaCompletionProposal[0]; // if (!(context instanceof IQuickAssistInvocationContext)) { // return new IJavaCompletionProposal[0]; // } // try { // IQuickAssistInvocationContext assistContext = (IQuickAssistInvocationContext) context; // TemplateStore codeTemplates = GroovyQuickFixPlugin.getDefault().getTemplateStore(); // List<IJavaCompletionProposal> templates = new ArrayList<IJavaCompletionProposal>(); // Region region = new Region(assistContext.getOffset(), assistContext.getLength()); // ContextTypeRegistry templateContextRegistry= GroovyQuickFixPlugin.getDefault().getTemplateContextRegistry(); // TemplateContextType contextType= templateContextRegistry.getContextType(GroovyQuickFixPlugin.GROOVY_CONTEXT_TYPE); // IDocument document = assistContext.getSourceViewer().getDocument(); // JavaContext templateContext = new GroovyContext(contextType, document, // region.getOffset(), region.getLength(), context.getCompilationUnit()); // // templateContext.setForceEvaluation(true); // templateContext.setVariable("selection", document.get(region.getOffset(), region.getLength())); // for (Template template : codeTemplates.getTemplates()) { // templates.add(new TemplateProposal(template, templateContext, region, null)); // } // return templates.toArray(new IJavaCompletionProposal[0]); // } catch (BadLocationException e) { // GroovyQuickFixPlugin.log(e); // return new IJavaCompletionProposal[0]; // } } /** * Generates a representation of the Java problem context that the Groovy * quick fix framework will understand. * * @param context * Java context containing information about the problem * @param locations * where the problem occurs * @return model representing the Java problem context */ protected QuickFixProblemContext getQuickFixProblemContext(IInvocationContext context, IProblemLocation[] locations) { if (context == null || locations == null || locations.length == 0) { return null; } // FIX: for now return the first location. Add support to // return multiple locations if necessary IProblemLocation location = locations[0]; ProblemDescriptor descriptor = getProblemDescriptor( location.getProblemId(), location.getMarkerType(), location.getProblemArguments()); if (descriptor != null) { return new QuickFixProblemContext(descriptor, context, location); } return null; } /** not API. Public for testing purposes */ public ProblemDescriptor getProblemDescriptor(int problemID, String markerDescription, String[] messages) { ProblemType type = ProblemType.getProblemType(problemID, markerDescription, messages); if (type != null) { return new ProblemDescriptor(type, messages); } return null; } /** * True if the problem is contained in an accessible (open and existing) * Groovy project in the workspace. False otherwise. * * @param context * containing Java/Groovy problem information * @param locations * of the Java/Groovy problem * @return true if and only if the problem is contained in an accessible * Groovy project. False otherwise */ protected boolean isProblemInGroovyProject(IInvocationContext context, IProblemLocation[] locations) { if (context != null && locations != null && locations.length > 0) { return isProblemInGroovyProject(context.getCompilationUnit()); } return false; } /** * True if the problem is contained in an accessible (open and existing) * Groovy project in the workspace. False otherwise. * * @param unit * compilation unit containing the resource with the problem * @return true if and only if the problem is contained in an accessible * Groovy project. False otherwise */ protected boolean isProblemInGroovyProject(ICompilationUnit unit) { if (unit != null) { IResource resource = unit.getResource(); if (resource != null) { IProject project = resource.getProject(); if (project != null && project.isAccessible() && GroovyNature.hasGroovyNature(project)) { return true; } } } return false; } }