/* * 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.refactoring.core.extract; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.Variable; import org.codehaus.groovy.ast.expr.VariableExpression; import org.codehaus.groovy.eclipse.codebrowsing.requestor.Region; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.groovy.search.ITypeRequestor; import org.eclipse.jdt.groovy.search.TypeLookupResult; import org.eclipse.jdt.groovy.search.VariableScope; import org.eclipse.jdt.internal.core.util.Util; /** * * @author andrew * @created May 18, 2010 */ public class InferParameterAndReturnTypesRequestor implements ITypeRequestor { private Map<Variable, ClassNode> inferredTypes; private final Region selectedText; public InferParameterAndReturnTypesRequestor(List<Variable> actualParameters, Set<Variable> returnParameters, Region selectedText) { inferredTypes = new HashMap<Variable, ClassNode>(); for (Variable variable : actualParameters) { inferredTypes.put(variable, null); } for (Variable variable : returnParameters) { inferredTypes.put(variable, null); } this.selectedText = selectedText; } public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaElement enclosingElement) { // check to see if the enclosing element does not enclose the // nodeToLookFor if (!interestingElement(enclosingElement)) { return VisitStatus.CANCEL_MEMBER; } if (node instanceof Variable) { if (inferredTypes.containsKey((Variable) node)) { inferredTypes.put((Variable) node, extractType(result)); } else if (node instanceof VariableExpression) { Variable accessedVar = ((VariableExpression) node).getAccessedVariable(); if (inferredTypes.containsKey(accessedVar)) { inferredTypes.put(accessedVar, extractType(result)); } } } return VisitStatus.CONTINUE; } private ClassNode extractType(TypeLookupResult result) { ClassNode type = result.type.getPlainNodeReference(); if (type.getName().equals(VariableScope.VOID_WRAPPER_CLASS_NODE.getName())) { type = VariableScope.OBJECT_CLASS_NODE; } return type; } public Map<Variable, ClassNode> getInferredTypes() { return inferredTypes; } /** * @param enclosingElement * @return true iff enclosingElement's source location contains the source * location of {@link #selectedText} */ private boolean interestingElement(IJavaElement enclosingElement) { // the clinit is always interesting since the clinit contains static // initializers if (enclosingElement.getElementName().equals("<clinit>")) { return true; } if (enclosingElement instanceof ISourceReference) { try { ISourceRange range = ((ISourceReference) enclosingElement).getSourceRange(); return range.getOffset() <= selectedText.getOffset() && range.getOffset() + range.getLength() >= selectedText.getEnd(); } catch (JavaModelException e) { Util.log(e); } } return false; } }