IDEA-243546 Allow local interfaces and enums on language level 15-preview (part of JEP 384)

Also: fix non-static access checks for local interfaces/enums/records (JEP 384)
Also: i18n of error messages

GitOrigin-RevId: 40448f089229d77e32eb200b4011e1aea09391b0
This commit is contained in:
Tagir Valeev
2020-06-16 13:25:49 +07:00
committed by intellij-monorepo-bot
parent 1a1a2b05a6
commit 2072855222
16 changed files with 257 additions and 58 deletions

View File

@@ -115,6 +115,8 @@ feature.switch.expressions='switch' expressions
feature.records=Records
feature.patterns.instanceof=Patterns in 'instanceof'
feature.sealed.classes=Sealed classes
feature.local.interfaces=Local interfaces
feature.local.enums=Local enums
find.searching.for.references.to.class.progress=Searching for references to class {0}...
find.usages.panel.title.derived.classes=Derived Classes

View File

@@ -235,7 +235,7 @@ public class GenericsHighlightUtil {
final PsiType psiType = substitutor.substitute(classParameter);
if (psiType instanceof PsiClassType && !(PsiUtil.resolveClassInType(psiType) instanceof PsiTypeParameter)) {
if (GenericsUtil.checkNotInBounds(type, psiType, referenceParameterList)) {
final String description = "Actual type argument and inferred type contradict each other";
final String description = JavaErrorBundle.message("actual.type.argument.contradict.inferred.type");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement2Highlight).descriptionAndTooltip(description).create();
}
}
@@ -407,7 +407,7 @@ public class GenericsHighlightUtil {
final PsiClass containingClass = objectMethod.getContainingClass();
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && objectMethod.hasModifierProperty(PsiModifier.PUBLIC)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip("Default method '" + sig.getName() + "' overrides a member of 'java.lang.Object'")
.descriptionAndTooltip(JavaErrorBundle.message("default.method.overrides.object.member", sig.getName()))
.range(methodIdentifier)
.create();
}
@@ -547,12 +547,9 @@ public class GenericsHighlightUtil {
!foundMethod.hasModifierProperty(PsiModifier.DEFAULT) &&
(foundMethodContainingClass = foundMethod.getContainingClass()) != null) {
final String description =
"Methods " +
JavaHighlightUtil.formatMethod(foundMethod) + " from " + HighlightUtil.formatClass(foundMethodContainingClass) +
" and " +
JavaHighlightUtil.formatMethod(method) + " from " + HighlightUtil.formatClass(containingClass) +
" are inherited with the same signature";
JavaErrorBundle.message("two.methods.are.inherited.with.same.signature",
JavaHighlightUtil.formatMethod(foundMethod), HighlightUtil.formatClass(foundMethodContainingClass),
JavaHighlightUtil.formatMethod(method), HighlightUtil.formatClass(containingClass));
final HighlightInfo info = HighlightInfo
.newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(
description)
@@ -896,7 +893,8 @@ public class GenericsHighlightUtil {
for (PsiJavaCodeReferenceElement referenceElement : typeParameter1.getExtendsList().getReferenceElements()) {
final PsiElement resolve = referenceElement.resolve();
if (resolve instanceof PsiTypeParameter && ArrayUtilRt.find(parameters, resolve) > i) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(referenceElement).descriptionAndTooltip("Illegal forward reference").create();
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(referenceElement).descriptionAndTooltip(
JavaErrorBundle.message("illegal.forward.reference")).create();
}
}
}
@@ -981,8 +979,8 @@ public class GenericsHighlightUtil {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(operand).descriptionAndTooltip(description).create();
}
if (type.getParameters().length > 0) {
return HighlightInfo
.newHighlightInfo(HighlightInfoType.ERROR).range(operand).descriptionAndTooltip("Cannot select from parameterized type").create();
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(operand).descriptionAndTooltip(
JavaErrorBundle.message("cannot.select.from.parameterized.type")).create();
}
return null;
}
@@ -1034,11 +1032,11 @@ public class GenericsHighlightUtil {
try {
if (!method.isVarArgs()) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(safeVarargsAnnotation).descriptionAndTooltip(
"@SafeVarargs is not allowed on methods with fixed arity").create();
JavaErrorBundle.message("safevarargs.not.allowed.on.methods.with.fixed.arity")).create();
}
if (!isSafeVarargsNoOverridingCondition(method, languageLevel)) {
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(safeVarargsAnnotation).descriptionAndTooltip(
"@SafeVarargs is not allowed on non-final instance methods").create();
JavaErrorBundle.message("safevarargs.not.allowed.non.final.instance.methods")).create();
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.FINAL, true, true));
return info;
}
@@ -1049,7 +1047,7 @@ public class GenericsHighlightUtil {
for (PsiReferenceExpression element : VariableAccessUtils.getVariableReferences(varParameter, method.getBody())) {
if (!PsiUtil.isAccessedForReading(element)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(element).descriptionAndTooltip(
"@SafeVarargs do not suppress potentially unsafe operations").create();
JavaErrorBundle.message("safevarargs.not.suppress.potentially.unsafe.operations")).create();
}
}
@@ -1060,7 +1058,7 @@ public class GenericsHighlightUtil {
if (JavaGenericsUtil.isReifiableType(componentType)) {
PsiElement element = varParameter.getTypeElement();
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(element).descriptionAndTooltip(
"@SafeVarargs is not applicable for reifiable types").create();
JavaErrorBundle.message("safevarargs.not.applicable.for.reifiable.types")).create();
}
return null;
}
@@ -1274,17 +1272,6 @@ public class GenericsHighlightUtil {
return containingClass != null && PsiUtil.typeParametersIterator(containingClass).hasNext();
}
static HighlightInfo checkEnumMustNotBeLocal(@NotNull PsiClass aClass) {
if (!aClass.isEnum()) return null;
PsiElement parent = aClass.getParent();
if (!(parent instanceof PsiClass || parent instanceof PsiFile || parent instanceof PsiClassLevelDeclarationStatement)) {
String description = JavaErrorBundle.message("local.enum");
TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
}
return null;
}
static HighlightInfo checkSelectStaticClassFromParameterizedType(@Nullable PsiElement resolved, @NotNull PsiJavaCodeReferenceElement ref) {
if (resolved instanceof PsiClass && ((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC)) {
final PsiElement qualifier = ref.getQualifier();
@@ -1420,7 +1407,8 @@ public class GenericsHighlightUtil {
final String conflictingConjunctsMessage = ((PsiIntersectionType)type).getConflictingConjunctsMessage();
if (conflictingConjunctsMessage != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip("Type parameter " + parameterName + " has incompatible upper bounds: " + conflictingConjunctsMessage)
.descriptionAndTooltip(
JavaErrorBundle.message("type.parameter.has.incompatible.upper.bounds", parameterName, conflictingConjunctsMessage))
.range(ref).create();
}
}

View File

@@ -31,8 +31,10 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.*;
import com.intellij.util.JavaPsiConstructorUtil;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -593,13 +595,26 @@ public class HighlightClassUtil {
return info;
}
static HighlightInfo checkInterfaceCannotBeLocal(@NotNull PsiClass aClass) {
if (PsiUtil.isLocalClass(aClass)) {
TextRange range = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
String description = JavaErrorBundle.message("interface.cannot.be.local");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(description).create();
static HighlightInfo checkMustNotBeLocal(@NotNull PsiClass aClass) {
IElementType token;
HighlightingFeature feature;
if (aClass.isEnum()) {
token = JavaTokenType.ENUM_KEYWORD;
feature = HighlightingFeature.LOCAL_ENUMS;
}
return null;
else if (aClass.isInterface()) {
token = JavaTokenType.INTERFACE_KEYWORD;
feature = HighlightingFeature.LOCAL_INTERFACES;
}
else {
return null;
}
if (!PsiUtil.isLocalClass(aClass)) return null;
PsiElement anchor = StreamEx.iterate(aClass.getFirstChild(), Objects::nonNull, PsiElement::getNextSibling)
.findFirst(e -> e instanceof PsiKeyword && ((PsiKeyword)e).getTokenType().equals(token))
.orElseThrow(NoSuchElementException::new);
PsiFile file = aClass.getContainingFile();
return HighlightUtil.checkFeature(anchor, feature, PsiUtil.getLanguageLevel(file), file);
}
static HighlightInfo checkCyclicInheritance(@NotNull PsiClass aClass) {
@@ -700,7 +715,7 @@ public class HighlightClassUtil {
final PsiClass baseClass = PsiUtil.resolveClassInType(((PsiAnonymousClass)aClass).getBaseClassType());
if (baseClass != null && baseClass.isInterface()) {
info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
.descriptionAndTooltip("Anonymous class implements interface; cannot have qualifier for new").create();
.descriptionAndTooltip(JavaErrorBundle.message("anonymous.class.implements.interface.cannot.have.qualifier")).create();
}
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createRemoveNewQualifierFix(expression, aClass));
}
@@ -710,7 +725,7 @@ public class HighlightClassUtil {
PsiElement refQualifier = reference.getQualifier();
if (refQualifier != null) {
info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refQualifier)
.descriptionAndTooltip("Qualified class reference is not allowed in qualified new")
.descriptionAndTooltip(JavaErrorBundle.message("qualified.class.reference.not.allowed.in.qualified.new"))
.create();
QuickFixAction
.registerQuickFixAction(info, QUICK_FIX_FACTORY.createDeleteFix(refQualifier, QuickFixBundle.message("remove.qualifier.fix")));
@@ -885,7 +900,7 @@ public class HighlightClassUtil {
return HighlightUtil.checkAssignability(outerType, null, qualifier, qualifier);
}
} else {
String description = "'" + HighlightUtil.formatClass(targetClass) + "' is not an inner class";
String description = JavaErrorBundle.message("not.inner.class", HighlightUtil.formatClass(targetClass));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
}
}

View File

@@ -954,6 +954,9 @@ public class HighlightUtil {
if (PsiModifier.STATIC.equals(modifier) || privateOrProtected || PsiModifier.PACKAGE_LOCAL.equals(modifier)) {
isAllowed = modifierOwnerParent instanceof PsiClass;
}
if (PsiModifier.PUBLIC.equals(modifier)) {
isAllowed = !(modifierOwnerParent instanceof PsiDeclarationStatement);
}
}
else {
if (PsiModifier.PUBLIC.equals(modifier)) {
@@ -966,7 +969,6 @@ public class HighlightUtil {
//noinspection DuplicateExpressions
if (PsiModifier.STATIC.equals(modifier) || privateOrProtected || PsiModifier.PACKAGE_LOCAL.equals(modifier)) {
isAllowed = modifierOwnerParent instanceof PsiClass && ((PsiClass)modifierOwnerParent).getQualifiedName() != null ||
(modifierOwnerParent instanceof PsiDeclarationStatement && aClass.isRecord() && PsiModifier.STATIC.equals(modifier)) ||
FileTypeUtils.isInServerPageFile(modifierOwnerParent) ||
// non-physical dummy holder might not have FQN
!modifierOwnerParent.isPhysical();

View File

@@ -40,6 +40,7 @@ import com.intellij.psi.util.*;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.MostlySingularMultiMap;
import com.siyeh.ig.psiutils.ClassUtils;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -467,7 +468,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkClassSupersAccessibility(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkMustNotBeLocal(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkPublicClassInRightFile(aClass));
@@ -863,9 +864,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
}
else if (PsiKeyword.INTERFACE.equals(text) && parent instanceof PsiClass) {
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal((PsiClass)parent));
}
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkStaticDeclarationInInnerClass(keyword));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalVoidType(keyword));
}
@@ -1283,6 +1281,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass)owner, ref));
}
}
else if (owner instanceof PsiMethod) {
PsiClass cls = ClassUtils.getContainingStaticClass(ref);
if (cls != null && PsiTreeUtil.isAncestor(owner, cls, true)) {
String description = JavaErrorBundle.message("cannot.be.referenced.from.static.context", ref.getReferenceName());
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description).create());
}
}
}
}

View File

@@ -58,7 +58,9 @@ public enum HighlightingFeature {
return LanguageLevel.JDK_15;
}
},
SEALED_CLASSES(LanguageLevel.JDK_15_PREVIEW, "feature.sealed.classes");
SEALED_CLASSES(LanguageLevel.JDK_15_PREVIEW, "feature.sealed.classes"),
LOCAL_INTERFACES(LanguageLevel.JDK_15_PREVIEW, "feature.local.interfaces"),
LOCAL_ENUMS(LanguageLevel.JDK_15_PREVIEW, "feature.local.enums");
final LanguageLevel level;
@PropertyKey(resourceBundle = JavaErrorBundle.BUNDLE)

View File

@@ -116,8 +116,8 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (((PsiClass)parent).isInterface()) {
implicitModifiers.add(ABSTRACT);
// nested interface is implicitly static
if (grandParent instanceof PsiClass) {
// nested or local interface is implicitly static
if (!(grandParent instanceof PsiFile)) {
implicitModifiers.add(STATIC);
}
}

View File

@@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull;
public class VariableResolverProcessor extends ConflictFilterProcessor implements ElementClassHint {
private static final ElementFilter ourFilter = ElementClassFilter.VARIABLE;
private boolean myStaticScopeFlag;
private @NotNull StaticScope myStaticScopeFlag = StaticScope.NON_STATIC;
private final PsiClass myAccessClass;
private PsiElement myCurrentFileContext;
@@ -73,7 +73,10 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
public final void handleEvent(@NotNull PsiScopeProcessor.Event event, Object associated) {
super.handleEvent(event, associated);
if (JavaScopeProcessorEvent.isEnteringStaticScope(event, associated)) {
myStaticScopeFlag = true;
if (myStaticScopeFlag != StaticScope.STATIC_NO_CONSTANTS) {
myStaticScopeFlag = associated instanceof PsiClass && ((PsiClass)associated).getParent() instanceof PsiDeclarationStatement ?
StaticScope.STATIC_NO_CONSTANTS : StaticScope.STATIC;
}
}
else if (JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT.equals(event)) {
myCurrentFileContext = (PsiElement)associated;
@@ -82,12 +85,19 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
@Override
public void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) {
final boolean staticProblem = myStaticScopeFlag &&
!((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC) &&
(element instanceof PsiField || !(element instanceof PsiVariable && PsiUtil.isCompileTimeConstant((PsiVariable)element)));
final boolean staticProblem = isStaticProblem(element);
add(new CandidateInfo(element, substitutor, myPlace, myAccessClass, staticProblem, myCurrentFileContext));
}
private boolean isStaticProblem(@NotNull PsiElement element) {
if (myStaticScopeFlag == StaticScope.NON_STATIC || ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) {
return false;
}
if (element instanceof PsiField) return true;
return !(myStaticScopeFlag == StaticScope.STATIC && element instanceof PsiVariable &&
PsiUtil.isCompileTimeConstant((PsiVariable)element));
}
@Override
public boolean shouldProcess(@NotNull DeclarationKind kind) {
@@ -113,4 +123,8 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
return super.getHint(hintKey);
}
private enum StaticScope {
NON_STATIC, STATIC, STATIC_NO_CONSTANTS
}
}

View File

@@ -86,7 +86,6 @@ generics.type.arguments.on.raw.type=Type arguments given on a raw type
generics.type.arguments.on.raw.method=Type arguments given on a raw method
classes.extends.prohibited.super=Classes cannot directly extend ''{0}''
unchecked.overriding.incompatible.return.type=Unchecked overriding: return type requires unchecked conversion. Found ''{0}'', required ''{1}''
local.enum=Enum must not be local
interface.expected=Interface expected here
no.interface.expected=No interface expected here
@@ -104,7 +103,6 @@ public.class.should.be.named.after.file=Class ''{0}'' is public, should be decla
inheritance.from.final.class=Cannot inherit from {1} ''{0}''
package.name.file.path.mismatch=Package name ''{0}'' does not correspond to the file path ''{1}''
missing.package.statement=Missing package statement: ''{0}''
interface.cannot.be.local=Interface not allowed here
cyclic.inheritance=Cyclic inheritance involving ''{0}''
class.already.imported=''{0}'' is already defined in this compilation unit
class.cannot.extend.multiple.classes=Class cannot extend multiple classes
@@ -464,5 +462,17 @@ class.cannot.be.inherited.with.different.arguments={0} cannot be inherited with
bad.type.in.switch.expression=Bad type in switch expression: {0} cannot be converted to {1}
switch.expression.cannot.be.void=Target type for switch expression cannot be void
annotation.on.static.member.qualifying.type.family.name=Move type annotation
not.inner.class=''{0}'' is not an inner class
anonymous.class.implements.interface.cannot.have.qualifier=Anonymous class implements interface; cannot have qualifier for new
qualified.class.reference.not.allowed.in.qualified.new=Qualified class reference is not allowed in qualified new
actual.type.argument.contradict.inferred.type=Actual type argument and inferred type contradict each other
default.method.overrides.object.member=Default method ''{0}'' overrides a member of ''java.lang.Object''
two.methods.are.inherited.with.same.signature=Methods {0} from {1} and {2} from {3} are inherited with the same signature
cannot.select.from.parameterized.type=Cannot select from parameterized type
safevarargs.not.allowed.non.final.instance.methods=@SafeVarargs is not allowed on non-final instance methods
safevarargs.not.suppress.potentially.unsafe.operations=@SafeVarargs do not suppress potentially unsafe operations
safevarargs.not.applicable.for.reifiable.types=@SafeVarargs is not applicable for reifiable types
type.parameter.has.incompatible.upper.bounds=Type parameter {0} has incompatible upper bounds: {1}
safevarargs.not.allowed.on.methods.with.fixed.arity=@SafeVarargs is not allowed on methods with fixed arity
functional.interface.must.not.be.sealed.error.description=Functional interface can''t be declared as ''{0}''
sealed.type.inheritor.expected.modifiers={0}, {1} or {2} modifiers expected

View File

@@ -89,16 +89,16 @@ public class a {
// local interface
class cc {
void f() {
<error descr="Interface not allowed here">interface i</error> {}
<error descr="Local interfaces are not supported at language level '1.4'">interface</error> i {}
}
void ff() {
class inn {
<error descr="Interface not allowed here">interface i</error> {}
<error descr="Inner classes cannot have static declarations">interface i</error> {}
}
}
Object o = new Runnable() {
<error descr="Interface not allowed here">interface i</error> {}
<error descr="Inner classes cannot have static declarations">interface i</error> {}
public void run() {}
};
}

View File

@@ -2,7 +2,7 @@ class Foo {
void test() {
record NoComponent() {}
static record DeclaredStatic() {}
<error descr="Modifier 'static' not allowed here">static</error> record DeclaredStatic() {}
<error descr="Modifier 'private' not allowed here">private</error> record Private() {}
}
@@ -22,8 +22,19 @@ class Foo {
System.out.println(<error descr="Non-static field 'instanceVar' cannot be referenced from a static context">instanceVar</error>);
System.out.println(<error descr="Non-static variable 'outerLocal' cannot be referenced from a static context">outerLocal</error>);
System.out.println(X);
System.out.println(compileTimeConstant);
System.out.println(<error descr="Non-static variable 'compileTimeConstant' cannot be referenced from a static context">compileTimeConstant</error>);
}
}
}
<T> void typeParameter() {
record R(<error descr="'T' cannot be referenced from a static context">T</error> t) {}
}
static class Box<T> {
void test() {
T t;
record R(<error descr="'Foo.Box.this' cannot be referenced from a static context">T</error> t) {}
}
}
}

View File

@@ -145,7 +145,7 @@ interface Barz {
///////////////////////
class sss {
void f() {
<error descr="Enum must not be local">enum EEEE</error> { EE, YY };
<error descr="Local enums are not supported at language level '5'">enum</error> EEEE { EE, YY };
}
}

View File

@@ -131,7 +131,7 @@ interface Barz {
///////////////////////
class sss {
void f() {
<error descr="Enum must not be local">enum EEEE</error> { EE, YY };
<error descr="Local enums are not supported at language level '8'">enum</error> EEEE { EE, YY };
}
}

View File

@@ -0,0 +1,57 @@
class X {
void ok() {
enum Foo {
A, B, C;
void m() {
}
}
Foo.A.m();
}
void modifiers() {
<error descr="Modifier 'static' not allowed here">static</error> enum E1 {}
<error descr="Modifier 'private' not allowed here">private</error> enum E2 {}
<error descr="Modifier 'public' not allowed here">public</error> enum E3 {}
<error descr="Modifier 'protected' not allowed here">protected</error> enum E4 {}
<error descr="Modifier 'abstract' not allowed here">abstract</error> enum E5 {}
strictfp enum E6 {}
<error descr="Modifier 'final' not allowed here">final</error> enum E7 {}
}
static int sf = 0;
int f = 2;
void capture() {
int l = 5;
final int cst = 2;
enum Foo {
A, B, C {
void m() {
System.out.println(x);
System.out.println(<error descr="Non-static variable 'l' cannot be referenced from a static context">l</error>);
System.out.println(<error descr="Non-static field 'f' cannot be referenced from a static context">f</error>);
System.out.println(sf);
System.out.println(<error descr="Non-static variable 'cst' cannot be referenced from a static context">cst</error>);
}
};
int x = 2;
void m() {}
}
}
<U> U getAndSet(U u) {
enum Xyz {
A;
<error descr="'U' cannot be referenced from a static context">U</error> u;
}
U old = Xyz.A.u;
Xyz.A.u = u;
return old;
}
}

View File

@@ -0,0 +1,60 @@
class X {
void ok() {
interface Foo {
void m();
default void m2() {}
static void m3() {}
}
Foo foo = () -> {};
}
void modifiers() {
<error descr="Modifier 'static' not allowed here">static</error> interface Intf1 {}
<error descr="Modifier 'private' not allowed here">private</error> interface Intf2 {}
<error descr="Modifier 'public' not allowed here">public</error> interface Intf3 {}
<error descr="Modifier 'protected' not allowed here">protected</error> interface Intf3 {}
abstract interface Intf4 {}
strictfp interface Intf5 {}
<error descr="Modifier 'final' not allowed here">final</error> interface Intf6 {}
}
static int sf = 0;
int f = 2;
void capture() {
int l = 5;
final int cst = 2;
interface Foo {
int x = 2;
void m();
default void m2() {
System.out.println(<error descr="Non-static variable 'l' cannot be referenced from a static context">l</error>);
System.out.println(<error descr="Non-static field 'f' cannot be referenced from a static context">f</error>);
System.out.println(sf);
System.out.println(x);
System.out.println(<error descr="Non-static variable 'cst' cannot be referenced from a static context">cst</error>);
}
}
}
static <T> void typeParameter() {
interface Foo extends I<String> {
<error descr="'T' cannot be referenced from a static context">T</error> t = null;
}
interface Foo1 extends I<<error descr="'T' cannot be referenced from a static context">T</error>> {}
}
interface I<Y> {}
class Box<PARAM> {
void test() {
interface LocalI {
<error descr="'X.Box.this' cannot be referenced from a static context">PARAM</error> getParam();
}
}
}
}

View File

@@ -0,0 +1,33 @@
// 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.
package com.intellij.java.codeInsight.daemon;
import com.intellij.JavaTestUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class LightLocalEnumsInterfacesHighlightingTest extends LightJavaCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/localInterfaceEnum";
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_15;
}
public void testLocalInterface() {
doTest();
}
public void testLocalEnum() {
doTest();
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
}
}