use of org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod in project intellij-community by JetBrains.
the class GrFinalVariableAccessInspection method isFieldInitialized.
private static boolean isFieldInitialized(@NotNull GrField field) {
if (field instanceof GrEnumConstant)
return true;
if (field.getInitializerGroovy() != null)
return true;
if (isImmutableField(field))
return true;
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
final GrTypeDefinition aClass = ((GrTypeDefinition) field.getContainingClass());
if (aClass == null)
return true;
GrClassInitializer[] initializers = aClass.getInitializers();
for (GrClassInitializer initializer : initializers) {
if (initializer.isStatic() != isStatic)
continue;
final GrOpenBlock block = initializer.getBlock();
final Instruction[] initializerFlow = buildFlowForField(block);
if (VariableInitializationChecker.isVariableDefinitelyInitializedCached(field, block, initializerFlow)) {
return true;
}
}
if (isStatic)
return false;
final GrMethod[] constructors = aClass.getCodeConstructors();
if (constructors.length == 0)
return false;
Set<GrMethod> initializedConstructors = ContainerUtil.newHashSet();
Set<GrMethod> notInitializedConstructors = ContainerUtil.newHashSet();
NEXT_CONSTR: for (GrMethod constructor : constructors) {
if (constructor.getBlock() == null)
return false;
final List<GrMethod> chained = getChainedConstructors(constructor);
NEXT_CHAINED: for (GrMethod method : chained) {
if (initializedConstructors.contains(method)) {
continue NEXT_CONSTR;
} else if (notInitializedConstructors.contains(method)) {
continue NEXT_CHAINED;
}
final GrOpenBlock block = method.getBlock();
assert block != null;
final boolean initialized = VariableInitializationChecker.isVariableDefinitelyInitializedCached(field, block, buildFlowForField(block));
if (initialized) {
initializedConstructors.add(method);
continue NEXT_CONSTR;
} else {
notInitializedConstructors.add(method);
}
}
return false;
}
return true;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod in project intellij-community by JetBrains.
the class GrFinalVariableAccessInspection method buildVisitor.
@NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
@Override
public void visitMethod(@NotNull GrMethod method) {
super.visitMethod(method);
final GrOpenBlock block = method.getBlock();
if (block != null) {
processLocalVars(block);
}
if (method.isConstructor()) {
processFieldsInConstructors(method);
}
}
@Override
public void visitFile(@NotNull GroovyFileBase file) {
super.visitFile(file);
if (file instanceof GroovyFile && file.isScript()) {
processLocalVars(file);
}
}
@Override
public void visitField(@NotNull GrField field) {
super.visitField(field);
final GrExpression initializer = field.getInitializerGroovy();
if (initializer != null) {
processLocalVars(initializer);
}
if (field.hasModifierProperty(PsiModifier.FINAL)) {
if (!isFieldInitialized(field)) {
registerError(field.getNameIdentifierGroovy(), GroovyBundle.message("variable.0.might.not.have.been.initialized", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
}
@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
final PsiElement resolved = ref.resolve();
if (resolved instanceof GrField && ((GrField) resolved).hasModifierProperty(PsiModifier.FINAL)) {
final GrField field = (GrField) resolved;
final PsiClass containingClass = field.getContainingClass();
if (PsiUtil.isLValue(ref)) {
if (containingClass == null || !PsiTreeUtil.isAncestor(containingClass, ref, true)) {
registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
} else if (PsiUtil.isUsedInIncOrDec(ref)) {
if (containingClass == null || !isInsideConstructorOrInitializer(containingClass, ref, field.hasModifierProperty(PsiModifier.STATIC))) {
registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
} else if (resolved instanceof GrParameter && ((GrParameter) resolved).getDeclarationScope() instanceof GrMethod && ((GrParameter) resolved).hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isUsedInIncOrDec(ref)) {
registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.parameter.0", ((GrParameter) resolved).getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
@Override
public void visitClassInitializer(@NotNull GrClassInitializer initializer) {
super.visitClassInitializer(initializer);
processLocalVars(initializer.getBlock());
processFieldsInClassInitializer(initializer);
}
private void processFieldsInConstructors(@NotNull GrMethod constructor) {
final GrOpenBlock block = constructor.getBlock();
if (block == null)
return;
final GrTypeDefinition clazz = (GrTypeDefinition) constructor.getContainingClass();
if (clazz == null)
return;
final GrClassInitializer[] initializers = clazz.getInitializers();
final List<GrField> fields = getFinalFields(clazz);
Set<GrVariable> initializedFields = ContainerUtil.newHashSet();
appendFieldInitializedInDeclaration(false, fields, initializedFields);
appendFieldsInitializedInClassInitializer(initializers, null, false, fields, initializedFields);
appendInitializationFromChainedConstructors(constructor, fields, initializedFields);
final Instruction[] flow = buildFlowForField(block);
final Map<String, GrVariable> variables = buildVarMap(fields, false);
highlightInvalidWriteAccess(flow, variables, initializedFields);
}
private void processFieldsInClassInitializer(@NotNull GrClassInitializer initializer) {
final GrTypeDefinition clazz = (GrTypeDefinition) initializer.getContainingClass();
if (clazz == null)
return;
final boolean isStatic = initializer.isStatic();
final GrClassInitializer[] initializers = clazz.getInitializers();
final List<GrField> fields = getFinalFields(clazz);
Set<GrVariable> initializedFields = ContainerUtil.newHashSet();
appendFieldInitializedInDeclaration(isStatic, fields, initializedFields);
appendFieldsInitializedInClassInitializer(initializers, initializer, isStatic, fields, initializedFields);
final Instruction[] flow = buildFlowForField(initializer.getBlock());
final Map<String, GrVariable> variables = buildVarMap(fields, isStatic);
highlightInvalidWriteAccess(flow, variables, initializedFields);
}
private void processLocalVars(@NotNull GroovyPsiElement scope) {
final MultiMap<PsiElement, GrVariable> scopes = collectVariables(scope);
for (final Map.Entry<PsiElement, Collection<GrVariable>> entry : scopes.entrySet()) {
final PsiElement scopeToProcess = entry.getKey();
final Set<GrVariable> forInParameters = ContainerUtil.newHashSet();
final Map<String, GrVariable> variables = ContainerUtil.newHashMap();
for (final GrVariable var : entry.getValue()) {
variables.put(var.getName(), var);
if (var instanceof GrParameter && ((GrParameter) var).getDeclarationScope() instanceof GrForStatement) {
forInParameters.add(var);
}
}
final Instruction[] flow = getFlow(scopeToProcess);
highlightInvalidWriteAccess(flow, variables, forInParameters);
}
}
private void highlightInvalidWriteAccess(@NotNull Instruction[] flow, @NotNull Map<String, GrVariable> variables, @NotNull Set<GrVariable> initializedVariables) {
final List<ReadWriteVariableInstruction> result = InvalidWriteAccessSearcher.findInvalidWriteAccess(flow, variables, initializedVariables);
if (result == null)
return;
for (final ReadWriteVariableInstruction instruction : result) {
if (variables.containsKey(instruction.getVariableName())) {
registerError(instruction.getElement(), GroovyBundle.message("cannot.assign.a.value.to.final.field.0", instruction.getVariableName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
}
};
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod in project intellij-community by JetBrains.
the class GroovyVariableCanBeFinalInspection method process.
private static void process(@NotNull GrControlFlowOwner owner, @NotNull GrVariable variable, @NotNull ProblemsHolder problemsHolder) {
if (variable.hasModifierProperty(PsiModifier.FINAL))
return;
if (!checkVariableDeclaredInsideScope(owner, variable))
return;
if (checkVariableAssignedInsideClosureOrAnonymous(owner, variable))
return;
final boolean isParameterTooltip = variable instanceof GrParameter && (((GrParameter) variable).getDeclarationScope() instanceof GrMethod || ((GrParameter) variable).getDeclarationScope() instanceof GrClosableBlock);
final String tooltip = GroovyInspectionBundle.message(isParameterTooltip ? "parameter.can.be.final.tooltip" : "variable.can.be.final.tooltip", variable.getName());
problemsHolder.registerProblem(variable.getNameIdentifierGroovy(), tooltip, new GrModifierFix(variable, PsiModifier.FINAL, true, ID_MODIFIER_LIST_PROVIDER));
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod in project intellij-community by JetBrains.
the class GrMethodMayBeStaticInspection method buildVisitor.
@NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
@Override
public void visitMethod(@NotNull GrMethod method) {
if (checkMethod(method)) {
final GrModifierFix modifierFix = new GrModifierFix(method, PsiModifier.STATIC, false, true, descriptor -> {
final PsiElement element = descriptor.getPsiElement();
final PsiElement parent = element.getParent();
assert parent instanceof GrMethod : "element: " + element + ", parent:" + parent;
return ((GrMethod) parent).getModifierList();
});
registerError(method.getNameIdentifierGroovy(), message("method.may.be.static"), new LocalQuickFix[] { modifierFix }, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
};
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod 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;
}
Aggregations