Switch to new extension method syntax

This commit is contained in:
Roman Shevchenko
2012-11-10 21:36:44 +01:00
parent fa15325a23
commit 39d9fd7235
37 changed files with 296 additions and 314 deletions
@@ -848,13 +848,18 @@ public class HighlightMethodUtil {
@Nullable
static HighlightInfo checkMethodCanHaveBody(PsiMethod method) {
if (method.getBody() == null) return null;
PsiClass aClass = method.getContainingClass();
boolean hasBody = method.getBody() == null;
boolean isInterface = aClass != null && aClass.isInterface();
boolean isExtension = method.isExtensionMethod();
boolean isExtension = method.hasModifierProperty(PsiModifier.DEFAULT);
String message = null;
if (isInterface) {
if (hasBody) {
if (isExtension) {
message = JavaErrorMessages.message("extension.method.should.have.a.body");
}
}
else if (isInterface) {
if (!isExtension) {
message = JavaErrorMessages.message("interface.methods.cannot.have.body");
}
@@ -875,10 +880,11 @@ public class HighlightMethodUtil {
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message);
QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method));
if (hasBody) {
QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method));
}
if (method.hasModifierProperty(PsiModifier.ABSTRACT) && isInterface) {
IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false);
QuickFixAction.registerQuickFixAction(info, fix);
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false));
}
return info;
}
@@ -30,7 +30,10 @@ import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -51,7 +54,6 @@ import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.XmlStringUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -62,6 +64,7 @@ import java.util.*;
import static com.intellij.codeInsight.daemon.JavaHighlightingFilter.Kind;
import static com.intellij.codeInsight.daemon.JavaHighlightingFilter.suppressed;
import static com.intellij.util.containers.ContainerUtil.newTroveSet;
/**
* @author cdr
@@ -69,6 +72,7 @@ import static com.intellij.codeInsight.daemon.JavaHighlightingFilter.suppressed;
*/
public class HighlightUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil");
@NotNull private static final Map<String, Set<String>> ourInterfaceIncompatibleModifiers;
@NotNull private static final Map<String, Set<String>> ourMethodIncompatibleModifiers;
@NotNull private static final Map<String, Set<String>> ourFieldIncompatibleModifiers;
@@ -84,134 +88,54 @@ public class HighlightUtil {
static {
ourClassIncompatibleModifiers = new THashMap<String, Set<String>>(8);
Set<String> modifiers = new THashSet<String>(1);
modifiers.add(PsiModifier.FINAL);
ourClassIncompatibleModifiers.put(PsiModifier.ABSTRACT, modifiers);
modifiers = new THashSet<String>(1);
modifiers.add(PsiModifier.ABSTRACT);
ourClassIncompatibleModifiers.put(PsiModifier.FINAL, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourClassIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourClassIncompatibleModifiers.put(PsiModifier.PRIVATE, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PROTECTED);
ourClassIncompatibleModifiers.put(PsiModifier.PUBLIC, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PRIVATE);
ourClassIncompatibleModifiers.put(PsiModifier.PROTECTED, modifiers);
ourClassIncompatibleModifiers.put(PsiModifier.ABSTRACT, newTroveSet(PsiModifier.FINAL));
ourClassIncompatibleModifiers.put(PsiModifier.FINAL, newTroveSet(PsiModifier.ABSTRACT));
ourClassIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, newTroveSet(PsiModifier.PRIVATE, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourClassIncompatibleModifiers.put(PsiModifier.PRIVATE, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourClassIncompatibleModifiers.put(PsiModifier.PUBLIC, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE, PsiModifier.PROTECTED));
ourClassIncompatibleModifiers.put(PsiModifier.PROTECTED, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PRIVATE));
ourClassIncompatibleModifiers.put(PsiModifier.STRICTFP, Collections.<String>emptySet());
ourClassIncompatibleModifiers.put(PsiModifier.STATIC, Collections.<String>emptySet());
ourInterfaceIncompatibleModifiers = new THashMap<String, Set<String>>(7);
ourInterfaceIncompatibleModifiers.put(PsiModifier.ABSTRACT, Collections.<String>emptySet());
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourInterfaceIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourInterfaceIncompatibleModifiers.put(PsiModifier.PRIVATE, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PROTECTED);
ourInterfaceIncompatibleModifiers.put(PsiModifier.PUBLIC, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
ourInterfaceIncompatibleModifiers.put(PsiModifier.PROTECTED, modifiers);
ourInterfaceIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, newTroveSet(PsiModifier.PRIVATE, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourInterfaceIncompatibleModifiers.put(PsiModifier.PRIVATE, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourInterfaceIncompatibleModifiers.put(PsiModifier.PUBLIC, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE, PsiModifier.PROTECTED));
ourInterfaceIncompatibleModifiers.put(PsiModifier.PROTECTED, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PRIVATE));
ourInterfaceIncompatibleModifiers.put(PsiModifier.STRICTFP, Collections.<String>emptySet());
ourInterfaceIncompatibleModifiers.put(PsiModifier.STATIC, Collections.<String>emptySet());
ourMethodIncompatibleModifiers = new THashMap<String, Set<String>>(10);
modifiers = new THashSet<String>(6);
modifiers.addAll(Arrays.asList(PsiModifier.NATIVE, PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PRIVATE, PsiModifier.STRICTFP,
PsiModifier.SYNCHRONIZED));
ourMethodIncompatibleModifiers.put(PsiModifier.ABSTRACT, modifiers);
modifiers = new THashSet<String>(2);
modifiers.add(PsiModifier.ABSTRACT);
modifiers.add(PsiModifier.STRICTFP);
ourMethodIncompatibleModifiers.put(PsiModifier.NATIVE, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourMethodIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, modifiers);
modifiers = new THashSet<String>(4);
modifiers.add(PsiModifier.ABSTRACT);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourMethodIncompatibleModifiers.put(PsiModifier.PRIVATE, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PROTECTED);
ourMethodIncompatibleModifiers.put(PsiModifier.PUBLIC, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PRIVATE);
ourMethodIncompatibleModifiers.put(PsiModifier.PROTECTED, modifiers);
modifiers = new THashSet<String>(1);
modifiers.add(PsiModifier.ABSTRACT);
ourMethodIncompatibleModifiers.put(PsiModifier.STATIC, modifiers);
ourMethodIncompatibleModifiers.put(PsiModifier.SYNCHRONIZED, modifiers);
ourMethodIncompatibleModifiers.put(PsiModifier.STRICTFP, modifiers);
ourMethodIncompatibleModifiers.put(PsiModifier.FINAL, modifiers);
ourMethodIncompatibleModifiers = new THashMap<String, Set<String>>(11);
ourMethodIncompatibleModifiers.put(PsiModifier.ABSTRACT, newTroveSet(PsiModifier.NATIVE, PsiModifier.STATIC, PsiModifier.FINAL,
PsiModifier.PRIVATE, PsiModifier.STRICTFP, PsiModifier.SYNCHRONIZED,
PsiModifier.DEFAULT));
ourMethodIncompatibleModifiers.put(PsiModifier.NATIVE, newTroveSet(PsiModifier.ABSTRACT, PsiModifier.STRICTFP));
ourMethodIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, newTroveSet(PsiModifier.PRIVATE, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourMethodIncompatibleModifiers.put(PsiModifier.PRIVATE, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourMethodIncompatibleModifiers.put(PsiModifier.PUBLIC, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE, PsiModifier.PROTECTED));
ourMethodIncompatibleModifiers.put(PsiModifier.PROTECTED, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PRIVATE));
ourMethodIncompatibleModifiers.put(PsiModifier.STATIC, newTroveSet(PsiModifier.ABSTRACT, PsiModifier.DEFAULT));
ourMethodIncompatibleModifiers.put(PsiModifier.DEFAULT, newTroveSet(PsiModifier.ABSTRACT, PsiModifier.STATIC));
ourMethodIncompatibleModifiers.put(PsiModifier.SYNCHRONIZED, newTroveSet(PsiModifier.ABSTRACT));
ourMethodIncompatibleModifiers.put(PsiModifier.STRICTFP, newTroveSet(PsiModifier.ABSTRACT));
ourMethodIncompatibleModifiers.put(PsiModifier.FINAL, newTroveSet(PsiModifier.ABSTRACT));
ourFieldIncompatibleModifiers = new THashMap<String, Set<String>>(8);
modifiers = new THashSet<String>(1);
modifiers.add(PsiModifier.VOLATILE);
ourFieldIncompatibleModifiers.put(PsiModifier.FINAL, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourFieldIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PUBLIC);
modifiers.add(PsiModifier.PROTECTED);
ourFieldIncompatibleModifiers.put(PsiModifier.PRIVATE, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PROTECTED);
ourFieldIncompatibleModifiers.put(PsiModifier.PUBLIC, modifiers);
modifiers = new THashSet<String>(3);
modifiers.add(PsiModifier.PACKAGE_LOCAL);
modifiers.add(PsiModifier.PRIVATE);
modifiers.add(PsiModifier.PUBLIC);
ourFieldIncompatibleModifiers.put(PsiModifier.PROTECTED, modifiers);
ourFieldIncompatibleModifiers.put(PsiModifier.FINAL, newTroveSet(PsiModifier.VOLATILE));
ourFieldIncompatibleModifiers.put(PsiModifier.PACKAGE_LOCAL, newTroveSet(PsiModifier.PRIVATE, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourFieldIncompatibleModifiers.put(PsiModifier.PRIVATE, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PROTECTED));
ourFieldIncompatibleModifiers.put(PsiModifier.PUBLIC, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE, PsiModifier.PROTECTED));
ourFieldIncompatibleModifiers.put(PsiModifier.PROTECTED, newTroveSet(PsiModifier.PACKAGE_LOCAL, PsiModifier.PUBLIC, PsiModifier.PRIVATE));
ourFieldIncompatibleModifiers.put(PsiModifier.STATIC, Collections.<String>emptySet());
ourFieldIncompatibleModifiers.put(PsiModifier.TRANSIENT, Collections.<String>emptySet());
modifiers = new THashSet<String>(1);
modifiers.add(PsiModifier.FINAL);
ourFieldIncompatibleModifiers.put(PsiModifier.VOLATILE, modifiers);
ourFieldIncompatibleModifiers.put(PsiModifier.VOLATILE, newTroveSet(PsiModifier.FINAL));
ourClassInitializerIncompatibleModifiers = new THashMap<String, Set<String>>(1);
ourClassInitializerIncompatibleModifiers.put(PsiModifier.STATIC, Collections.<String>emptySet());
ourConstructorNotAllowedModifiers = new THashSet<String>(6);
ourConstructorNotAllowedModifiers.add(PsiModifier.ABSTRACT);
ourConstructorNotAllowedModifiers.add(PsiModifier.STATIC);
ourConstructorNotAllowedModifiers.add(PsiModifier.NATIVE);
ourConstructorNotAllowedModifiers.add(PsiModifier.FINAL);
ourConstructorNotAllowedModifiers.add(PsiModifier.STRICTFP);
ourConstructorNotAllowedModifiers.add(PsiModifier.SYNCHRONIZED);
ourConstructorNotAllowedModifiers = newTroveSet(PsiModifier.ABSTRACT, PsiModifier.STATIC, PsiModifier.NATIVE,
PsiModifier.FINAL, PsiModifier.STRICTFP, PsiModifier.SYNCHRONIZED);
}
@Nullable
@@ -219,6 +143,7 @@ public class HighlightUtil {
@Nullable PsiModifierList modifierList,
@NotNull Map<String, Set<String>> incompatibleModifiersHash) {
if (modifierList == null) return null;
// modifier is always incompatible with itself
PsiElement[] modifiers = modifierList.getChildren();
int modifierCount = 0;
@@ -235,13 +160,11 @@ public class HighlightUtil {
if (modifierList.hasModifierProperty(incompatible)) {
return incompatible;
}
else if (PsiModifier.ABSTRACT.equals(incompatible)) {
final PsiElement owner = modifierList.getParent();
if (owner instanceof PsiMethod && ((PsiMethod)owner).isExtensionMethod()) {
return incompatible;
}
else if (PsiModifier.ABSTRACT.equals(incompatible) && modifierList.hasExplicitModifier(incompatible)) {
return incompatible;
}
}
return null;
}
@@ -795,21 +718,18 @@ public class HighlightUtil {
return null;
}
@Nullable
static HighlightInfo checkIllegalModifierCombination(@NotNull PsiKeyword keyword, @NotNull PsiModifierList modifierList) {
@PsiModifier.ModifierConstant String modifier = keyword.getText();
String incompatible = getIncompatibleModifier(modifier, modifierList);
HighlightInfo highlightInfo = null;
if (incompatible != null) {
String message = JavaErrorMessages.message("incompatible.modifiers", modifier, incompatible);
highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message);
HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message);
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createModifierListFix(modifierList, modifier, false, false));
return highlightInfo;
}
return highlightInfo;
return null;
}
@Nullable
@@ -840,9 +760,11 @@ public class HighlightUtil {
PsiElement modifierOwner = modifierList.getParent();
if (modifierOwner == null) return null;
if (PsiUtilCore.hasErrorElementChild(modifierOwner)) return null;
@PsiModifier.ModifierConstant String modifier = keyword.getText();
final Map<String, Set<String>> incompatibleModifierMap = getIncompatibleModifierMap(modifierList);
if (incompatibleModifierMap == null) return null;
Set<String> incompatibles = incompatibleModifierMap.get(modifier);
PsiElement modifierOwnerParent = modifierOwner instanceof PsiMember ? ((PsiMember)modifierOwner).getContainingClass() : modifierOwner.getParent();
if (modifierOwnerParent == null) modifierOwnerParent = modifierOwner.getParent();
@@ -1363,7 +1285,7 @@ public class HighlightUtil {
if (PsiUtil.isLanguageLevel8OrHigher(expr)) {
final PsiMethod method = PsiTreeUtil.getParentOfType(expr, PsiMethod.class);
if (method != null && method.isExtensionMethod() && qualifier == null) {
if (method != null && method.hasModifierProperty(PsiModifier.DEFAULT) && qualifier == null) {
//todo[r.sh] "Add qualifier" quick fix
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, parent, JavaErrorMessages.message("unqualified.super.disallowed"));
}
@@ -705,14 +705,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) visitExpression(expression);
}
@Override public void visitModifierList(PsiModifierList list) {
@Override
public void visitModifierList(PsiModifierList list) {
super.visitModifierList(list);
PsiElement parent = list.getParent();
if (!myHolder.hasErrorResults() && parent instanceof PsiMethod) {
myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody((PsiMethod)parent));
}
if (parent instanceof PsiMethod) {
PsiMethod method = (PsiMethod)parent;
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method));
MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
if (!method.isConstructor()) {
try {
@@ -454,7 +454,7 @@ public class OverrideImplementUtil {
}
public static void setupMethodBody(PsiMethod result, PsiMethod originalMethod, PsiClass targetClass) throws IncorrectOperationException {
boolean isAbstract = originalMethod.hasModifierProperty(PsiModifier.ABSTRACT) || originalMethod.isExtensionMethod();
boolean isAbstract = originalMethod.hasModifierProperty(PsiModifier.ABSTRACT) || originalMethod.hasModifierProperty(PsiModifier.DEFAULT);
String templateName = isAbstract ? JavaTemplateUtil.TEMPLATE_IMPLEMENTED_METHOD_BODY : JavaTemplateUtil.TEMPLATE_OVERRIDDEN_METHOD_BODY;
FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templateName);
setupMethodBody(result, originalMethod, targetClass, template);
@@ -538,7 +538,7 @@ public class OverrideImplementUtil {
for (Iterator<CandidateInfo> iterator = candidates.iterator(); iterator.hasNext(); ) {
CandidateInfo candidate = iterator.next();
PsiElement element = candidate.getElement();
if (element instanceof PsiMethod && ((PsiMethod)element).isExtensionMethod()) {
if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) {
iterator.remove();
secondary.add(candidate);
}
@@ -267,11 +267,6 @@ public class LightMethodBuilder extends LightElement implements PsiMethod, Origi
return PsiImplUtil.isVarArgs(this);
}
@Override
public boolean isExtensionMethod() {
return false;
}
@Override
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
@@ -222,7 +222,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
if (method.findDeepestSuperMethods().length == 0) {
deleteOverrideAnnotationIfFound(methodCopy);
}
final boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.isExtensionMethod();
final boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT);
if (myIsTargetInterface || info.isToAbstract()) {
ChangeContextUtil.clearContextInfo(method);
RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
@@ -27,7 +27,6 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -358,20 +357,17 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
}
else if (member instanceof PsiMethod) {
PsiMethod method = (PsiMethod)member;
final PsiMethod methodBySignature =
MethodSignatureUtil.findMethodBySuperSignature(targetClass, method.getSignature(substitutor), false);
PsiMethod methodBySignature = MethodSignatureUtil.findMethodBySuperSignature(targetClass, method.getSignature(substitutor), false);
if (methodBySignature == null) {
final boolean wasInterface = myClass.isInterface();
newMember = (PsiMethod)targetClass.add(method);
if (wasInterface) {
if (myClass.isInterface()) {
if (!targetClass.isInterface()) {
PsiUtil.setModifierProperty(newMember, PsiModifier.PUBLIC, true);
final PsiJavaToken extMethodMarker = PsiImplUtil.findExtensionMethodMarker((PsiMethod)newMember);
if (extMethodMarker == null) {
PsiUtil.setModifierProperty(newMember, PsiModifier.ABSTRACT, true);
if (newMember.hasModifierProperty(PsiModifier.DEFAULT)) {
PsiUtil.setModifierProperty(newMember, PsiModifier.DEFAULT, false);
}
else {
extMethodMarker.delete();
PsiUtil.setModifierProperty(newMember, PsiModifier.ABSTRACT, true);
}
}
}
@@ -808,7 +808,7 @@ public class RefactoringUtil {
}
public static void makeMethodAbstract(@NotNull PsiClass targetClass, @NotNull PsiMethod method) throws IncorrectOperationException {
if (!method.isExtensionMethod()) {
if (!method.hasModifierProperty(PsiModifier.DEFAULT)) {
PsiCodeBlock body = method.getBody();
if (body != null) {
body.delete();
@@ -17,12 +17,9 @@ package com.intellij.psi;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
import org.jetbrains.annotations.NotNull;
@@ -230,7 +227,7 @@ public class LambdaUtil {
for (HierarchicalMethodSignature signature : visibleSignatures) {
final PsiMethod psiMethod = signature.getMethod();
if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue;
if (!overridesPublicObjectMethod(psiMethod) && !psiMethod.isExtensionMethod()) {
if (!overridesPublicObjectMethod(psiMethod)) {
methods.add(signature);
}
}
@@ -99,13 +99,6 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie
*/
boolean isVarArgs();
/**
* Checks if the method is a Java 8 extension method.
*
* @return true if the method is an extension method, false otherwise.
*/
boolean isExtensionMethod();
/**
* Returns the signature of this method, using the specified substitutor to specify
* values of generic type parameters.
@@ -34,13 +34,14 @@ public interface PsiModifier {
@NonNls String STRICTFP = "strictfp";
@NonNls String TRANSIENT = "transient";
@NonNls String VOLATILE = "volatile";
@NonNls String DEFAULT = "default";
@NonNls String[] MODIFIERS = {
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT
};
@MagicConstant(stringValues = {
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, PACKAGE_LOCAL
PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, PACKAGE_LOCAL
})
@interface ModifierConstant { }
}
@@ -559,19 +559,6 @@ public class PsiImplUtil {
return parameters.length > 0 && parameters[parameters.length - 1].isVarArgs();
}
public static boolean isExtensionMethod(@NotNull PsiMethod method) {
return findExtensionMethodMarker(method) != null;
}
@Nullable
public static PsiJavaToken findExtensionMethodMarker(@Nullable PsiMethod method) {
if (method == null) return null;
final PsiCodeBlock body = method.getBody();
if (body == null) return null;
final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class);
return previous instanceof PsiJavaToken && PsiUtil.isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD) ? (PsiJavaToken)previous : null;
}
public static PsiElement handleMirror(PsiElement element) {
return element instanceof PsiMirrorElement ? ((PsiMirrorElement)element).getPrototype() : element;
}
@@ -33,6 +33,7 @@ public final class ModifierFlags {
public static final int VOLATILE_MASK = 0x0040;
public static final int TRANSIENT_MASK = 0x0080;
public static final int NATIVE_MASK = 0x0100;
public static final int DEFENDER_MASK = 0x0200;
public static final int ABSTRACT_MASK = 0x0400;
public static final int STRICTFP_MASK = 0x0800;
public static final int PACKAGE_LOCAL_MASK = 0x1000;
@@ -50,6 +51,7 @@ public final class ModifierFlags {
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.VOLATILE, VOLATILE_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.TRANSIENT, TRANSIENT_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.NATIVE, NATIVE_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.DEFAULT, DEFENDER_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.ABSTRACT, ABSTRACT_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.STRICTFP, STRICTFP_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PACKAGE_LOCAL, PACKAGE_LOCAL_MASK);
@@ -64,6 +66,7 @@ public final class ModifierFlags {
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.VOLATILE_KEYWORD, VOLATILE_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.TRANSIENT_KEYWORD, TRANSIENT_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.NATIVE_KEYWORD, NATIVE_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.DEFAULT_KEYWORD, DEFENDER_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.ABSTRACT_KEYWORD, ABSTRACT_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.STRICTFP_KEYWORD, STRICTFP_MASK);
}
@@ -20,6 +20,7 @@ import com.intellij.lang.LighterASTNode;
import com.intellij.lang.LighterASTTokenNode;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.*;
import com.intellij.psi.impl.java.stubs.impl.PsiMethodStubImpl;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
import com.intellij.psi.stubs.PsiFileStub;
@@ -109,7 +110,10 @@ public class RecordUtil {
else if (parent instanceof PsiMethodStub) {
if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) {
packed |= ModifierFlags.PUBLIC_MASK;
if (!((PsiMethodStub)parent).isExtensionMethod()) {
if (parent instanceof PsiMethodStubImpl && ((PsiMethodStubImpl)parent).hasExtensionMethodMark()) {
packed |= ModifierFlags.DEFENDER_MASK;
}
else {
packed |= ModifierFlags.ABSTRACT_MASK;
}
}
@@ -131,6 +135,10 @@ public class RecordUtil {
}
}
if ((packed & ModifierFlags.DEFENDER_MASK) != 0) {
packed &= ~ModifierFlags.ABSTRACT_MASK;
}
if ((packed & (ModifierFlags.PRIVATE_MASK | ModifierFlags.PROTECTED_MASK | ModifierFlags.PUBLIC_MASK)) == 0) {
packed |= ModifierFlags.PACKAGE_LOCAL_MASK;
}
@@ -185,11 +185,6 @@ public class ClsMethodImpl extends ClsMemberImpl<PsiMethodStub> implements PsiAn
return getStub().isVarArgs();
}
@Override
public boolean isExtensionMethod() {
return getStub().isExtensionMethod();
}
@Override
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
@@ -145,6 +145,10 @@ public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierList
buffer.append(PsiModifier.STRICTFP);
buffer.append(' ');
}
if (hasModifierProperty(PsiModifier.DEFAULT)) {
buffer.append(PsiModifier.DEFAULT);
buffer.append(' ');
}
}
@Override
@@ -258,7 +258,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
return flags;
}
private static int packMethodFlags(final int access) {
private static int packMethodFlags(final int access, boolean isInterface) {
int flags = packCommonFlags(access);
if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
@@ -270,6 +270,9 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
if ((access & Opcodes.ACC_ABSTRACT) != 0) {
flags |= ModifierFlags.ABSTRACT_MASK;
}
else if (isInterface) {
flags |= ModifierFlags.DEFENDER_MASK;
}
if ((access & Opcodes.ACC_STRICT) != 0) {
flags |= ModifierFlags.STRICTFP_MASK;
}
@@ -388,19 +391,19 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
boolean isConstructor = SYNTHETIC_INIT_METHOD.equals(name);
boolean isVarargs = (access & Opcodes.ACC_VARARGS) != 0;
boolean isAnnotationMethod = myResult.isAnnotationType();
boolean isExtensionMethod = myResult.isInterface() && (access & Opcodes.ACC_ABSTRACT) == 0;
if (!isConstructor && !isCorrectName(name)) return null;
final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false, isExtensionMethod);
final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false);
String canonicalMethodName = isConstructor ? myResult.getName() : name;
final String canonicalMethodName = isConstructor ? myResult.getName() : name;
final List<String> args = new ArrayList<String>();
final List<String> throwables = exceptions != null ? new ArrayList<String>() : null;
PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null);
final PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null);
final PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packMethodFlags(access, myResult.isInterface()));
final PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packMethodFlags(access));
boolean parsedViaGenericSignature = false;
String returnType;
if (signature == null) {
@@ -116,9 +116,11 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
final TypeInfo typeInfo = isConstructor ? TypeInfo.createConstructorType() : TypeInfo.create(tree, node, parentStub);
final boolean isAnno = (node.getTokenType() == JavaElementType.ANNOTATION_METHOD);
final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation, isExtension);
final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation);
return new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
final PsiMethodStubImpl stub = new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
stub.setExtensionMethodMark(isExtension);
return stub;
}
@Override
@@ -29,7 +29,6 @@ public interface PsiMethodStub extends NamedStub<PsiMethod> {
boolean isConstructor();
boolean isVarArgs();
boolean isAnnotationMethod();
boolean isExtensionMethod();
@Nullable String getDefaultValueText();
@NotNull TypeInfo getReturnTypeText(boolean doResolve);
@@ -37,14 +37,14 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
private final byte myFlags;
private final StringRef myName;
private StringRef myDefaultValueText;
// todo[r.sh] drop this after transition period finished
private boolean myHasExtMethodMark = false;
private static final int CONSTRUCTOR = 0x01;
private static final int VARARGS = 0x02;
private static final int ANNOTATION = 0x04;
private static final int DEPRECATED = 0x08;
private static final int DEPRECATED_ANNOTATION = 0x10;
private static final int EXTENSION = 0x20;
public PsiMethodStubImpl(final StubElement parent,
final StringRef name,
@@ -74,6 +74,14 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
myReturnType = returnType;
}
public void setExtensionMethodMark(boolean hasExtMethodMark) {
myHasExtMethodMark = hasExtMethodMark;
}
public boolean hasExtensionMethodMark() {
return myHasExtMethodMark;
}
@Override
public boolean isConstructor() {
return (myFlags & CONSTRUCTOR) != 0;
@@ -89,11 +97,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
return isAnnotationMethod(myFlags);
}
@Override
public boolean isExtensionMethod() {
return (myFlags & EXTENSION) != 0;
}
public static boolean isAnnotationMethod(final byte flags) {
return (flags & ANNOTATION) != 0;
}
@@ -155,15 +158,13 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
boolean isAnnotationMethod,
boolean isVarargs,
boolean isDeprecated,
boolean hasDeprecatedAnnotation,
boolean isExtensionMethod) {
boolean hasDeprecatedAnnotation) {
byte flags = 0;
if (isConstructor) flags |= CONSTRUCTOR;
if (isAnnotationMethod) flags |= ANNOTATION;
if (isVarargs) flags |= VARARGS;
if (isDeprecated) flags |= DEPRECATED;
if (hasDeprecatedAnnotation) flags |= DEPRECATED_ANNOTATION;
if (isExtensionMethod) flags |= EXTENSION;
return flags;
}
@@ -191,10 +192,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
builder.append(" default=").append(defaultValue);
}
if (isExtensionMethod()) {
builder.append(" default {}");
}
builder.append("]");
return builder.toString();
}
@@ -142,11 +142,6 @@ public class LightMethod extends LightElement implements PsiMethod {
return myMethod.isVarArgs();
}
@Override
public boolean isExtensionMethod() {
return myMethod.isExtensionMethod();
}
@Override
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
@@ -37,7 +37,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
public static final int STUB_VERSION = 14;
public static final int STUB_VERSION = 15;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
@@ -15,8 +15,8 @@
*/
package com.intellij.psi.impl.source;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
@@ -30,7 +30,6 @@ import org.jetbrains.annotations.NotNull;
* @author ven
*/
public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotationMethod {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiAnnotationMethodImpl");
private PatchedSoftReference<PsiAnnotationMemberValue> myCachedDefaultValue = null;
public PsiAnnotationMethodImpl(final PsiMethodStub stub) {
@@ -51,11 +50,6 @@ public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotat
myCachedDefaultValue = null;
}
@Override
public boolean isExtensionMethod() {
return false;
}
@Override
public PsiAnnotationMemberValue getDefaultValue() {
final PsiMethodStub stub = getStub();
@@ -71,7 +65,8 @@ public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotat
}
@NonNls final String annoText = "@interface _Dummy_ { Class foo() default " + text + "; }";
final PsiJavaFile file = (PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", annoText);
final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
final PsiJavaFile file = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText);
final PsiAnnotationMemberValue value = ((PsiAnnotationMethod)file.getClasses()[0].getMethods()[0]).getDefaultValue();
myCachedDefaultValue = new PatchedSoftReference<PsiAnnotationMemberValue>(value);
return value;
@@ -159,8 +159,10 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
}
@Override
public PsiElement setName(@NotNull String name) throws IncorrectOperationException{
PsiImplUtil.setName(getNameIdentifier(), name);
public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
final PsiIdentifier identifier = getNameIdentifier();
if (identifier == null) throw new IncorrectOperationException("Empty name: " + this);
PsiImplUtil.setName(identifier, name);
return this;
}
@@ -311,16 +313,6 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
return PsiImplUtil.isVarArgs(this);
}
@Override
public boolean isExtensionMethod() {
final PsiMethodStub stub = getStub();
if (stub != null) {
return stub.isExtensionMethod();
}
return PsiImplUtil.isExtensionMethod(this);
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
@@ -349,9 +341,14 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
@Override
public PsiElement getOriginalElement() {
PsiClass originalClass = (PsiClass)getContainingClass().getOriginalElement();
final PsiMethod originalMethod = originalClass.findMethodBySignature(this, false);
return originalMethod != null ? originalMethod : this;
final PsiClass containingClass = getContainingClass();
if (containingClass != null) {
final PsiMethod originalMethod = ((PsiClass)containingClass.getOriginalElement()).findMethodBySignature(this, false);
if (originalMethod != null) {
return originalMethod;
}
}
return this;
}
@Override
@@ -391,5 +388,4 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
protected boolean isVisibilitySupported() {
return true;
}
}
@@ -27,16 +27,18 @@ import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
@@ -56,6 +58,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.STRICTFP, JavaTokenType.STRICTFP_KEYWORD);
NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.TRANSIENT, JavaTokenType.TRANSIENT_KEYWORD);
NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.VOLATILE, JavaTokenType.VOLATILE_KEYWORD);
NAME_TO_KEYWORD_TYPE_MAP.put(PsiModifier.DEFAULT, JavaTokenType.DEFAULT_KEYWORD);
}
public PsiModifierListImpl(final PsiModifierListStub stub) {
@@ -82,7 +85,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (type == JavaTokenType.PUBLIC_KEYWORD) {
return true;
}
if (type == null) { // package local
if (type == null /* package local */) {
return false;
}
if (type == JavaTokenType.STATIC_KEYWORD) {
@@ -127,13 +130,16 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (type == JavaTokenType.PUBLIC_KEYWORD) {
return true;
}
if (type == null) { // package local
if (type == null /* package local */) {
return false;
}
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
return !((PsiMethod)parent).isExtensionMethod();
return !(getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) != null || findExtensionMethodMarker((PsiMethod)parent) != null);
}
}
if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) {
return true;
}
}
else if (parent instanceof PsiField) {
if (parent instanceof PsiEnumConstant) {
@@ -145,7 +151,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (type == JavaTokenType.PUBLIC_KEYWORD) {
return true;
}
if (type == null) { // package local
if (type == null /* package local */) {
return false;
}
if (type == JavaTokenType.STATIC_KEYWORD) {
@@ -164,7 +170,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (type == JavaTokenType.FINAL_KEYWORD) return true;
}
if (type == null) { // package local
if (type == null /* package local */) {
return !hasModifierProperty(PsiModifier.PUBLIC) &&
!hasModifierProperty(PsiModifier.PRIVATE) &&
!hasModifierProperty(PsiModifier.PROTECTED);
@@ -173,10 +179,20 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
return getNode().findChildByType(type) != null;
}
@Nullable
private static PsiJavaToken findExtensionMethodMarker(@Nullable PsiMethod method) {
// todo[r.sh] drop this after transition period finished
if (method == null) return null;
final PsiCodeBlock body = method.getBody();
if (body == null) return null;
final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class);
return previous instanceof PsiJavaToken && PsiUtil.isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD) ? (PsiJavaToken)previous : null;
}
@Override
public boolean hasExplicitModifier(@NotNull String name) {
final CompositeElement tree = (CompositeElement)getNode();
IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name);
final IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name);
return tree.findChildByType(type) != null;
}
@@ -184,74 +200,70 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
public void setModifierProperty(@NotNull String name, boolean value) throws IncorrectOperationException{
checkSetModifierProperty(name, value);
PsiElement parent = getParent();
PsiElement grandParent = parent != null ? parent.getParent() : null;
IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name);
CompositeElement treeElement = (CompositeElement)getNode();
// There is a possible case that parameters list occupies more than one line and its elements are aligned. Modifiers list change
// changes horizontal position of parameters list start, hence, we need to reformat them in order to preserve alignment.
PsiElement methodCandidate = getParent();
if (methodCandidate instanceof PsiMethod) {
PsiMethod method = (PsiMethod)methodCandidate;
if (parent instanceof PsiMethod) {
PsiMethod method = (PsiMethod)parent;
CodeEditUtil.markToReformat(method.getParameterList().getNode(), true);
}
IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name);
CompositeElement treeElement = (CompositeElement)getNode();
ASTNode parentTreeElement = treeElement.getTreeParent();
if (value){
if (parentTreeElement.getElementType() == JavaElementType.FIELD &&
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
if (value) {
if (parent instanceof PsiField && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD) return;
}
else if (parentTreeElement.getElementType() == JavaElementType.METHOD &&
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
else if (parent instanceof PsiMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) return;
}
else if (parentTreeElement.getElementType() == JavaElementType.CLASS &&
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
else if (parent instanceof PsiClass && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
if (type == JavaTokenType.PUBLIC_KEYWORD) return;
}
else if (parentTreeElement.getElementType() == JavaElementType.ANNOTATION_METHOD &&
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isAnnotationType()) {
else if (parent instanceof PsiAnnotationMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isAnnotationType()) {
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
}
if (type == JavaTokenType.PUBLIC_KEYWORD
|| type == JavaTokenType.PRIVATE_KEYWORD
|| type == JavaTokenType.PROTECTED_KEYWORD
|| type == null /* package local */){
if (type != JavaTokenType.PUBLIC_KEYWORD){
if (type == JavaTokenType.PUBLIC_KEYWORD ||
type == JavaTokenType.PRIVATE_KEYWORD ||
type == JavaTokenType.PROTECTED_KEYWORD ||
type == null /* package local */) {
if (type != JavaTokenType.PUBLIC_KEYWORD) {
setModifierProperty(PsiModifier.PUBLIC, false);
}
if (type != JavaTokenType.PRIVATE_KEYWORD){
if (type != JavaTokenType.PRIVATE_KEYWORD) {
setModifierProperty(PsiModifier.PRIVATE, false);
}
if (type != JavaTokenType.PROTECTED_KEYWORD){
if (type != JavaTokenType.PROTECTED_KEYWORD) {
setModifierProperty(PsiModifier.PROTECTED, false);
}
if (type == null) return;
}
if (treeElement.findChildByType(type) == null){
if (treeElement.findChildByType(type) == null) {
TreeElement keyword = Factory.createSingleLeafElement(type, name, null, getManager());
treeElement.addInternal(keyword, keyword, null, null);
}
if ((type == JavaTokenType.ABSTRACT_KEYWORD || type == JavaTokenType.NATIVE_KEYWORD) &&
parentTreeElement.getElementType() == JavaElementType.METHOD){
//Q: remove body?
}
}
else{
if (type == null){ // package local
else {
if (type == null /* package local */) {
throw new IncorrectOperationException("Cannot reset package local modifier."); //?
}
ASTNode child = treeElement.findChildByType(type);
if (child != null){
if (child != null) {
SourceTreeToPsiMap.treeToPsiNotNull(child).delete();
}
if (type == JavaTokenType.DEFAULT_KEYWORD && parent instanceof PsiMethod) {
final PsiJavaToken marker = findExtensionMethodMarker((PsiMethod)parent);
if (marker != null) {
marker.delete();
}
}
}
}
@@ -45,7 +45,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
TokenSet MODIFIER_BIT_SET = TokenSet.create(
PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, STATIC_KEYWORD, ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD,
SYNCHRONIZED_KEYWORD, STRICTFP_KEYWORD, TRANSIENT_KEYWORD, VOLATILE_KEYWORD);
SYNCHRONIZED_KEYWORD, STRICTFP_KEYWORD, TRANSIENT_KEYWORD, VOLATILE_KEYWORD, DEFAULT_KEYWORD);
TokenSet PRIMITIVE_TYPE_BIT_SET = TokenSet.create(
BOOLEAN_KEYWORD, BYTE_KEYWORD, SHORT_KEYWORD, INT_KEYWORD, LONG_KEYWORD, CHAR_KEYWORD, FLOAT_KEYWORD, DOUBLE_KEYWORD, VOID_KEYWORD);
@@ -175,6 +175,7 @@ incompatible.types.html.tooltip=\
interface.methods.cannot.have.body=Interface methods cannot have body
abstract.methods.cannot.have.a.body=Abstract methods cannot have a body
native.methods.cannot.have.a.body=Native methods cannot have a body
extension.method.should.have.a.body=Extension method should have a body
extension.method.in.class=Extension methods can only be used within an interface
instance.method.cannot.override.static.method=Instance method ''{0}'' in ''{1}'' cannot override static method ''{2}'' in ''{3}''
@@ -50,6 +50,15 @@ class D {
}
interface IllegalMods {
<error descr="Illegal combination of modifiers: 'static' and 'abstract'">static</error> void sm1();
<error descr="Illegal combination of modifiers: 'static' and 'abstract'">static</error> void sm2() default { }
<error descr="Illegal combination of modifiers: 'static' and 'abstract'">static</error> void m1();
<error descr="Illegal combination of modifiers: 'static' and 'default'">static</error> void m2() default { }
<error descr="Illegal combination of modifiers: 'static' and 'default'">static</error> <error descr="Illegal combination of modifiers: 'default' and 'static'">default</error> void m3() { }
<error descr="Illegal combination of modifiers: 'abstract' and 'default'">abstract</error> void m4() default { }
<error descr="Illegal combination of modifiers: 'abstract' and 'default'">abstract</error> <error descr="Illegal combination of modifiers: 'default' and 'abstract'">default</error> void m5() { }
<error descr="Extension method should have a body">default void m6()</error>;
<error descr="Modifier 'default' not allowed here">default</error> int i;
<error descr="Modifier 'default' not allowed here">default</error> interface X { }
}
@@ -7,5 +7,5 @@ package pkg;
interface ExtMethods {
void m1();
void m2() { /* compiled code */ }
default void m2() { /* compiled code */ }
}
@@ -0,0 +1,27 @@
PsiJavaFile:MethodNormal2.java
PsiJavaToken:LBRACE('{')
PsiWhiteSpace(' ')
PsiMethod:f
PsiModifierList:default public
PsiKeyword:default('default')
PsiWhiteSpace(' ')
PsiKeyword:public('public')
PsiTypeParameterList
<empty list>
PsiWhiteSpace(' ')
PsiTypeElement:void
PsiKeyword:void('void')
PsiWhiteSpace(' ')
PsiIdentifier:f('f')
PsiParameterList:()
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace(' ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace(' ')
PsiJavaToken:RBRACE('}')
@@ -76,6 +76,7 @@ public class DeclarationParserTest extends JavaParsingTestCase {
public void testMethodNormal0() { doParserTest("{ void f() {} }", false, false); }
public void testMethodNormal1() { doParserTest("{ void f(); }", false, false); }
public void testMethodNormal2() { doParserTest("{ default public void f() { } }", false, false); }
public void testSemicolons() { doParserTest("{ void f() {}; void g() {}; }", false, false); }
public void testUnclosed0() { doParserTest("{ void f() }", false, false); }
public void testExtension() { doParserTest("{ int f() throws E default { return 42; } }", false, false); }
@@ -175,8 +175,8 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
" METHOD:PsiMethodStub[m2:void default {}]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" METHOD:PsiMethodStub[m2:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=513]\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2012 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.psi.impl.source.tree.java;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
public class PsiModifierListTest extends LightCodeInsightFixtureTestCase {
// todo[r.sh] drop this after transition period finished
public void testDefaultModifier() throws Exception {
final PsiFile file = myFixture.configureByText(JavaFileType.INSTANCE,
"class C {\n" +
" default void m() default {\n" +
" }\n" +
"}");
final PsiMethod method = ((PsiJavaFile)file).getClasses()[0].getMethods()[0];
assertEquals("default void m() default {\n }", method.getText());
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
PsiUtil.setModifierProperty(method, PsiModifier.DEFAULT, false);
CodeStyleManager.getInstance(getProject()).reformat(method);
}
});
assertEquals("void m() {\n }", method.getText());
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
PsiUtil.setModifierProperty(method, PsiModifier.DEFAULT, true);
}
});
assertEquals("default void m() {\n }", method.getText());
}
}
@@ -19,9 +19,9 @@ import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.ui.ConflictsDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
@@ -66,14 +66,12 @@ public class ConvertInterfaceToClassIntention extends Intention {
final PsiMethod[] methods = anInterface.getMethods();
for (final PsiMethod method : methods) {
final PsiJavaToken marker = PsiImplUtil.findExtensionMethodMarker(method);
final PsiModifierList modifierList = method.getModifierList();
modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
if (marker != null) {
marker.delete();
PsiUtil.setModifierProperty(method, PsiModifier.PUBLIC, true);
if (method.hasModifierProperty(PsiModifier.DEFAULT)) {
PsiUtil.setModifierProperty(method, PsiModifier.DEFAULT, false);
}
else {
modifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
PsiUtil.setModifierProperty(method, PsiModifier.ABSTRACT, true);
}
}
@@ -319,11 +319,6 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
return PsiImplUtil.isVarArgs(getParameters());
}
@Override
public boolean isExtensionMethod() {
return false;
}
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
return MethodSignatureBackedByPsiMethod.create(this, substitutor);
@@ -280,11 +280,6 @@ public class GrLightMethodBuilder extends LightElement implements GrMethod, Ori
return parameters[parameters.length - 1].isVarArgs();
}
@Override
public boolean isExtensionMethod() {
return false;
}
@Override
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
@@ -176,11 +176,6 @@ public class GrDynamicMethodImpl extends LightElement implements GrMethod {
return myMethod.isVarArgs();
}
@Override
public boolean isExtensionMethod() {
return myMethod.isExtensionMethod();
}
@NotNull
public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) {
return myMethod.getSignature(substitutor);