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);
}
}
}
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);
}
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);
}
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();
}
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;
}
Aggregations