blob: 7ca042426001c64d5fc48ccaa8d26d7b74702752 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 Angelo Zerr and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* - Angelo Zerr: initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor.codemining;
import java.util.List;
import org.eclipse.jface.text.codemining.ICodeMining;
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
import org.eclipse.jdt.internal.ui.JavaPlugin;
public class CalleeJavaMethodParameterVisitor extends HierarchicalASTVisitor {
private final List<ICodeMining> minings;
private final ICodeMiningProvider provider;
public CalleeJavaMethodParameterVisitor(List<ICodeMining> minings, ICodeMiningProvider provider) {
this.minings= minings;
this.provider= provider;
}
@Override
public boolean visit(ConstructorInvocation constructorInvocation) {
List<?> arguments= constructorInvocation.arguments();
if (!arguments.isEmpty()) {
IMethodBinding constructorBinding= constructorInvocation.resolveConstructorBinding();
if (constructorBinding != null) {
IMethod method = resolveMethodBinding(constructorBinding);
collectParameterNamesCodeMinings(method, arguments, constructorBinding.isVarargs());
}
}
return super.visit(constructorInvocation);
}
@Override
public boolean visit(ClassInstanceCreation classInstanceCreation) {
List<?> arguments= classInstanceCreation.arguments();
if (!arguments.isEmpty()) {
IMethodBinding constructorBinding= classInstanceCreation.resolveConstructorBinding();
if (constructorBinding != null) {
IMethod method = resolveMethodBinding(constructorBinding);
collectParameterNamesCodeMinings(method, arguments, constructorBinding.isVarargs());
}
}
return super.visit(classInstanceCreation);
}
@Override
public boolean visit(SuperConstructorInvocation superConstructorInvocation) {
List<?> arguments= superConstructorInvocation.arguments();
if (!arguments.isEmpty()) {
IMethodBinding constructorBinding= superConstructorInvocation.resolveConstructorBinding();
if (constructorBinding != null) {
IMethod method = resolveMethodBinding(constructorBinding);
collectParameterNamesCodeMinings(method, arguments, constructorBinding.isVarargs());
}
}
return super.visit(superConstructorInvocation);
}
@Override
public boolean visit(EnumConstantDeclaration enumConstantDeclaration) {
List<?> arguments= enumConstantDeclaration.arguments();
if (!arguments.isEmpty()) {
IMethodBinding constructorBinding= enumConstantDeclaration.resolveConstructorBinding();
if (constructorBinding != null) {
IMethod method = resolveMethodBinding(constructorBinding);
collectParameterNamesCodeMinings(method, arguments, constructorBinding.isVarargs());
}
}
return super.visit(enumConstantDeclaration);
}
@Override
public boolean visit(MethodInvocation methodInvocation) {
List<?> arguments= methodInvocation.arguments();
if (!arguments.isEmpty()) {
IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
if (methodBinding != null) {
IMethod method = resolveMethodBinding(methodBinding);
collectParameterNamesCodeMinings(method, arguments, methodBinding.isVarargs());
}
}
return super.visit(methodInvocation);
}
protected void collectParameterNamesCodeMinings(IMethod method, List<?> arguments, boolean isVarargs) {
if (method != null) {
if (!skipParameterNamesCodeMinings(method)) {
try {
for (int i= 0; i < Math.min(arguments.size(), method.getParameterNames().length); i++) {
if (!skipParameterNameCodeMining(method, arguments, i)) {
minings.add(new JavaMethodParameterCodeMining((Expression)arguments.get(i), i, method, isVarargs, provider));
}
}
} catch (Exception e) {
JavaPlugin.log(e);
}
}
}
}
protected static IMethod resolveMethodBinding(IMethodBinding binding) {
if (binding == null) {
return null;
}
IJavaElement javaElement = binding.getJavaElement();
if (javaElement == null || !(javaElement instanceof IMethod)) {
return null;
}
return (IMethod)javaElement;
}
private boolean skipParameterNameCodeMining(IMethod method, List<?> arguments, int parameterIndex) {
if (method == null) {
return false;
}
try {
if (method.getParameterNames().length < parameterIndex) {
return true;
}
String parameterName = method.getParameterNames()[parameterIndex].toLowerCase();
String expression = arguments.get(parameterIndex).toString().toLowerCase();
return expression.contains(parameterName);
} catch (JavaModelException ex) {
JavaPlugin.log(ex);
return false;
}
}
private boolean skipParameterNamesCodeMinings(IMethod method) {
return method.getNumberOfParameters() <= 1;
}
}