use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.
the class GrFinalVariableAccessInspection method appendInitializationFromChainedConstructors.
private static void appendInitializationFromChainedConstructors(@NotNull GrMethod constructor, @NotNull List<GrField> fields, @NotNull Set<GrVariable> initializedFields) {
final List<GrMethod> chained = getChainedConstructors(constructor);
chained.remove(0);
for (GrMethod method : chained) {
final GrOpenBlock block = method.getBlock();
if (block == null)
continue;
final Instruction[] flow = buildFlowForField(block);
for (GrField field : fields) {
if (!field.hasModifierProperty(PsiModifier.STATIC) && !initializedFields.contains(field) && VariableInitializationChecker.isVariableDefinitelyInitializedCached(field, block, flow)) {
initializedFields.add(field);
}
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock 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.blocks.GrOpenBlock 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.blocks.GrOpenBlock in project intellij-community by JetBrains.
the class GrChangeSignatureUsageProcessor method processConstructor.
private static void processConstructor(GrMethod constructor, JavaChangeInfo changeInfo) {
final PsiClass containingClass = constructor.getContainingClass();
final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, containingClass, PsiSubstitutor.EMPTY);
GrOpenBlock block = constructor.getBlock();
GrConstructorInvocation invocation = GroovyPsiElementFactory.getInstance(constructor.getProject()).createConstructorInvocation("super()");
invocation = (GrConstructorInvocation) block.addStatementBefore(invocation, getFirstStatement(block));
processMethodUsage(invocation.getInvokedExpression(), changeInfo, changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(), changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.<PsiElement>empty_array(), substitutor);
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock in project intellij-community by JetBrains.
the class GrChageSignatureUsageSearcher method detectLocalsCollisionsInMethod.
/* todo
private void findUsagesInCallers(final ArrayList<UsageInfo> usages) {
if (myChangeInfo instanceof JavaChangeInfoImpl) {
JavaChangeInfoImpl changeInfo = (JavaChangeInfoImpl)myChangeInfo;
for (PsiMethod caller : changeInfo.propagateParametersMethods) {
usages.add(new CallerUsageInfo(caller, true, changeInfo.propagateExceptionsMethods.contains(caller)));
}
for (PsiMethod caller : changeInfo.propagateExceptionsMethods) {
usages.add(new CallerUsageInfo(caller, changeInfo.propagateParametersMethods.contains(caller), true));
}
Set<PsiMethod> merged = new HashSet<PsiMethod>();
merged.addAll(changeInfo.propagateParametersMethods);
merged.addAll(changeInfo.propagateExceptionsMethods);
for (final PsiMethod method : merged) {
findSimpleUsagesWithoutParameters(method, usages, changeInfo.propagateParametersMethods.contains(method),
changeInfo.propagateExceptionsMethods.contains(method), false);
}
}
}
*/
private void detectLocalsCollisionsInMethod(final GrMethod method, final ArrayList<UsageInfo> result, boolean isOriginal) {
if (!GroovyLanguage.INSTANCE.equals(method.getLanguage()))
return;
final PsiParameter[] parameters = method.getParameterList().getParameters();
final Set<PsiParameter> deletedOrRenamedParameters = new HashSet<>();
if (isOriginal) {
ContainerUtil.addAll(deletedOrRenamedParameters, parameters);
for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
if (parameterInfo.getOldIndex() >= 0) {
final PsiParameter parameter = parameters[parameterInfo.getOldIndex()];
if (parameterInfo.getName().equals(parameter.getName())) {
deletedOrRenamedParameters.remove(parameter);
}
}
}
}
final GrOpenBlock block = method.getBlock();
for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
final int oldParameterIndex = parameterInfo.getOldIndex();
final String newName = parameterInfo.getName();
if (oldParameterIndex >= 0) {
if (isOriginal) {
//Name changes take place only in primary method
final PsiParameter parameter = parameters[oldParameterIndex];
if (!newName.equals(parameter.getName())) {
final GrUnresolvableLocalCollisionDetector.CollidingVariableVisitor collidingVariableVisitor = new GrUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
@Override
public void visitCollidingVariable(final PsiVariable collidingVariable) {
if (!deletedOrRenamedParameters.contains(collidingVariable)) {
result.add(new RenamedParameterCollidesWithLocalUsageInfo(parameter, collidingVariable, method));
}
}
};
if (block != null) {
GrUnresolvableLocalCollisionDetector.visitLocalsCollisions(parameter, newName, block, collidingVariableVisitor);
}
}
}
} else {
final GrUnresolvableLocalCollisionDetector.CollidingVariableVisitor variableVisitor = new GrUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
@Override
public void visitCollidingVariable(PsiVariable collidingVariable) {
if (!deletedOrRenamedParameters.contains(collidingVariable)) {
result.add(new NewParameterCollidesWithLocalUsageInfo(collidingVariable, collidingVariable, method));
}
}
};
if (block != null) {
GrUnresolvableLocalCollisionDetector.visitLocalsCollisions(method, newName, block, variableVisitor);
}
}
}
}
Aggregations