use of com.intellij.psi.infos.CandidateInfo in project intellij-community by JetBrains.
the class PsiDocParamRef method getReference.
@Override
public PsiReference getReference() {
final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
if (comment == null)
return null;
final PsiJavaDocumentedElement owner = comment.getOwner();
if (!(owner instanceof PsiMethod) && !(owner instanceof PsiClass))
return null;
final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
if (valueToken == null)
return null;
final String name = valueToken.getText();
PsiElement reference = null;
final PsiElement firstChild = getFirstChild();
if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
final PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner) owner).getTypeParameters();
for (PsiTypeParameter typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
reference = typeParameter;
}
}
} else if (owner instanceof PsiMethod) {
final PsiParameter[] parameters = ((PsiMethod) owner).getParameterList().getParameters();
for (PsiParameter parameter : parameters) {
if (parameter.getName().equals(name)) {
reference = parameter;
}
}
}
final PsiElement resultReference = reference;
return new PsiJavaReference() {
@Override
public PsiElement resolve() {
return resultReference;
}
@Override
@NotNull
public String getCanonicalText() {
return valueToken.getText();
}
@Override
public PsiElement handleElementRename(String newElementName) {
final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(getNode());
LeafElement newElement = Factory.createSingleLeafElement(JavaDocTokenType.DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager());
replaceChild(valueToken, newElement);
return PsiDocParamRef.this;
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (isReferenceTo(element))
return PsiDocParamRef.this;
if (!(element instanceof PsiParameter)) {
throw new IncorrectOperationException("Unsupported operation");
}
return handleElementRename(((PsiParameter) element).getName());
}
@Override
public boolean isReferenceTo(PsiElement element) {
if (!(element instanceof PsiNamedElement))
return false;
PsiNamedElement namedElement = (PsiNamedElement) element;
if (!getCanonicalText().equals(namedElement.getName()))
return false;
return getManager().areElementsEquivalent(resolve(), element);
}
@Override
@NotNull
public PsiElement[] getVariants() {
final PsiElement firstChild = getFirstChild();
Set<String> usedNames = new HashSet<>();
for (PsiDocTag tag : comment.getTags()) {
if (tag.getName().equals("param")) {
PsiDocTagValue valueElement = tag.getValueElement();
if (valueElement != null) {
usedNames.add(valueElement.getText());
}
}
}
PsiNamedElement[] result = PsiNamedElement.EMPTY_ARRAY;
if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
result = ((PsiTypeParameterListOwner) owner).getTypeParameters();
} else if (owner instanceof PsiMethod) {
result = ((PsiMethod) owner).getParameterList().getParameters();
}
List<PsiElement> filtered = new ArrayList<>();
for (PsiNamedElement namedElement : result) {
if (!usedNames.contains(namedElement.getName())) {
filtered.add(namedElement);
}
}
return filtered.toArray(new PsiElement[filtered.size()]);
}
@Override
public boolean isSoft() {
return false;
}
@Override
public TextRange getRangeInElement() {
final int startOffsetInParent = valueToken.getPsi().getStartOffsetInParent();
return new TextRange(startOffsetInParent, startOffsetInParent + valueToken.getTextLength());
}
@Override
public PsiElement getElement() {
return PsiDocParamRef.this;
}
@Override
public void processVariants(@NotNull PsiScopeProcessor processor) {
for (final PsiElement element : getVariants()) {
if (!processor.execute(element, ResolveState.initial())) {
return;
}
}
}
@Override
@NotNull
public JavaResolveResult advancedResolve(boolean incompleteCode) {
return resultReference == null ? JavaResolveResult.EMPTY : new CandidateInfo(resultReference, PsiSubstitutor.EMPTY);
}
@Override
@NotNull
public JavaResolveResult[] multiResolve(boolean incompleteCode) {
return resultReference == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[] { new CandidateInfo(resultReference, PsiSubstitutor.EMPTY) };
}
};
}
use of com.intellij.psi.infos.CandidateInfo in project intellij-community by JetBrains.
the class MethodCallFixer method getUnambiguousParameterCount.
@Nullable
private static Integer getUnambiguousParameterCount(PsiCallExpression call) {
int argCount = -1;
for (CandidateInfo candidate : PsiResolveHelper.SERVICE.getInstance(call.getProject()).getReferencedMethodCandidates(call, false)) {
PsiElement element = candidate.getElement();
if (!(element instanceof PsiMethod))
return null;
if (((PsiMethod) element).isVarArgs())
return null;
int count = ((PsiMethod) element).getParameterList().getParametersCount();
if (argCount == -1) {
argCount = count;
} else if (argCount != count) {
return null;
}
}
return argCount;
}
use of com.intellij.psi.infos.CandidateInfo in project intellij-community by JetBrains.
the class PsiMethodWithOverridingPercentMember method calculateOverridingPercents.
@NotNull
public static PsiMethodWithOverridingPercentMember[] calculateOverridingPercents(@NotNull final Collection<CandidateInfo> candidateInfos) {
final List<PsiMethodWithOverridingPercentMember> result = new ArrayList<>(candidateInfos.size());
final Map<String, Collection<PsiClass>> classShortNames2Inheritors = new HashMap<>();
for (final CandidateInfo candidateInfo : candidateInfos) {
final PsiMethod method = (PsiMethod) candidateInfo.getElement();
if (!method.hasModifierProperty(PsiModifier.FINAL) && !method.isConstructor() && !method.isDeprecated() && !EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES.contains(method.getName())) {
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
continue;
}
final String classShortName = containingClass.getName();
Collection<PsiClass> allInheritors = classShortNames2Inheritors.get(classShortName);
if (allInheritors == null) {
allInheritors = ClassInheritorsSearch.search(containingClass).findAll();
classShortNames2Inheritors.put(classShortName, allInheritors);
}
final int allInheritorsCount = allInheritors.size() - 1;
if (allInheritorsCount > 0) {
final int percent = searchForOverridingCount(method, allInheritors) * 100 / allInheritorsCount;
if (percent > 1) {
result.add(new PsiMethodWithOverridingPercentMember(candidateInfo, percent));
}
}
}
}
return result.toArray(new PsiMethodWithOverridingPercentMember[result.size()]);
}
use of com.intellij.psi.infos.CandidateInfo in project intellij-community by JetBrains.
the class MethodParameterInfoHandler method updateParameterInfo.
@Override
public void updateParameterInfo(@NotNull final PsiExpressionList o, @NotNull final UpdateParameterInfoContext context) {
PsiElement parameterOwner = context.getParameterOwner();
if (parameterOwner != o) {
context.removeHint();
return;
}
int index = ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), context.getOffset(), JavaTokenType.COMMA);
context.setCurrentParameter(index);
Object[] candidates = context.getObjectsToView();
PsiExpression[] args = o.getExpressions();
PsiCall call = getCall(o);
PsiElement realResolve = call != null ? call.resolveMethod() : null;
PsiMethod chosenMethod = CompletionMemory.getChosenMethod(call);
CandidateInfo chosenInfo = null;
CandidateInfo completeMatch = null;
for (int i = 0; i < candidates.length; i++) {
CandidateInfo candidate = (CandidateInfo) candidates[i];
PsiMethod method = (PsiMethod) candidate.getElement();
if (!method.isValid())
continue;
PsiSubstitutor substitutor = getCandidateInfoSubstitutor(candidate);
assert substitutor != null;
if (!method.isValid() || !substitutor.isValid()) {
// this may sometimes happen e,g, when editing method call in field initializer candidates in the same file get invalidated
context.setUIComponentEnabled(i, false);
continue;
}
PsiParameter[] parms = method.getParameterList().getParameters();
boolean enabled = true;
if (parms.length <= index) {
if (parms.length > 0) {
if (method.isVarArgs()) {
for (int j = 0; j < parms.length - 1; j++) {
PsiType parmType = substitutor.substitute(parms[j].getType());
PsiType argType = args[j].getType();
if (argType != null && !parmType.isAssignableFrom(argType)) {
enabled = false;
break;
}
}
if (enabled) {
PsiArrayType lastParmType = (PsiArrayType) substitutor.substitute(parms[parms.length - 1].getType());
PsiType componentType = lastParmType.getComponentType();
if (parms.length == args.length) {
PsiType lastArgType = args[args.length - 1].getType();
if (lastArgType != null && !lastParmType.isAssignableFrom(lastArgType) && !componentType.isAssignableFrom(lastArgType)) {
enabled = false;
}
} else {
for (int j = parms.length; j <= index && j < args.length; j++) {
PsiExpression arg = args[j];
PsiType argType = arg.getType();
if (argType != null && !componentType.isAssignableFrom(argType)) {
enabled = false;
break;
}
}
}
}
} else {
enabled = false;
}
} else {
enabled = index == 0;
}
} else {
enabled = isAssignableParametersBeforeGivenIndex(parms, args, index, substitutor);
}
context.setUIComponentEnabled(i, enabled);
if (candidates.length > 1 && enabled) {
if (chosenMethod == method) {
chosenInfo = candidate;
}
if (parms.length == args.length && realResolve == method && isAssignableParametersBeforeGivenIndex(parms, args, args.length, substitutor)) {
completeMatch = candidate;
}
}
}
if (chosenInfo != null) {
context.setHighlightedParameter(chosenInfo);
} else if (completeMatch != null) {
context.setHighlightedParameter(completeMatch);
}
}
use of com.intellij.psi.infos.CandidateInfo in project intellij-community by JetBrains.
the class MethodParameterInfoHandler method getCandidates.
private static CandidateInfo[] getCandidates(PsiCallExpression call) {
final MethodCandidatesProcessor processor = new MethodResolverProcessor(call, call.getContainingFile(), new PsiConflictResolver[0]) {
@Override
protected boolean acceptVarargs() {
return false;
}
};
try {
PsiScopesUtil.setupAndRunProcessor(processor, call, true);
} catch (MethodProcessorSetupFailedException e) {
return CandidateInfo.EMPTY_ARRAY;
}
final List<CandidateInfo> results = processor.getResults();
return results.toArray(new CandidateInfo[results.size()]);
}
Aggregations