use of org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter in project intellij-community by JetBrains.
the class GroovyPostHighlightingPass method doCollectInformation.
@Override
public void doCollectInformation(@NotNull final ProgressIndicator progress) {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
VirtualFile virtualFile = myFile.getViewProvider().getVirtualFile();
if (!fileIndex.isInContent(virtualFile)) {
return;
}
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(myProject).getCurrentProfile();
final HighlightDisplayKey unusedDefKey = HighlightDisplayKey.find(GroovyUnusedDeclarationInspection.SHORT_NAME);
final boolean deadCodeEnabled = profile.isToolEnabled(unusedDefKey, myFile);
final UnusedDeclarationInspectionBase deadCodeInspection = (UnusedDeclarationInspectionBase) profile.getUnwrappedTool(UnusedDeclarationInspectionBase.SHORT_NAME, myFile);
final GlobalUsageHelper usageHelper = new GlobalUsageHelper() {
@Override
public boolean isCurrentFileAlreadyChecked() {
return false;
}
@Override
public boolean isLocallyUsed(@NotNull PsiNamedElement member) {
return false;
}
@Override
public boolean shouldCheckUsages(@NotNull PsiMember member) {
return deadCodeInspection == null || !deadCodeInspection.isEntryPoint(member);
}
};
final List<HighlightInfo> unusedDeclarations = new ArrayList<>();
final Map<GrParameter, Boolean> usedParams = new HashMap<>();
myFile.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof GrReferenceExpression && !((GrReferenceElement) element).isQualified()) {
GroovyResolveResult[] results = ((GrReferenceExpression) element).multiResolve(false);
if (results.length == 0) {
results = ((GrReferenceExpression) element).multiResolve(true);
}
for (GroovyResolveResult result : results) {
PsiElement resolved = result.getElement();
if (resolved instanceof GrParameter && resolved.getContainingFile() == myFile) {
usedParams.put((GrParameter) resolved, Boolean.TRUE);
}
}
}
if (deadCodeEnabled && element instanceof GrNamedElement && element instanceof PsiModifierListOwner && !UnusedSymbolUtil.isImplicitUsage(element.getProject(), (PsiModifierListOwner) element, progress) && !GroovySuppressableInspectionTool.isElementToolSuppressedIn(element, GroovyUnusedDeclarationInspection.SHORT_NAME)) {
PsiElement nameId = ((GrNamedElement) element).getNameIdentifierGroovy();
if (nameId.getNode().getElementType() == GroovyTokenTypes.mIDENT) {
String name = ((GrNamedElement) element).getName();
if (element instanceof GrTypeDefinition && !UnusedSymbolUtil.isClassUsed(myProject, element.getContainingFile(), (GrTypeDefinition) element, progress, usageHelper)) {
HighlightInfo highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfo(nameId, "Class " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL);
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createSafeDeleteFix(element), unusedDefKey);
ContainerUtil.addIfNotNull(unusedDeclarations, highlightInfo);
} else if (element instanceof GrMethod) {
GrMethod method = (GrMethod) element;
if (!UnusedSymbolUtil.isMethodReferenced(method.getProject(), method.getContainingFile(), method, progress, usageHelper)) {
String message = (method.isConstructor() ? "Constructor" : "Method") + " " + name + " is unused";
HighlightInfo highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfo(nameId, message, HighlightInfoType.UNUSED_SYMBOL);
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createSafeDeleteFix(method), unusedDefKey);
ContainerUtil.addIfNotNull(unusedDeclarations, highlightInfo);
}
} else if (element instanceof GrField && isFieldUnused((GrField) element, progress, usageHelper)) {
HighlightInfo highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfo(nameId, "Property " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL);
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createSafeDeleteFix(element), unusedDefKey);
ContainerUtil.addIfNotNull(unusedDeclarations, highlightInfo);
} else if (element instanceof GrParameter) {
if (!usedParams.containsKey(element)) {
usedParams.put((GrParameter) element, Boolean.FALSE);
}
}
}
}
super.visitElement(element);
}
});
final Set<GrImportStatement> unusedImports = new HashSet<>(PsiUtil.getValidImportStatements(myFile));
unusedImports.removeAll(GroovyImportUtil.findUsedImports(myFile));
myUnusedImports = unusedImports;
if (deadCodeEnabled) {
for (GrParameter parameter : usedParams.keySet()) {
if (usedParams.get(parameter))
continue;
PsiElement scope = parameter.getDeclarationScope();
if (scope instanceof GrMethod) {
GrMethod method = (GrMethod) scope;
if (methodMayHaveUnusedParameters(method)) {
PsiElement identifier = parameter.getNameIdentifierGroovy();
HighlightInfo highlightInfo = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, "Parameter " + parameter.getName() + " is unused", HighlightInfoType.UNUSED_SYMBOL);
QuickFixAction.registerQuickFixAction(highlightInfo, GroovyQuickFixFactory.getInstance().createRemoveUnusedGrParameterFix(parameter), unusedDefKey);
ContainerUtil.addIfNotNull(unusedDeclarations, highlightInfo);
}
} else if (scope instanceof GrClosableBlock) {
//todo Max Medvedev
}
}
}
myUnusedDeclarations = unusedDeclarations;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter in project intellij-community by JetBrains.
the class GroovyTypeCheckVisitor method visitMethod.
/**
* Handles method default values.
*/
@Override
public void visitMethod(@NotNull GrMethod method) {
super.visitMethod(method);
final PsiTypeParameter[] parameters = method.getTypeParameters();
final Map<PsiTypeParameter, PsiType> map = ContainerUtil.newHashMap();
for (PsiTypeParameter parameter : parameters) {
final PsiClassType[] types = parameter.getSuperTypes();
final PsiType bound = PsiIntersectionType.createIntersection(types);
final PsiWildcardType wildcardType = PsiWildcardType.createExtends(method.getManager(), bound);
map.put(parameter, wildcardType);
}
final PsiSubstitutor substitutor = PsiSubstitutorImpl.createSubstitutor(map);
for (GrParameter parameter : method.getParameterList().getParameters()) {
final GrExpression initializer = parameter.getInitializerGroovy();
if (initializer == null)
continue;
final PsiType targetType = parameter.getType();
processAssignment(substitutor.substitute(targetType), initializer, parameter.getNameIdentifierGroovy(), "cannot.assign", method, ApplicableTo.ASSIGNMENT);
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter in project intellij-community by JetBrains.
the class GroovyTypeCheckVisitor method visitParameterList.
@Override
public void visitParameterList(@NotNull final GrParameterList parameterList) {
super.visitParameterList(parameterList);
PsiElement parent = parameterList.getParent();
if (!(parent instanceof GrClosableBlock))
return;
GrParameter[] parameters = parameterList.getParameters();
if (parameters.length > 0) {
List<PsiType[]> signatures = ClosureParamsEnhancer.findFittingSignatures((GrClosableBlock) parent);
final List<PsiType> paramTypes = ContainerUtil.map(parameters, parameter -> parameter.getType());
if (signatures.size() > 1) {
final PsiType[] fittingSignature = ContainerUtil.find(signatures, types -> {
for (int i = 0; i < types.length; i++) {
if (!TypesUtil.isAssignableByMethodCallConversion(paramTypes.get(i), types[i], parameterList)) {
return false;
}
}
return true;
});
if (fittingSignature == null) {
registerError(parameterList, GroovyInspectionBundle.message("no.applicable.signature.found"), null, ProblemHighlightType.GENERIC_ERROR);
}
} else if (signatures.size() == 1) {
PsiType[] types = signatures.get(0);
for (int i = 0; i < types.length; i++) {
GrTypeElement typeElement = parameters[i].getTypeElementGroovy();
if (typeElement == null)
continue;
PsiType expected = types[i];
PsiType actual = paramTypes.get(i);
if (!TypesUtil.isAssignableByMethodCallConversion(actual, expected, parameterList)) {
registerError(typeElement, GroovyInspectionBundle.message("expected.type.0", expected.getCanonicalText(false), actual.getCanonicalText(false)), null, ProblemHighlightType.GENERIC_ERROR);
}
}
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter in project intellij-community by JetBrains.
the class DelegatesToInspection method buildVisitor.
@NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
@Override
public void visitAnnotation(@NotNull GrAnnotation annotation) {
checkTarget(annotation);
checkDelegatesTo(annotation);
}
private void checkTarget(GrAnnotation annotation) {
if (!GroovyCommonClassNames.GROOVY_LANG_DELEGATES_TO_TARGET.equals(annotation.getQualifiedName()))
return;
final PsiElement owner = annotation.getParent().getParent();
if (!(owner instanceof GrParameter))
return;
final boolean isTargetDeclared = annotation.findDeclaredAttributeValue("value") != null;
String targetName = GrAnnotationUtil.inferStringAttribute(annotation, "value");
final GrParameterList parameterList = DefaultGroovyMethods.asType(owner.getParent(), GrParameterList.class);
for (GrParameter parameter : parameterList.getParameters()) {
final PsiAnnotation delegatesTo = parameter.getModifierList().findAnnotation(GroovyCommonClassNames.GROOVY_LANG_DELEGATES_TO);
if (delegatesTo != null) {
if (isTargetDeclared) {
final String curTarget = GrAnnotationUtil.inferStringAttribute(delegatesTo, "target");
if (curTarget != null && curTarget.equals(targetName)) {
//target is used
return;
}
} else {
if (delegatesTo.findDeclaredAttributeValue("target") == null && delegatesTo.findDeclaredAttributeValue("value") == null) {
// target is used
return;
}
}
}
}
registerError(annotation.getClassReference(), GroovyInspectionBundle.message("target.annotation.is.unused"), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
private void checkDelegatesTo(GrAnnotation annotation) {
if (!GroovyCommonClassNames.GROOVY_LANG_DELEGATES_TO.equals(annotation.getQualifiedName()))
return;
final PsiElement owner = annotation.getParent().getParent();
if (!(owner instanceof GrParameter))
return;
final PsiAnnotationMemberValue targetPair = annotation.findDeclaredAttributeValue("target");
if (targetPair == null)
return;
String targetName = GrAnnotationUtil.inferStringAttribute(annotation, "target");
final GrParameterList parameterList = DefaultGroovyMethods.asType(owner.getParent(), GrParameterList.class);
for (GrParameter parameter : parameterList.getParameters()) {
final PsiAnnotation target = parameter.getModifierList().findAnnotation(GroovyCommonClassNames.GROOVY_LANG_DELEGATES_TO_TARGET);
if (target != null) {
final String curTarget = GrAnnotationUtil.inferStringAttribute(target, "value");
if (curTarget != null && curTarget.equals(targetName)) {
//target is used
return;
}
}
}
registerError(targetPair, GroovyInspectionBundle.message("target.0.does.not.exist", targetName != null ? targetName : "?"), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
};
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter in project intellij-community by JetBrains.
the class GrUnusedDefaultParameterInspection method isInitializerUnused.
/**
* Consider following method:
* <pre>
* def foo(a = 1, b = 2, c = 3) {}
* </pre>
* Its reflected methods:
* <pre>
* def foo(a, b, c) {}
* def foo(a, b) {}
* def foo(a) {}
* def foo() {}
* </pre>
* Initializer for '<code>a</code>' is used only when <code>foo</code> called without arguments,
* we do not care if <code>foo</code> is called with one, two ot three arguments.
* <p>
* In case of <code>b</code> we search <code>foo()</code> or <code>foo(1)</code> calls.
* <p>
* The general idea: search usages of last N reflected methods where N is number of current parameter among other default parameters.
*/
private static boolean isInitializerUnused(@NotNull GrParameter parameter, @NotNull GrMethod method) {
int optionalParameterNumber = 0;
for (GrParameter someParameter : method.getParameters()) {
if (someParameter.isOptional())
optionalParameterNumber++;
if (someParameter == parameter)
break;
}
GrReflectedMethod[] reflectedMethods = method.getReflectedMethods();
for (int i = reflectedMethods.length - optionalParameterNumber; i < reflectedMethods.length; i++) {
GrReflectedMethod reflectedMethod = reflectedMethods[i];
if (FindSuperElementsHelper.findSuperElements(reflectedMethod).length > 0)
return false;
if (MethodReferencesSearch.search(reflectedMethod).findFirst() != null)
return false;
}
return true;
}
Aggregations