[java] correct language levels for array stub classes (IDEA-152384)

This commit is contained in:
Roman Shevchenko
2016-03-04 12:20:55 +01:00
parent f872a3d7f5
commit 54c811b9c7
2 changed files with 50 additions and 27 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -48,10 +49,23 @@ import java.util.Map;
import java.util.concurrent.ConcurrentMap;
public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements PsiElementFactory {
private PsiClass myArrayClass;
private PsiClass myArrayClass15;
private final ConcurrentMap<GlobalSearchScope, PsiClassType> myCachedObjectType =
ContainerUtil.newConcurrentMap();
private final NotNullLazyValue<PsiClass> myArrayClass = new NotNullLazyValue<PsiClass>() {
@NotNull
@Override
protected PsiClass compute() {
return createArrayClass("public class __Array__{\n public final int length;\n public Object clone() {}\n}", LanguageLevel.JDK_1_3);
}
};
private final NotNullLazyValue<PsiClass> myArrayClass15 = new NotNullLazyValue<PsiClass>() {
@NotNull
@Override
protected PsiClass compute() {
return createArrayClass("public class __Array__<T> {\n public final int length;\n public T[] clone() {}\n}", LanguageLevel.JDK_1_5);
}
};
private final ConcurrentMap<GlobalSearchScope, PsiClassType> myCachedObjectType = ContainerUtil.newConcurrentMap();
public PsiElementFactoryImpl(final PsiManagerEx manager) {
super(manager);
@@ -65,23 +79,17 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
@NotNull
@Override
public PsiClass getArrayClass(@NotNull final LanguageLevel languageLevel) {
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) {
if (myArrayClass == null) {
@NonNls final String body = "public class __Array__{\n public final int length;\n public Object clone() {}\n}";
myArrayClass = ((PsiExtensibleClass)createClassFromText(body, null)).getOwnInnerClasses().get(0);
ensureNonWritable(myArrayClass);
}
return myArrayClass;
}
else {
if (myArrayClass15 == null) {
@NonNls final String body = "public class __Array__<T>{\n public final int length;\n public T[] clone() {}\n}";
myArrayClass15 = ((PsiExtensibleClass)createClassFromText(body, null)).getOwnInnerClasses().get(0);
ensureNonWritable(myArrayClass15);
}
return myArrayClass15;
}
public PsiClass getArrayClass(@NotNull LanguageLevel languageLevel) {
return (languageLevel.isAtLeast(LanguageLevel.JDK_1_5) ? myArrayClass15 : myArrayClass).getValue();
}
private PsiClass createArrayClass(String text, LanguageLevel level) {
PsiClass psiClass = ((PsiExtensibleClass)createClassFromText(text, null)).getOwnInnerClasses().get(0);
ensureNonWritable(psiClass);
PsiFile file = psiClass.getContainingFile();
((PsiJavaFileBaseImpl)file).clearCaches();
PsiUtil.FILE_LANGUAGE_LEVEL_KEY.set(file, level);
return psiClass;
}
private static void ensureNonWritable(PsiClass arrayClass) {
@@ -438,6 +446,9 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
else {
text = aClass.getName();
}
if (text == null) {
throw new IncorrectOperationException("Invalid class: " + aClass);
}
return new LightClassReference(myManager, text, aClass);
}
@@ -815,4 +826,4 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
private boolean isIdentifier(@NotNull String name) {
return PsiNameHelper.getInstance(myManager.getProject()).isIdentifier(name);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,16 @@
*/
package com.intellij.psi.impl;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElementFactory;
import com.intellij.testFramework.LightIdeaTestCase;
import com.intellij.psi.util.PsiUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.IncorrectOperationException;
public class JavaElementFactoryTest extends LightIdeaTestCase {
import static com.intellij.testFramework.LightCodeInsightTestCase.getJavaFacade;
public class JavaElementFactoryTest extends LightCodeInsightFixtureTestCase {
private PsiElementFactory myFactory;
@Override
@@ -39,4 +44,11 @@ public class JavaElementFactoryTest extends LightIdeaTestCase {
}
catch (IncorrectOperationException ignored) { }
}
}
public void testArrayClassLanguageLevel() {
PsiClass arrayClass3 = myFactory.getArrayClass(LanguageLevel.JDK_1_4);
PsiClass arrayClass5 = myFactory.getArrayClass(LanguageLevel.HIGHEST);
assertEquals(LanguageLevel.JDK_1_3, PsiUtil.getLanguageLevel(arrayClass3));
assertEquals(LanguageLevel.JDK_1_5, PsiUtil.getLanguageLevel(arrayClass5));
}
}