Search in sources :

Example 21 with GrOpenBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.

the class GroovyAnnotator method checkRecursiveConstructors.

private static void checkRecursiveConstructors(AnnotationHolder holder, PsiMethod[] constructors) {
    Map<PsiMethod, PsiMethod> nodes = new HashMap<>(constructors.length);
    Set<PsiMethod> set = ContainerUtil.set(constructors);
    for (PsiMethod constructor : constructors) {
        if (!(constructor instanceof GrMethod))
            continue;
        final GrOpenBlock block = ((GrMethod) constructor).getBlock();
        if (block == null)
            continue;
        final GrStatement[] statements = block.getStatements();
        if (statements.length <= 0 || !(statements[0] instanceof GrConstructorInvocation))
            continue;
        final PsiMethod resolved = ((GrConstructorInvocation) statements[0]).resolveMethod();
        if (!set.contains(resolved))
            continue;
        nodes.put(constructor, resolved);
    }
    Set<PsiMethod> checked = new HashSet<>();
    Set<PsiMethod> current;
    for (PsiMethod constructor : constructors) {
        if (!checked.add(constructor))
            continue;
        current = new HashSet<>();
        current.add(constructor);
        for (constructor = nodes.get(constructor); constructor != null && current.add(constructor); constructor = nodes.get(constructor)) {
            checked.add(constructor);
        }
        if (constructor != null) {
            PsiMethod circleStart = constructor;
            do {
                holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(constructor), GroovyBundle.message("recursive.constructor.invocation"));
                constructor = nodes.get(constructor);
            } while (constructor != circleStart);
        }
    }
}
Also used : GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) HashSet(com.intellij.util.containers.HashSet) THashSet(gnu.trove.THashSet)

Example 22 with GrOpenBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.

the class GroovyAnnotator method visitMethod.

@Override
public void visitMethod(@NotNull GrMethod method) {
    checkDuplicateMethod(method);
    checkMethodWithTypeParamsShouldHaveReturnType(myHolder, method);
    checkInnerMethod(myHolder, method);
    checkOptionalParametersInAbstractMethod(myHolder, method);
    checkConstructorOfImmutableClass(myHolder, method);
    checkGetterOfImmutable(myHolder, method);
    final PsiElement nameIdentifier = method.getNameIdentifierGroovy();
    if (nameIdentifier.getNode().getElementType() == GroovyTokenTypes.mSTRING_LITERAL) {
        checkStringLiteral(nameIdentifier);
    }
    GrOpenBlock block = method.getBlock();
    if (block != null && TypeInferenceHelper.isTooComplexTooAnalyze(block)) {
        myHolder.createWeakWarningAnnotation(nameIdentifier, GroovyBundle.message("method.0.is.too.complex.too.analyze", method.getName()));
    }
    final PsiClass containingClass = method.getContainingClass();
    if (method.isConstructor()) {
        if (containingClass instanceof GrAnonymousClassDefinition) {
            myHolder.createErrorAnnotation(nameIdentifier, GroovyBundle.message("constructors.are.not.allowed.in.anonymous.class"));
        } else if (containingClass != null && containingClass.isInterface()) {
            myHolder.createErrorAnnotation(nameIdentifier, GroovyBundle.message("constructors.are.not.allowed.in.interface"));
        }
    }
    if (method.getBlock() == null && !method.hasModifierProperty(PsiModifier.NATIVE) && !GrTraitUtil.isMethodAbstract(method)) {
        final Annotation annotation = myHolder.createErrorAnnotation(nameIdentifier, GroovyBundle.message("not.abstract.method.should.have.body"));
    //annotation.registerFix(new AddMethodBodyFix(method)); //todo make intentions work
    //registerFix(annotation, new GrModifierFix(method, ABSTRACT, false, true, GrModifierFix.MODIFIER_LIST_OWNER), method);
    }
    checkOverridingMethod(myHolder, method);
}
Also used : GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) Annotation(com.intellij.lang.annotation.Annotation)

Example 23 with GrOpenBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.

the class GroovyAnnotator method checkConstructors.

private static void checkConstructors(AnnotationHolder holder, GrTypeDefinition typeDefinition) {
    if (typeDefinition.isEnum() || typeDefinition.isInterface() || typeDefinition.isAnonymous() || typeDefinition instanceof GrTypeParameter)
        return;
    final PsiClass superClass = typeDefinition.getSuperClass();
    if (superClass == null)
        return;
    if (InheritConstructorContributor.hasInheritConstructorsAnnotation(typeDefinition))
        return;
    PsiMethod defConstructor = getDefaultConstructor(superClass);
    boolean hasImplicitDefConstructor = superClass.getConstructors().length == 0;
    final PsiMethod[] constructors = typeDefinition.getCodeConstructors();
    final String qName = superClass.getQualifiedName();
    if (constructors.length == 0) {
        if (!hasImplicitDefConstructor && (defConstructor == null || !PsiUtil.isAccessible(typeDefinition, defConstructor))) {
            final TextRange range = GrHighlightUtil.getClassHeaderTextRange(typeDefinition);
            holder.createErrorAnnotation(range, GroovyBundle.message("there.is.no.default.constructor.available.in.class.0", qName)).registerFix(QuickFixFactory.getInstance().createCreateConstructorMatchingSuperFix(typeDefinition));
        }
        return;
    }
    for (PsiMethod method : constructors) {
        if (method instanceof GrMethod) {
            final GrOpenBlock block = ((GrMethod) method).getBlock();
            if (block == null)
                continue;
            final GrStatement[] statements = block.getStatements();
            if (statements.length > 0) {
                if (statements[0] instanceof GrConstructorInvocation)
                    continue;
            }
            if (!hasImplicitDefConstructor && (defConstructor == null || !PsiUtil.isAccessible(typeDefinition, defConstructor))) {
                holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method), GroovyBundle.message("there.is.no.default.constructor.available.in.class.0", qName));
            }
        }
    }
    checkRecursiveConstructors(holder, constructors);
}
Also used : TextRange(com.intellij.openapi.util.TextRange) GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)

Example 24 with GrOpenBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.

the class GrMethodMayBeStaticInspection method checkMethod.

private boolean checkMethod(final GrMethod method) {
    if (method.hasModifierProperty(PsiModifier.STATIC))
        return false;
    if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED))
        return false;
    if (method.getModifierList().hasExplicitModifier(PsiModifier.ABSTRACT))
        return false;
    if (method.isConstructor())
        return false;
    PsiClass containingClass = method.getContainingClass();
    if (containingClass == null)
        return false;
    if (myIgnoreTraitMethods && containingClass instanceof GrTraitTypeDefinition)
        return false;
    if (SuperMethodsSearch.search(method, null, true, false).findFirst() != null)
        return false;
    if (OverridingMethodsSearch.search(method).findFirst() != null)
        return false;
    if (ignoreMethod(method))
        return false;
    if (myOnlyPrivateOrFinal) {
        if (!(method.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty(PsiModifier.PRIVATE)))
            return false;
    }
    GrOpenBlock block = method.getBlock();
    if (block == null)
        return false;
    if (myIgnoreEmptyMethods && block.getStatements().length == 0)
        return false;
    if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
        return false;
    }
    final Condition<PsiElement>[] addins = InspectionManager.CANT_BE_STATIC_EXTENSION.getExtensions();
    for (Condition<PsiElement> addin : addins) {
        if (addin.value(method)) {
            return false;
        }
    }
    MethodMayBeStaticVisitor visitor = new MethodMayBeStaticVisitor();
    method.accept(visitor);
    return !visitor.haveInstanceRefsOutsideClosures();
}
Also used : Condition(com.intellij.openapi.util.Condition) GrTraitTypeDefinition(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTraitTypeDefinition) GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 25 with GrOpenBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.

the class RecursionUtils method tryStatementMayReturnBeforeRecursing.

private static boolean tryStatementMayReturnBeforeRecursing(GrTryCatchStatement tryStatement, GrMethod method) {
    final GrFinallyClause finallyBlock = tryStatement.getFinallyClause();
    if (finallyBlock != null) {
        final GrOpenBlock body = finallyBlock.getBody();
        if (codeBlockMayReturnBeforeRecursing(body, method, false)) {
            return true;
        }
        if (codeBlockDefinitelyRecurses(body, method)) {
            return false;
        }
    }
    final GrCodeBlock tryBlock = tryStatement.getTryBlock();
    if (codeBlockMayReturnBeforeRecursing(tryBlock, method, false)) {
        return true;
    }
    final GrCatchClause[] catchBlocks = tryStatement.getCatchClauses();
    for (final GrCatchClause catchBlock : catchBlocks) {
        if (codeBlockMayReturnBeforeRecursing(catchBlock.getBody(), method, false)) {
            return true;
        }
    }
    return false;
}
Also used : GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) GrCodeBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)

Aggregations

GrOpenBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)68 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)24 GrStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)21 PsiElement (com.intellij.psi.PsiElement)13 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)10 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)10 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)9 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)9 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)8 GrParameter (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)8 GrReturnStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement)7 Nullable (org.jetbrains.annotations.Nullable)6 NotNull (org.jetbrains.annotations.NotNull)5 GrBlockStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement)5 Instruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction)5 ReadWriteVariableInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction)5 TextRange (com.intellij.openapi.util.TextRange)4 GroovyRecursiveElementVisitor (org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor)4 GrCodeBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)4 UsageInfo (com.intellij.usageView.UsageInfo)3