Search in sources :

Example 61 with GrParameter

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;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) GrField(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField) HighlightDisplayKey(com.intellij.codeInsight.daemon.HighlightDisplayKey) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GrImportStatement(org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement) NotNull(org.jetbrains.annotations.NotNull) GrNamedElement(org.jetbrains.plugins.groovy.lang.psi.GrNamedElement) InspectionProfile(com.intellij.codeInspection.InspectionProfile) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) UnusedDeclarationInspectionBase(com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase) GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrTypeDefinition(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition) ProjectFileIndex(com.intellij.openapi.roots.ProjectFileIndex)

Example 62 with GrParameter

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);
    }
}
Also used : GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)

Example 63 with GrParameter

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);
                }
            }
        }
    }
}
Also used : GrTypeElement(org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 64 with GrParameter

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);
        }
    };
}
Also used : GrParameterList(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList) BaseInspectionVisitor(org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor) GrAnnotation(org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation) PsiAnnotation(com.intellij.psi.PsiAnnotation) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) PsiAnnotationMemberValue(com.intellij.psi.PsiAnnotationMemberValue) NotNull(org.jetbrains.annotations.NotNull)

Example 65 with GrParameter

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;
}
Also used : GrReflectedMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)

Aggregations

GrParameter (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)99 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)22 NotNull (org.jetbrains.annotations.NotNull)20 PsiElement (com.intellij.psi.PsiElement)19 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)19 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)18 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)16 GrParameterList (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList)14 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)13 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)12 ArrayList (java.util.ArrayList)11 GrVariable (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable)10 TextRange (com.intellij.openapi.util.TextRange)9 GrOpenBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)9 Nullable (org.jetbrains.annotations.Nullable)8 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)7 Project (com.intellij.openapi.project.Project)6 IncorrectOperationException (com.intellij.util.IncorrectOperationException)6 GroovyFile (org.jetbrains.plugins.groovy.lang.psi.GroovyFile)6 GrField (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField)6