mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
register Java fields referenced from injected fragments as read/written
This commit is contained in:
+4
@@ -41,6 +41,7 @@ import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
@@ -83,6 +84,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
PsiElement resolved = reference.resolve();
|
||||
if (resolved instanceof PsiNamedElement) {
|
||||
myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
|
||||
if (resolved instanceof PsiMember) {
|
||||
myRefCountHolder.registerReference(reference, new CandidateInfo(resolved, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-12
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator;
|
||||
import com.intellij.codeInsight.daemon.impl.FileStatusMap;
|
||||
import com.intellij.codeInsight.daemon.impl.GlobalUsageHelper;
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector;
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteUtil;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -33,7 +35,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiMatcherImpl;
|
||||
import com.intellij.psi.util.PsiMatchers;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.Predicate;
|
||||
@@ -279,21 +280,29 @@ class RefCountHolder {
|
||||
if (array.isEmpty()) return false;
|
||||
for (PsiReference ref : array) {
|
||||
PsiElement refElement = ref.getElement();
|
||||
if (!(refElement instanceof PsiExpression)) { // possible with incomplete code
|
||||
return true;
|
||||
}
|
||||
if (PsiUtil.isAccessedForReading((PsiExpression)refElement)) {
|
||||
if (refElement.getParent() instanceof PsiExpression &&
|
||||
refElement.getParent().getParent() instanceof PsiExpressionStatement &&
|
||||
PsiUtil.isAccessedForWriting((PsiExpression)refElement)) {
|
||||
continue; // "var++;"
|
||||
PsiElement resolved = ref.resolve();
|
||||
if (resolved != null) {
|
||||
ReadWriteAccessDetector.Access access = ReadWriteUtil.getReadWriteAccess(new PsiElement[]{resolved}, refElement);
|
||||
if (access == ReadWriteAccessDetector.Access.Read || access == ReadWriteAccessDetector.Access.ReadWrite) {
|
||||
if (isJustIncremented(access, refElement)) continue;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// "var++;"
|
||||
private static boolean isJustIncremented(@NotNull ReadWriteAccessDetector.Access access, @NotNull PsiElement refElement) {
|
||||
if (access == ReadWriteAccessDetector.Access.ReadWrite &&
|
||||
refElement instanceof PsiExpression &&
|
||||
refElement.getParent() instanceof PsiExpression &&
|
||||
refElement.getParent().getParent() instanceof PsiExpressionStatement) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isReferencedForWrite(@NotNull PsiVariable variable) {
|
||||
Collection<PsiReference> array;
|
||||
synchronized (myLocalRefsMap) {
|
||||
@@ -305,8 +314,13 @@ class RefCountHolder {
|
||||
if (!(refElement instanceof PsiExpression)) { // possible with incomplete code
|
||||
return true;
|
||||
}
|
||||
if (PsiUtil.isAccessedForWriting((PsiExpression)refElement)) {
|
||||
return true;
|
||||
|
||||
PsiElement resolved = ref.resolve();
|
||||
if (resolved != null) {
|
||||
ReadWriteAccessDetector.Access access = ReadWriteUtil.getReadWriteAccess(new PsiElement[]{resolved}, refElement);
|
||||
if (access == ReadWriteAccessDetector.Access.Write || access == ReadWriteAccessDetector.Access.ReadWrite) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -50,4 +50,31 @@ class PrivateClassTest {
|
||||
f(b, param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class IncrementedButNeverAccessed {
|
||||
private int <warning descr="Private field 'ffff' is assigned but never accessed">ffff</warning>;
|
||||
|
||||
void foo(int p) {
|
||||
if (p == 0) return;
|
||||
ffff++;
|
||||
}
|
||||
}
|
||||
class IncrementedAndPassed {
|
||||
private int ffff;
|
||||
|
||||
void foo(int p) {
|
||||
if (p == 0) return;
|
||||
foo(ffff++);
|
||||
}
|
||||
}
|
||||
class IncrementedAndRead{
|
||||
private int ffff;
|
||||
|
||||
void foo(int p) {
|
||||
if (p == 0) return;
|
||||
p = ffff++;
|
||||
if (p == 0) foo(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.highlighting;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ReadWriteUtil {
|
||||
public static ReadWriteAccessDetector.Access getReadWriteAccess(@NotNull PsiElement[] primaryElements, @NotNull PsiElement element) {
|
||||
for (ReadWriteAccessDetector detector : Extensions.getExtensions(ReadWriteAccessDetector.EP_NAME)) {
|
||||
if (isReadWriteAccessibleElements(primaryElements, detector)) {
|
||||
return detector.getExpressionAccess(element);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isReadWriteAccessibleElements(@NotNull PsiElement[] primaryElements, @NotNull ReadWriteAccessDetector detector) {
|
||||
for (PsiElement element : primaryElements) {
|
||||
if (!detector.isReadWriteAccessible(element)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.intellij.usages;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
@@ -119,13 +119,11 @@ public class UsageInfoToUsageConverter {
|
||||
public static Usage convert(@NotNull PsiElement[] primaryElements, @NotNull UsageInfo usageInfo) {
|
||||
PsiElement usageElement = usageInfo.getElement();
|
||||
if (usageElement != null && primaryElements.length != 0) {
|
||||
for(ReadWriteAccessDetector detector: Extensions.getExtensions(ReadWriteAccessDetector.EP_NAME)) {
|
||||
if (isReadWriteAccessibleElements(primaryElements, detector)) {
|
||||
final ReadWriteAccessDetector.Access rwAccess = detector.getExpressionAccess(usageElement);
|
||||
return new ReadWriteAccessUsageInfo2UsageAdapter(usageInfo,
|
||||
rwAccess != ReadWriteAccessDetector.Access.Write,
|
||||
rwAccess != ReadWriteAccessDetector.Access.Read);
|
||||
}
|
||||
ReadWriteAccessDetector.Access rwAccess = ReadWriteUtil.getReadWriteAccess(primaryElements, usageElement);
|
||||
if (rwAccess != null) {
|
||||
return new ReadWriteAccessUsageInfo2UsageAdapter(usageInfo,
|
||||
rwAccess != ReadWriteAccessDetector.Access.Write,
|
||||
rwAccess != ReadWriteAccessDetector.Access.Read);
|
||||
}
|
||||
}
|
||||
return new UsageInfo2UsageAdapter(usageInfo);
|
||||
@@ -140,15 +138,9 @@ public class UsageInfoToUsageConverter {
|
||||
return usages;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static Usage[] convert(@NotNull final PsiElement[] primaryElements, @NotNull UsageInfo[] usageInfos) {
|
||||
return ContainerUtil.map(usageInfos, info -> convert(primaryElements, info), new Usage[usageInfos.length]);
|
||||
}
|
||||
|
||||
private static boolean isReadWriteAccessibleElements(@NotNull PsiElement[] elements, @NotNull ReadWriteAccessDetector detector) {
|
||||
for (PsiElement element : elements) {
|
||||
if (!detector.isReadWriteAccessible(element)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user