mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: add synthetic default constructor on resolve (IDEA-376799)
GitOrigin-RevId: 71d783efd5095b0995ac1788863c8a50de759f77
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f0b97cbcd3
commit
cd8ada5c65
@@ -287,7 +287,6 @@ new.expression.diamond.not.applicable=Diamond operator is not applicable to non-
|
||||
new.expression.diamond.inference.failure={0}
|
||||
new.expression.diamond.anonymous.inner.non.private=Cannot use '<>' due to a non-private method which doesn't override or implement a method from a supertype
|
||||
new.expression.anonymous.implements.interface.with.type.arguments=Anonymous class implements interface; cannot have type arguments
|
||||
new.expression.arguments.to.default.constructor.call=Default constructor is invoked with arguments
|
||||
new.expression.unresolved.constructor=Cannot resolve constructor ''{0}''
|
||||
new.expression.type.parameter=Type parameter ''{0}'' cannot be instantiated directly
|
||||
|
||||
|
||||
+6
-30
@@ -19,7 +19,6 @@ import com.intellij.psi.controlFlow.ControlFlowUtil;
|
||||
import com.intellij.psi.impl.IncompleteModelUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ImplicitClassSearch;
|
||||
@@ -259,13 +258,11 @@ final class ExpressionChecker {
|
||||
void checkMethodCall(@NotNull PsiMethodCallExpression methodCall) {
|
||||
PsiExpressionList list = methodCall.getArgumentList();
|
||||
PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression();
|
||||
|
||||
JavaResolveResult[] results = referenceToMethod.multiResolve(true);
|
||||
JavaResolveResult resolveResult = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
PsiElement resolved = resolveResult.getElement();
|
||||
|
||||
boolean isDummy = isDummyConstructorCall(methodCall, list, referenceToMethod);
|
||||
if (isDummy) return;
|
||||
|
||||
PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
if (resolved instanceof PsiMethod psiMethod && resolveResult.isValidResult()) {
|
||||
checkUnhandledExceptions(methodCall);
|
||||
@@ -411,13 +408,12 @@ final class ExpressionChecker {
|
||||
if (!(type instanceof PsiClassType classType)) return;
|
||||
PsiClassType.ClassResolveResult typeResult = classType.resolveGenerics();
|
||||
PsiClass aClass = typeResult.getElement();
|
||||
if (aClass == null) return;
|
||||
if (aClass instanceof PsiAnonymousClass anonymousClass) {
|
||||
classType = anonymousClass.getBaseClassType();
|
||||
typeResult = classType.resolveGenerics();
|
||||
aClass = typeResult.getElement();
|
||||
if (aClass == null) return;
|
||||
}
|
||||
if (aClass == null || aClass instanceof PsiTypeParameter) return;
|
||||
|
||||
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
checkConstructorCall(typeResult, expression, classReference);
|
||||
@@ -1126,23 +1122,6 @@ final class ExpressionChecker {
|
||||
myVisitor.report(JavaErrorKinds.EXCEPTION_UNHANDLED.create(element, unhandled));
|
||||
}
|
||||
|
||||
boolean isDummyConstructorCall(@NotNull PsiMethodCallExpression methodCall,
|
||||
@NotNull PsiExpressionList list,
|
||||
@NotNull PsiReferenceExpression referenceToMethod) {
|
||||
boolean isThisOrSuper = referenceToMethod.getReferenceNameElement() instanceof PsiKeyword;
|
||||
if (isThisOrSuper) {
|
||||
// super(..) or this(..)
|
||||
if (list.isEmpty()) { // implicit ctr call
|
||||
CandidateInfo[] candidates = PsiResolveHelper.getInstance(myVisitor.project())
|
||||
.getReferencedMethodCandidates(methodCall, true);
|
||||
if (candidates.length == 1 && !candidates[0].getElement().isPhysical()) {
|
||||
return true; // dummy constructor
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkConstructorCall(@NotNull PsiClassType.ClassResolveResult typeResolveResult,
|
||||
@NotNull PsiConstructorCall constructorCall,
|
||||
@Nullable PsiJavaCodeReferenceElement classReference) {
|
||||
@@ -1163,11 +1142,8 @@ final class ExpressionChecker {
|
||||
}
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors.length == 0) {
|
||||
if (!list.isEmpty()) {
|
||||
myVisitor.report(JavaErrorKinds.NEW_EXPRESSION_ARGUMENTS_TO_DEFAULT_CONSTRUCTOR_CALL.create(constructorCall));
|
||||
}
|
||||
else if (classReference != null && aClass.hasModifierProperty(PsiModifier.PROTECTED) &&
|
||||
callingProtectedConstructorFromDerivedClass(constructorCall, aClass)) {
|
||||
if (classReference != null && aClass.hasModifierProperty(PsiModifier.PROTECTED) &&
|
||||
callingProtectedConstructorFromDerivedClass(constructorCall, aClass)) {
|
||||
myVisitor.myModifierChecker.reportAccessProblem(classReference, aClass, typeResolveResult);
|
||||
}
|
||||
else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression newExpression) {
|
||||
@@ -1175,8 +1151,8 @@ final class ExpressionChecker {
|
||||
if (typeArgumentList.getTypeArguments().length > 0) {
|
||||
myVisitor.report(JavaErrorKinds.NEW_EXPRESSION_ANONYMOUS_IMPLEMENTS_INTERFACE_WITH_TYPE_ARGUMENTS.create(typeArgumentList));
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
JavaResolveResult[] results = constructorCall.multiResolve(false);
|
||||
MethodCandidateInfo result = null;
|
||||
@@ -1216,7 +1192,7 @@ final class ExpressionChecker {
|
||||
constructorCall, new JavaErrorKinds.UnresolvedConstructorContext(aClass, results)));
|
||||
return;
|
||||
}
|
||||
if (classReference != null &&
|
||||
if (classReference != null && !constructor.isDefaultConstructor() &&
|
||||
(!result.isAccessible() ||
|
||||
constructor.hasModifierProperty(PsiModifier.PROTECTED) && callingProtectedConstructorFromDerivedClass(constructorCall, aClass))) {
|
||||
myVisitor.myModifierChecker.reportAccessProblem(classReference, constructor, result);
|
||||
|
||||
+3
-1
@@ -313,7 +313,9 @@ final class GenericsChecker {
|
||||
if (targetParametersNum == 0) {
|
||||
boolean shouldSuppress = PsiTreeUtil.getParentOfType(referenceParameterList, PsiCall.class) != null &&
|
||||
typeParameterListOwner instanceof PsiMethod psiMethod &&
|
||||
(myVisitor.sdkVersion().isAtLeast(JavaSdkVersion.JDK_1_7) || hasSuperMethodsWithTypeParams(psiMethod));
|
||||
(myVisitor.sdkVersion().isAtLeast(JavaSdkVersion.JDK_1_7)
|
||||
|| hasSuperMethodsWithTypeParams(psiMethod)
|
||||
|| psiMethod.isDefaultConstructor());
|
||||
if (!shouldSuppress) {
|
||||
if (typeParameterListOwner instanceof PsiMethod psiMethod) {
|
||||
myVisitor.report(JavaErrorKinds.TYPE_PARAMETER_ABSENT_METHOD.create(referenceParameterList, psiMethod));
|
||||
|
||||
+5
-9
@@ -827,14 +827,11 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (parent instanceof PsiMethodCallExpression methodCallExpression &&
|
||||
methodCallExpression.getMethodExpression() == expression &&
|
||||
(!result.isAccessible() || !result.isStaticsScopeCorrect())) {
|
||||
PsiExpressionList list = methodCallExpression.getArgumentList();
|
||||
if (!myExpressionChecker.isDummyConstructorCall(methodCallExpression, list, expression)) {
|
||||
myExpressionChecker.checkAmbiguousMethodCallIdentifier(results, result, methodCallExpression);
|
||||
if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
|
||||
PsiElement nameElement = expression.getReferenceNameElement();
|
||||
if (nameElement != null) {
|
||||
myExpressionChecker.checkAmbiguousMethodCallArguments(results, result, methodCallExpression);
|
||||
}
|
||||
myExpressionChecker.checkAmbiguousMethodCallIdentifier(results, result, methodCallExpression);
|
||||
if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
|
||||
PsiElement nameElement = expression.getReferenceNameElement();
|
||||
if (nameElement != null) {
|
||||
myExpressionChecker.checkAmbiguousMethodCallArguments(results, result, methodCallExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1221,7 +1218,6 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
JavaResolveResult result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
|
||||
if ((!result.isAccessible() || !result.isStaticsScopeCorrect()) &&
|
||||
!myExpressionChecker.isDummyConstructorCall(expression, list, referenceExpression) &&
|
||||
// this check is for fake expression from JspMethodCallImpl
|
||||
referenceExpression.getParent() == expression &&
|
||||
PsiTreeUtil.findChildrenOfType(expression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
|
||||
|
||||
-4
@@ -1126,10 +1126,6 @@ public final class JavaErrorKinds {
|
||||
parameterized(PsiReferenceParameterList.class, PsiDiamondType.DiamondInferenceResult.class, "new.expression.diamond.inference.failure")
|
||||
.withDescription(
|
||||
(list, inferenceResult) -> message("new.expression.diamond.inference.failure", inferenceResult.getErrorMessage()));
|
||||
public static final Simple<PsiConstructorCall> NEW_EXPRESSION_ARGUMENTS_TO_DEFAULT_CONSTRUCTOR_CALL =
|
||||
error(PsiConstructorCall.class, "new.expression.arguments.to.default.constructor.call")
|
||||
.withAnchor(call -> call.getArgumentList())
|
||||
.withNavigationShift(1);
|
||||
public static final Parameterized<PsiConstructorCall, UnresolvedConstructorContext> NEW_EXPRESSION_UNRESOLVED_CONSTRUCTOR =
|
||||
parameterized(PsiConstructorCall.class, UnresolvedConstructorContext.class, "new.expression.unresolved.constructor")
|
||||
.withAnchor(PsiCall::getArgumentList)
|
||||
|
||||
-10
@@ -536,16 +536,6 @@ public final class DefaultJavaErrorFixProvider extends AbstractJavaErrorFixProvi
|
||||
}
|
||||
return null;
|
||||
});
|
||||
fixes(NEW_EXPRESSION_ARGUMENTS_TO_DEFAULT_CONSTRUCTOR_CALL, (error, sink) -> {
|
||||
PsiConstructorCall constructorCall = error.psi();
|
||||
PsiJavaCodeReferenceElement classReference =
|
||||
constructorCall instanceof PsiNewExpression newExpression ? newExpression.getClassOrAnonymousClassReference() : null;
|
||||
if (classReference != null) {
|
||||
ConstructorParametersFixer.registerFixActions(constructorCall, sink);
|
||||
}
|
||||
QuickFixFactory.getInstance().createCreateConstructorFromUsageFixes(constructorCall).forEach(sink);
|
||||
RemoveRedundantArgumentsFix.registerIntentions(requireNonNull(constructorCall.getArgumentList()), sink);
|
||||
});
|
||||
fixes(NEW_EXPRESSION_UNRESOLVED_CONSTRUCTOR, (error, sink) -> {
|
||||
PsiConstructorCall constructorCall = error.psi();
|
||||
PsiExpressionList list = constructorCall.getArgumentList();
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
@@ -437,7 +437,7 @@ public final class HighlightFixUtil {
|
||||
}
|
||||
|
||||
PsiResolveHelper resolveHelper = PsiResolveHelper.getInstance(methodCall.getProject());
|
||||
CandidateInfo[] methodCandidates = resolveHelper.getReferencedMethodCandidates(methodCall, false);
|
||||
CandidateInfo[] methodCandidates = resolveHelper.getReferencedMethodCandidates(methodCall, true);
|
||||
IntentionAction action2 = QuickFixFactory.getInstance().createSurroundWithArrayFix(methodCall, null);
|
||||
info.accept(action2);
|
||||
|
||||
|
||||
-30
@@ -88,13 +88,6 @@ public final class RemoveRedundantArgumentsFix extends PsiUpdateModCommandAction
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerIntentions(@NotNull PsiExpressionList arguments,
|
||||
@NotNull Consumer<? super CommonIntentionAction> info) {
|
||||
if (!arguments.isEmpty()) {
|
||||
info.accept(new ForImplicitConstructorAction(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerIntention(@NotNull PsiExpressionList arguments,
|
||||
@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull JavaResolveResult candidate) {
|
||||
@@ -110,27 +103,4 @@ public final class RemoveRedundantArgumentsFix extends PsiUpdateModCommandAction
|
||||
}
|
||||
info.accept(new RemoveRedundantArgumentsFix(method, arguments, substitutor));
|
||||
}
|
||||
|
||||
private static class ForImplicitConstructorAction extends PsiUpdateModCommandAction<PsiExpressionList> {
|
||||
ForImplicitConstructorAction(@NotNull PsiExpressionList list) {
|
||||
super(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return QuickFixBundle.message("remove.redundant.arguments.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiExpressionList args) {
|
||||
return args.isEmpty() ? null : Presentation.of(getFamilyName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiExpressionList args, @NotNull ModPsiUpdater updater) {
|
||||
PsiExpression[] expressions = args.getExpressions();
|
||||
if (expressions.length == 0) return;
|
||||
args.deleteChildRange(expressions[0], expressions[expressions.length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.jvm.SpecialField;
|
||||
@@ -281,7 +281,7 @@ public final class MutationSignature {
|
||||
public static @NotNull MutationSignature fromCall(@Nullable PsiCall call) {
|
||||
if (call == null) return UNKNOWN;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method != null) {
|
||||
if (method != null && !method.isDefaultConstructor()) {
|
||||
if (SpecialField.findSpecialField(method) != null) {
|
||||
return PURE;
|
||||
}
|
||||
@@ -291,9 +291,7 @@ public final class MutationSignature {
|
||||
if (newExpression.isArrayCreation()) return PURE;
|
||||
if (newExpression.getArgumentList() == null || !newExpression.getArgumentList().isEmpty()) return UNKNOWN;
|
||||
PsiJavaCodeReferenceElement classReference = newExpression.getClassOrAnonymousClassReference();
|
||||
if (classReference == null) return UNKNOWN;
|
||||
PsiClass clazz = ObjectUtils.tryCast(classReference.resolve(), PsiClass.class);
|
||||
if (clazz == null) return UNKNOWN;
|
||||
if (classReference == null || !(classReference.resolve() instanceof PsiClass clazz)) return UNKNOWN;
|
||||
Set<PsiClass> visited = new HashSet<>();
|
||||
while (true) {
|
||||
for (PsiField field : clazz.getFields()) {
|
||||
|
||||
+9
-8
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.deprecation;
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
@@ -72,11 +72,12 @@ public final class DeprecatedApiUsageProcessor implements ApiUsageProcessor {
|
||||
@NotNull PsiClass instantiatedClass,
|
||||
@Nullable PsiMethod constructor,
|
||||
@Nullable UClass subclassDeclaration) {
|
||||
if (constructor != null) {
|
||||
if (JavaDeprecationUtils.isDeprecated(constructor, sourceNode.getSourcePsi()) && myForRemoval == isForRemovalAttributeSet(constructor)) {
|
||||
checkTargetDeprecated(sourceNode, constructor);
|
||||
return;
|
||||
}
|
||||
if (constructor != null
|
||||
&& !constructor.isDefaultConstructor()
|
||||
&& JavaDeprecationUtils.isDeprecated(constructor, sourceNode.getSourcePsi())
|
||||
&& myForRemoval == isForRemovalAttributeSet(constructor)) {
|
||||
checkTargetDeprecated(sourceNode, constructor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDefaultConstructorDeprecated(instantiatedClass)) {
|
||||
@@ -85,8 +86,8 @@ public final class DeprecatedApiUsageProcessor implements ApiUsageProcessor {
|
||||
return;
|
||||
}
|
||||
String description = JavaErrorBundle.message(myForRemoval
|
||||
? "marked.for.removal.default.constructor"
|
||||
: "deprecated.default.constructor",
|
||||
? "marked.for.removal.default.constructor"
|
||||
: "deprecated.default.constructor",
|
||||
instantiatedClass.getQualifiedName());
|
||||
|
||||
myHolder.registerProblem(elementToHighlight, description);
|
||||
|
||||
+6
-9
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.refactoring.util.duplicates;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
@@ -300,10 +300,9 @@ public final class DuplicatesFinder {
|
||||
if (type1 instanceof PsiImmediateClassType && type2 instanceof PsiImmediateClassType) {
|
||||
final PsiClass psiClass1 = ((PsiImmediateClassType)type1).resolve();
|
||||
final PsiClass psiClass2 = ((PsiImmediateClassType)type2).resolve();
|
||||
if (!(psiClass1 instanceof PsiAnonymousClass anonymousClass1 &&
|
||||
psiClass2 instanceof PsiAnonymousClass anonymousClass2 &&
|
||||
anonymousClass1.getBaseClassType().equals(anonymousClass2.getBaseClassType())
|
||||
)) {
|
||||
if (!(psiClass1 instanceof PsiAnonymousClass anonymousClass1) ||
|
||||
!(psiClass2 instanceof PsiAnonymousClass anonymousClass2) ||
|
||||
!anonymousClass1.getBaseClassType().equals(anonymousClass2.getBaseClassType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -548,11 +547,9 @@ public final class DuplicatesFinder {
|
||||
final PsiMethod constructor2 = candidate.resolveConstructor();
|
||||
if (constructor1 != null && constructor2 != null) {
|
||||
if (!pattern.getManager().areElementsEquivalent(constructor1, constructor2)) return false;
|
||||
if (pattern.getAnonymousClass() == null && candidate.getAnonymousClass() == null) return true;
|
||||
}
|
||||
else {
|
||||
if (!canTypesBeEquivalent(type1, type2)) return false;
|
||||
}
|
||||
return true;
|
||||
return canTypesBeEquivalent(type1, type2);
|
||||
}
|
||||
|
||||
private static boolean matchObjectAccess(@NotNull PsiClassObjectAccessExpression pattern,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2021 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2025 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -343,7 +343,7 @@ public final class SideEffectChecker {
|
||||
if (qualifiedName == null) return ThreeState.UNSURE;
|
||||
if (ourSideEffectFreeClasses.contains(qualifiedName)) return ThreeState.NO;
|
||||
PsiMethod method = newExpression.resolveConstructor();
|
||||
if (method != null) {
|
||||
if (method != null && !method.isDefaultConstructor()) {
|
||||
MutationSignature signature = MutationSignature.fromMethod(method);
|
||||
if (signature.isPure()) {
|
||||
return ThreeState.NO;
|
||||
@@ -364,7 +364,7 @@ public final class SideEffectChecker {
|
||||
return ThreeState.NO;
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
if (method == null || method.isDefaultConstructor()) {
|
||||
PsiClass superClass = aClass.getSuperClass();
|
||||
if (superClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
|
||||
for (PsiClassInitializer initializer : aClass.getInitializers()) {
|
||||
|
||||
+7
-4
@@ -68,7 +68,7 @@ class InlineToAnonymousConstructorProcessor {
|
||||
JavaResolveResult classResolveResult = myNewExpression.getClassReference().advancedResolve(false);
|
||||
JavaResolveResult methodResolveResult = myNewExpression.resolveMethodGenerics();
|
||||
final PsiElement element = methodResolveResult.getElement();
|
||||
myConstructor = element != null ? (PsiMethod) element.getNavigationElement() : null;
|
||||
myConstructor = (element == null || element instanceof SyntheticElement) ? null : (PsiMethod)element.getNavigationElement();
|
||||
myConstructorArguments = initConstructorArguments();
|
||||
|
||||
PsiSubstitutor classResolveSubstitutor = classResolveResult.getSubstitutor();
|
||||
@@ -116,7 +116,8 @@ class InlineToAnonymousConstructorProcessor {
|
||||
for (PsiElement child : classCopy.getChildren()) {
|
||||
if ((child instanceof PsiMethod method && !method.isConstructor()) ||
|
||||
child instanceof PsiClassInitializer || child instanceof PsiClass) {
|
||||
if (!myFieldInitializers.isEmpty() || !myLocalsForParameters.isEmpty() || classResolveSubstitutor != PsiSubstitutor.EMPTY || outerClassLocal != null) {
|
||||
if (!myFieldInitializers.isEmpty() || !myLocalsForParameters.isEmpty()
|
||||
|| classResolveSubstitutor != PsiSubstitutor.EMPTY || outerClassLocal != null) {
|
||||
replaceReferences((PsiMember) child, substitutedParameters, outerClassLocal);
|
||||
}
|
||||
anonymousClass.addBefore(child, token);
|
||||
@@ -138,11 +139,13 @@ class InlineToAnonymousConstructorProcessor {
|
||||
anonymousClass.deleteChildRange(anonymousClass.getLBrace(), anonymousClass.getRBrace());
|
||||
}
|
||||
PsiNewExpression superNewExpression = (PsiNewExpression) myNewExpression.replace(superNewExpressionTemplate);
|
||||
superNewExpression = (PsiNewExpression)ChangeContextUtil.decodeContextInfo(superNewExpression, superNewExpression.getAnonymousClass(), null);
|
||||
superNewExpression = (PsiNewExpression)
|
||||
ChangeContextUtil.decodeContextInfo(superNewExpression, superNewExpression.getAnonymousClass(), null);
|
||||
PsiAnonymousClass newExpressionAnonymousClass = superNewExpression.getAnonymousClass();
|
||||
if (newExpressionAnonymousClass != null &&
|
||||
AnonymousCanBeLambdaInspection.isLambdaForm(newExpressionAnonymousClass, false, Collections.emptySet())) {
|
||||
PsiExpression lambda = AnonymousCanBeLambdaInspection.replaceAnonymousWithLambda(superNewExpression, newExpressionAnonymousClass.getBaseClassType());
|
||||
PsiExpression lambda =
|
||||
AnonymousCanBeLambdaInspection.replaceAnonymousWithLambda(superNewExpression, newExpressionAnonymousClass.getBaseClassType());
|
||||
JavaCodeStyleManager.getInstance(newExpressionAnonymousClass.getProject()).shortenClassReferences(superNewExpression.replace(lambda));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiExtensionMethod;
|
||||
import com.intellij.psi.impl.light.LightDefaultConstructor;
|
||||
import com.intellij.psi.impl.light.LightRecordCanonicalConstructor;
|
||||
import com.intellij.psi.impl.light.LightRecordMember;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
@@ -161,6 +162,9 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
if (refElement instanceof LightRecordCanonicalConstructor) {
|
||||
return ((LightRecordCanonicalConstructor)refElement).getContainingClass();
|
||||
}
|
||||
if (refElement instanceof LightDefaultConstructor def) {
|
||||
return def.getContainingClass();
|
||||
}
|
||||
}
|
||||
return super.adjustReferenceOrReferencedElement(file, editor, offset, flags, refElement);
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ig.dependency;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
@@ -138,6 +138,7 @@ public final class SuspiciousPackagePrivateAccessInspection extends AbstractBase
|
||||
}
|
||||
|
||||
private void checkPackageLocalAccess(@NotNull UElement sourceNode, PsiJvmMember targetElement, final String accessType) {
|
||||
if (targetElement instanceof SyntheticElement) return;
|
||||
PsiElement sourcePsi = sourceNode.getSourcePsi();
|
||||
if (sourcePsi != null) {
|
||||
SuspiciousPackagePrivateAccess suspiciousAccess = verifyPackagePrivateAccess(sourcePsi, targetElement);
|
||||
@@ -164,6 +165,7 @@ public final class SuspiciousPackagePrivateAccessInspection extends AbstractBase
|
||||
}
|
||||
|
||||
private void checkOverridePackageLocal(@NotNull UMethod sourceNode, @NotNull PsiJvmMember targetElement) {
|
||||
if (targetElement instanceof SyntheticElement) return;
|
||||
PsiElement sourcePsi = sourceNode.getSourcePsi();
|
||||
PsiElement nameIdentifier = UElementKt.getSourcePsiElement(sourceNode.getUastAnchor());
|
||||
if (sourcePsi != null && nameIdentifier != null && targetElement.hasModifier(JvmModifier.PACKAGE_LOCAL)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.lang.jvm.JvmMethod;
|
||||
@@ -87,6 +87,18 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie
|
||||
@Override
|
||||
boolean isConstructor();
|
||||
|
||||
/**
|
||||
* Checks if the method is a default constructor.
|
||||
* When a class contains no explicit constructor declarations, a default constructor is implicitly declared.
|
||||
*
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-8.html#jls-8.8.9">JLS 8.8.9 Default Constructor</a>
|
||||
* @see #isConstructor()
|
||||
* @return true if the method is a default constructor, false otherwise
|
||||
*/
|
||||
default boolean isDefaultConstructor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the method accepts a variable number of arguments.
|
||||
* The method is considered to be a variable arity method only if its last
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.light;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.ElementPresentationUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.ui.IconManager;
|
||||
import com.intellij.ui.PlatformIcons;
|
||||
import com.intellij.ui.icons.RowIcon;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.VisibilityIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/// @see <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-8.html#jls-8.8.9">JLS 8.8.9 Default Constructor</a>
|
||||
public class LightDefaultConstructor extends LightMethod implements SyntheticElement {
|
||||
|
||||
private static final Key<PsiMethod> DEFAULT_CONSTRUCTOR = new Key<>("default_constructor");
|
||||
|
||||
private LightDefaultConstructor(@NotNull PsiMethod method, @NotNull PsiClass containingClass) {
|
||||
super(method.getManager(), method, containingClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return getContainingClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiIdentifier getNameIdentifier() {
|
||||
return getContainingClass().getNameIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
return getNavigationElement().getTextOffset();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getNavigationElement() {
|
||||
return getContainingClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return getContainingClass().getContainingFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getElementIcon(int flags) {
|
||||
Icon icon = IconManager.getInstance().getPlatformIcon(PlatformIcons.Method);
|
||||
final RowIcon baseIcon = IconManager.getInstance().createLayeredIcon(this, icon, ElementPresentationUtil.getFlags(this, false));
|
||||
if (BitUtil.isSet(flags, ICON_FLAG_VISIBILITY)) {
|
||||
VisibilityIcons.setVisibilityIcon(getContainingClass().getModifierList(), baseIcon);
|
||||
}
|
||||
return baseIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultConstructor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LightDefaultConstructor:" + getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod create(PsiClass aClass) {
|
||||
PsiMethod constructor = aClass.getUserData(DEFAULT_CONSTRUCTOR);
|
||||
if (constructor != null) return constructor;
|
||||
|
||||
if (aClass.isInterface()
|
||||
|| aClass.isRecord()
|
||||
|| aClass instanceof PsiCompiledElement // default constructor is physically present in compiled classes already
|
||||
|| aClass instanceof PsiAnonymousClass
|
||||
|| aClass instanceof PsiImplicitClass
|
||||
|| aClass instanceof PsiTypeParameter
|
||||
|| aClass.getClass().getSimpleName().contains("Decompiled") // Hack because Kotlin library classes are not PsiCompiledElements
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
String className = aClass.getName();
|
||||
if (className == null || aClass.getConstructors().length > 0) return null;
|
||||
PsiMethod nonPhysical = JavaPsiFacade.getElementFactory(aClass.getProject()).createConstructor(className, aClass);
|
||||
PsiModifierList classModifierList = aClass.getModifierList();
|
||||
if (classModifierList != null) {
|
||||
String modifier = PsiUtil.getAccessModifier(PsiUtil.getAccessLevel(classModifierList));
|
||||
nonPhysical.getModifierList().setModifierProperty(modifier, true);
|
||||
}
|
||||
LightDefaultConstructor defaultConstructor = new LightDefaultConstructor(nonPhysical, aClass);
|
||||
aClass.putUserData(DEFAULT_CONSTRUCTOR, defaultConstructor);
|
||||
return defaultConstructor;
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -7,6 +7,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaPsiImplementationHelper;
|
||||
import com.intellij.psi.impl.light.LightDefaultConstructor;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
@@ -67,9 +68,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
|
||||
for (PsiMethod constructor : aClass.getConstructors()) {
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (!processor.execute(constructor, state)) break;
|
||||
}
|
||||
if (constructors.length == 0) {
|
||||
PsiMethod defaultConstructor = LightDefaultConstructor.create(aClass);
|
||||
if (defaultConstructor != null) processor.execute(defaultConstructor, state);
|
||||
}
|
||||
|
||||
return processor.getResult();
|
||||
}
|
||||
|
||||
+1
-1
@@ -306,7 +306,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)getParent();
|
||||
MethodResolverProcessor processor = new MethodResolverProcessor(methodCall, containingFile);
|
||||
try {
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false);
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, methodCall, true);
|
||||
}
|
||||
catch (MethodProcessorSetupFailedException e) {
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
|
||||
+7
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.scope.processor;
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -87,7 +87,7 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
|
||||
}
|
||||
|
||||
protected @NotNull MethodCandidateInfo createCandidateInfo(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor,
|
||||
final boolean staticProblem, final boolean accessible, final boolean varargs) {
|
||||
boolean staticProblem, boolean accessible, boolean varargs) {
|
||||
return new VarargsAwareMethodCandidateInfo(method, substitutor, accessible, staticProblem, getArgumentList(), myCurrentFileContext,
|
||||
getTypeArguments(), getLanguageLevel(), varargs);
|
||||
}
|
||||
@@ -162,4 +162,9 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
|
||||
return myVarargs;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceAddResult(@NotNull PsiMethod method) {
|
||||
add(createCandidateInfo(method, PsiSubstitutor.EMPTY, false, true, method.isVarArgs()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.scope.util;
|
||||
|
||||
import com.intellij.lang.jvm.types.JvmReferenceType;
|
||||
@@ -9,6 +8,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.impl.light.LightDefaultConstructor;
|
||||
import com.intellij.psi.impl.source.PsiClassImpl;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
@@ -21,14 +21,12 @@ import com.intellij.psi.scope.processor.MethodsProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PsiScopesUtil {
|
||||
private static final Logger LOG = Logger.getInstance(PsiScopesUtil.class);
|
||||
@@ -36,16 +34,14 @@ public final class PsiScopesUtil {
|
||||
private PsiScopesUtil() {
|
||||
}
|
||||
|
||||
public static boolean treeWalkUp(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull PsiElement entrance,
|
||||
@Nullable PsiElement maxScope) {
|
||||
public static boolean treeWalkUp(@NotNull PsiScopeProcessor processor, @NotNull PsiElement entrance, @Nullable PsiElement maxScope) {
|
||||
return treeWalkUp(processor, entrance, maxScope, ResolveState.initial());
|
||||
}
|
||||
|
||||
public static boolean treeWalkUp(final @NotNull PsiScopeProcessor processor,
|
||||
final @NotNull PsiElement entrance,
|
||||
final @Nullable PsiElement maxScope,
|
||||
final @NotNull ResolveState state) {
|
||||
public static boolean treeWalkUp(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull PsiElement entrance,
|
||||
@Nullable PsiElement maxScope,
|
||||
@NotNull ResolveState state) {
|
||||
if (!entrance.isValid()) {
|
||||
LOG.error(new PsiInvalidElementAccessException(entrance));
|
||||
}
|
||||
@@ -215,7 +211,7 @@ public final class PsiScopesUtil {
|
||||
public static void setupAndRunProcessor(@NotNull MethodsProcessor processor,
|
||||
@NotNull PsiCallExpression call,
|
||||
boolean dummyImplicitConstructor)
|
||||
throws MethodProcessorSetupFailedException {
|
||||
throws MethodProcessorSetupFailedException {
|
||||
if (call instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)call;
|
||||
final PsiJavaCodeReferenceElement ref = methodCall.getMethodExpression();
|
||||
@@ -240,7 +236,7 @@ public final class PsiScopesUtil {
|
||||
aClass.processDeclarations(processor, ResolveState.initial(), null, call);
|
||||
|
||||
if (dummyImplicitConstructor) {
|
||||
processDummyConstructor(processor, aClass);
|
||||
processDefaultConstructor(processor, aClass);
|
||||
}
|
||||
}
|
||||
else if (keyword.getTokenType() == JavaTokenType.SUPER_KEYWORD) {
|
||||
@@ -279,7 +275,7 @@ public final class PsiScopesUtil {
|
||||
if (!processor.execute(constructor, state)) return;
|
||||
}
|
||||
|
||||
if (dummyImplicitConstructor) processDummyConstructor(processor, superClass);
|
||||
if (dummyImplicitConstructor) processDefaultConstructor(processor, superClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -370,7 +366,7 @@ public final class PsiScopesUtil {
|
||||
aClass.processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, result.getSubstitutor()), null, call);
|
||||
|
||||
if (dummyImplicitConstructor) {
|
||||
processDummyConstructor(processor, aClass);
|
||||
processDefaultConstructor(processor, aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,8 +421,8 @@ public final class PsiScopesUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean processQualifierType(final @NotNull PsiType type,
|
||||
final MethodsProcessor processor,
|
||||
private static boolean processQualifierType(@NotNull PsiType type,
|
||||
MethodsProcessor processor,
|
||||
PsiManager manager,
|
||||
PsiMethodCallExpression call) throws MethodProcessorSetupFailedException {
|
||||
PsiUtil.ensureValidType(type);
|
||||
@@ -479,23 +475,11 @@ public final class PsiScopesUtil {
|
||||
return resolve.processDeclarations(processor, state, methodCall, methodCall);
|
||||
}
|
||||
|
||||
private static void processDummyConstructor(MethodsProcessor processor, PsiClass aClass) {
|
||||
if (aClass instanceof PsiAnonymousClass) return;
|
||||
try {
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors.length != 0) {
|
||||
return;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject());
|
||||
final PsiMethod dummyConstructor = factory.createConstructor();
|
||||
PsiIdentifier nameIdentifier = aClass.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
Objects.requireNonNull(dummyConstructor.getNameIdentifier()).replace(nameIdentifier);
|
||||
}
|
||||
processor.forceAddResult(dummyConstructor);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
private static void processDefaultConstructor(MethodsProcessor processor, PsiClass aClass) {
|
||||
if (aClass.getConstructors().length != 0) {
|
||||
return;
|
||||
}
|
||||
PsiMethod defaultConstructor = LightDefaultConstructor.create(aClass);
|
||||
if (defaultConstructor != null) processor.forceAddResult(defaultConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class WrongNumberOfArguments {
|
||||
WrongNumberOfArguments() {
|
||||
super<error descr="Expected no arguments but found 1">(1)</error>;
|
||||
}
|
||||
|
||||
void fun1(String str, Consumer<String> onFinish) { }
|
||||
void getStr(String asd) { }
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant arguments" "true-preview"
|
||||
// "Remove redundant argument to call 'A()'" "true-preview"
|
||||
class A {
|
||||
private void method() {
|
||||
new A();
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant arguments" "true-preview"
|
||||
// "Remove redundant argument to call 'A()'" "true-preview"
|
||||
class A {
|
||||
private void method() {
|
||||
new A("<caret>");
|
||||
|
||||
+2
-1
@@ -2,8 +2,9 @@
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
int k;
|
||||
boolean k = new File("1.tmp").delete();
|
||||
private int run() {
|
||||
new a();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
int k;
|
||||
boolean k = new File("1.tmp").delete();
|
||||
private int run() {
|
||||
Object <caret>oo = (Object) new a();
|
||||
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
public class UtilityClassWithDefaultConstructor {
|
||||
|
||||
public static int util() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,19 @@ public class CatchTypeReference {
|
||||
|
||||
private static class TypeReference<T> {
|
||||
}
|
||||
}
|
||||
class CatchTypeReference2 {
|
||||
void foo(int i) {
|
||||
TypeReference<?> targetType = switch (i) {
|
||||
case 2231 -> new TypeReference<List<Boolean>>() {
|
||||
};
|
||||
default -> new TypeReference<List<String>>() {
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
private static class TypeReference<T> {
|
||||
private TypeReference() {
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
+3
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight.navigation;
|
||||
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
@@ -9,8 +9,8 @@ public class GotoEnumConstructorTest extends LightJavaCodeInsightFixtureTestCase
|
||||
|
||||
public void testGotoDeclarationOnEnumConstantDoesntNavigateToEnumClass() {
|
||||
doTest(
|
||||
"enum A { G<caret>; }",
|
||||
"enum A { G<caret>; }"
|
||||
"enum A { G<caret>G; }",
|
||||
"enum A { G<caret>G; }"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.psi.resolve;
|
||||
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
@@ -209,6 +209,27 @@ public class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
|
||||
assertNotNull(file.getStub());
|
||||
}
|
||||
|
||||
public void testLibraryClassWithoutConstructors() {
|
||||
VirtualFile lib =
|
||||
LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/libResolve/classWithoutConstructors");
|
||||
|
||||
PsiTestUtil.addLibrary(getModule(), "lib", lib.getPath(), new String[] {"/test.jar!/"}, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
myFixture.configureByText("p/Generous.java", """
|
||||
package p;
|
||||
|
||||
import com.pack.HiddenConstructor;
|
||||
import com.pack.ValueClass;
|
||||
|
||||
class Generous {
|
||||
static void main(){
|
||||
HiddenConstructor h = new HiddenConstructor<error descr="Cannot resolve constructor 'HiddenConstructor()'">()</error>;
|
||||
ValueClass v = new ValueClass<error descr="Cannot resolve constructor 'ValueClass()'">()</error>;
|
||||
}
|
||||
}
|
||||
""");
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
public void testDirectoryWithClassFilesInsideProjectContent() {
|
||||
String testData = PathManagerEx.getTestDataPath() + "/codeInsight/interJarDependencies";
|
||||
myFixture.setTestDataPath(testData);
|
||||
|
||||
+4
-7
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ig.classlayout;
|
||||
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
@@ -23,10 +23,7 @@ public class UtilityClassWithPublicConstructorInspectionTest extends LightJavaCo
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testUtilityClassWithPublicConstructorInspection() {
|
||||
doTest();
|
||||
}
|
||||
public void testUtilityClassWithInheritor() {
|
||||
doTest();
|
||||
}
|
||||
public void testUtilityClassWithPublicConstructorInspection() { doTest(); }
|
||||
public void testUtilityClassWithInheritor() { doTest(); }
|
||||
public void testUtilityClassWithDefaultConstructor() { doTest(); }
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ig.jdk;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
@@ -36,17 +34,17 @@ public class ForwardCompatibilityInspectionTest extends LightJavaInspectionTestC
|
||||
}
|
||||
|
||||
public void testAssert() {
|
||||
withLevel(LanguageLevel.JDK_1_3, this::doTest);
|
||||
IdeaTestUtil.withLevel(myFixture.getModule(), LanguageLevel.JDK_1_3, this::doTest);
|
||||
}
|
||||
|
||||
public void testEnum() {
|
||||
withLevel(LanguageLevel.JDK_1_3, this::doTest);
|
||||
IdeaTestUtil.withLevel(myFixture.getModule(), LanguageLevel.JDK_1_3, this::doTest);
|
||||
}
|
||||
|
||||
public void testUnqualifiedYield() { doTest(); }
|
||||
|
||||
public void testQualifiedYieldWithUnexpectedToken() {
|
||||
withLevel(LanguageLevel.JDK_1_8, () -> {
|
||||
IdeaTestUtil.withLevel(myFixture.getModule(), LanguageLevel.JDK_1_8, () -> {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
List<HighlightInfo> list = ContainerUtil.filter(myFixture.doHighlighting(HighlightSeverity.WARNING), it -> it.getSeverity().equals(HighlightSeverity.WARNING));
|
||||
assertEquals(1, list.size());
|
||||
@@ -65,24 +63,12 @@ public class ForwardCompatibilityInspectionTest extends LightJavaInspectionTestC
|
||||
|
||||
public void testRestrictedKeywordWarning() { doTest(); }
|
||||
|
||||
public void testLoneSemicolon() { withLevel(LanguageLevel.JDK_20, this::doTest); }
|
||||
public void testLoneSemicolon() { IdeaTestUtil.withLevel(myFixture.getModule(), LanguageLevel.JDK_20, this::doTest); }
|
||||
|
||||
public void testModuleInfoWarning() {
|
||||
withLevel(LanguageLevel.JDK_1_9, () -> {
|
||||
IdeaTestUtil.withLevel(myFixture.getModule(), LanguageLevel.JDK_1_9, () -> {
|
||||
myFixture.configureByFile("module-info.java");
|
||||
myFixture.testHighlighting(true, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
public void withLevel(LanguageLevel languageLevel, Runnable runnable) {
|
||||
Module module = getModule();
|
||||
LanguageLevel prev = LanguageLevelUtil.getCustomLanguageLevel(module);
|
||||
IdeaTestUtil.setModuleLanguageLevel(module, languageLevel);
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
finally {
|
||||
IdeaTestUtil.setModuleLanguageLevel(module, prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-28
@@ -13,7 +13,6 @@ import de.plushnikov.intellij.plugin.problem.LombokProblemInstance;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||
import de.plushnikov.intellij.plugin.processor.Processor;
|
||||
import de.plushnikov.intellij.plugin.processor.ValProcessor;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
|
||||
import de.plushnikov.intellij.plugin.quickfix.PsiQuickFixFactory;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -112,32 +111,5 @@ public final class LombokInspection extends LombokJavaInspectionBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check MethodCallExpressions for calls for default (argument less) constructor
|
||||
* Produce an error if resolved constructor method is build by lombok and contains some arguments
|
||||
*/
|
||||
@Override
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression methodCall) {
|
||||
super.visitMethodCallExpression(methodCall);
|
||||
|
||||
PsiExpressionList list = methodCall.getArgumentList();
|
||||
PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression();
|
||||
|
||||
boolean isThisOrSuper = referenceToMethod.getReferenceNameElement() instanceof PsiKeyword;
|
||||
final int parameterCount = list.getExpressions().length;
|
||||
if (isThisOrSuper && parameterCount == 0) {
|
||||
|
||||
JavaResolveResult[] results = referenceToMethod.multiResolve(true);
|
||||
JavaResolveResult resolveResult = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
PsiElement resolved = resolveResult.getElement();
|
||||
|
||||
if (resolved instanceof LombokLightMethodBuilder &&
|
||||
((LombokLightMethodBuilder)resolved).getParameterList().getParameters().length != 0) {
|
||||
holder.registerProblem(methodCall, LombokBundle.message("inspection.message.default.constructor.doesn.t.exist"),
|
||||
ProblemHighlightType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ dialog.message.logger.field.s.not.private.sfinal.field.named.s.refactor.anyway=L
|
||||
dialog.title.attention=Attention!
|
||||
dialog.message.this.element.cannot.be.renamed=This element cannot be renamed.
|
||||
inspection.message.lombok.annotation.deprecated.not.supported=Lombok''s annotation ''{0}'' is deprecated and not supported by Lombok plugin anymore. Use ''{1}'' instead.
|
||||
inspection.message.default.constructor.doesn.t.exist=Default constructor doesn't exist
|
||||
inspection.message.slf4j.logger.defined.explicitly=Slf4j Logger is defined explicitly. Use Lombok @Slf4j annotation instead.
|
||||
intention.name.replace.with.lombok=Replace with Lombok
|
||||
color.settings.comment=Comment
|
||||
|
||||
@@ -9,7 +9,7 @@ public class ClassWithData {
|
||||
|
||||
public static class B extends A {
|
||||
public B() {
|
||||
<error descr="Default constructor doesn't exist">super()</error>;
|
||||
super<error descr="Expected 2 arguments but found 0">()</error>;
|
||||
}
|
||||
|
||||
public B(int i) {
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ public class ClassWithLombokConstructor {
|
||||
|
||||
public static class B extends A {
|
||||
public B() {
|
||||
<error descr="Default constructor doesn't exist">super()</error>;
|
||||
super<error descr="Expected 2 arguments but found 0">()</error>;
|
||||
}
|
||||
|
||||
public B(int i) {
|
||||
|
||||
@@ -212,16 +212,7 @@ class JavaConstructorUCallExpression(
|
||||
get() = null
|
||||
|
||||
override fun resolve(): PsiMethod? = sourcePsi.resolveMethod()
|
||||
override fun multiResolve(): Iterable<ResolveResult> {
|
||||
val methodResolve = sourcePsi.resolveMethodGenerics()
|
||||
if (methodResolve != JavaResolveResult.EMPTY) {
|
||||
// if there is a non-default constructor
|
||||
return listOf<ResolveResult>(methodResolve)
|
||||
}
|
||||
// unable to resolve constructor method - resolve to class
|
||||
val classResolve = sourcePsi.classReference?.multiResolve(false) ?: emptyArray()
|
||||
return classResolve.asIterable()
|
||||
}
|
||||
override fun multiResolve() = sourcePsi.multiResolve(false).asIterable()
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
@@ -14,7 +14,7 @@ UClass (name = A) -> USimpleNameReferenceExpression (identifier = B) -> PsiClass
|
||||
UField (name = a) -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:A: null
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = A) -> PsiClass:A: A
|
||||
UTypeReferenceExpression (name = C) -> USimpleNameReferenceExpression (identifier = C) -> PsiClass:C: C
|
||||
UField (name = c) -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> null: null
|
||||
UField (name = c) -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> LightDefaultConstructor:C: null
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = C) -> PsiClass:C: C
|
||||
UTypeReferenceExpression (name = A) -> USimpleNameReferenceExpression (identifier = A) -> PsiClass:A: A
|
||||
UReturnExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:A: null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
UMethod (name = test) -> UTypeReferenceExpression (name = void) -> [] ~= []
|
||||
UMethod (name = test) -> UBlockExpression -> [] ~= []
|
||||
UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> [M] PsiClassImpl ~= []
|
||||
UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> [M] PsiClassImpl ~= []
|
||||
UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> [M] LightDefaultConstructor ~= LightDefaultConstructor:Foo
|
||||
UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> [M] LightDefaultConstructor ~= LightDefaultConstructor:Foo
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = Foo) -> [M] PsiClassImpl ~= PsiClass:Foo
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.
|
||||
*/
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.uast.test.java
|
||||
|
||||
import com.intellij.psi.*
|
||||
@@ -190,7 +176,7 @@ class JavaUastApiTest : AbstractJavaUastTest() {
|
||||
fun testDefaultConstructorRef() = doTest("Simple/ComplexCalls.java") { _, file ->
|
||||
val call = file.findElementByTextFromPsi<UCallExpression>("new C()")
|
||||
TestCase.assertEquals(UastCallKind.CONSTRUCTOR_CALL, call.kind)
|
||||
TestCase.assertEquals(null, call.resolve())
|
||||
TestCase.assertEquals("C", call.resolve()?.name)
|
||||
TestCase.assertEquals("C", (call.classReference?.resolve() as? PsiClass)?.qualifiedName)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user