Optimized memory usage in test checking for errors in JDK annotations.
This commit is contained in:
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-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 org.jetbrains.jet.jvm.compiler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.codeInsight.AnnotationUtil;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.psi.util.PsiFormatUtil;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.ConfigurationKind;
|
||||||
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
|
import org.jetbrains.jet.TestJdkKind;
|
||||||
|
import org.jetbrains.jet.cli.jvm.compiler.CoreExternalAnnotationsManager;
|
||||||
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.KotlinTestWithEnvironment;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
|
||||||
|
private VirtualFile kotlinAnnotationsRoot;
|
||||||
|
private VirtualFile ideaAnnotationsRoot;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JetCoreEnvironment createEnvironment() {
|
||||||
|
return JetTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
|
||||||
|
myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
kotlinAnnotationsRoot = VirtualFileManager.getInstance().findFileByUrl("file://jdk-annotations");
|
||||||
|
ideaAnnotationsRoot = VirtualFileManager.getInstance().findFileByUrl("jar://ideaSDK/lib/jdkAnnotations.jar!/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
ideaAnnotationsRoot = null;
|
||||||
|
kotlinAnnotationsRoot = null;
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private CoreExternalAnnotationsManager createFakeAnnotationsManager(VirtualFile annotationsRoot) {
|
||||||
|
CoreExternalAnnotationsManager annotationsManager = new CoreExternalAnnotationsManager(PsiManager.getInstance(getProject()));
|
||||||
|
annotationsManager.addExternalAnnotationsRoot(annotationsRoot);
|
||||||
|
return annotationsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllIdeaJdkAnnotationsAreReflected() {
|
||||||
|
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(getProject());
|
||||||
|
GlobalSearchScope allScope = GlobalSearchScope.allScope(getProject());
|
||||||
|
|
||||||
|
final CoreExternalAnnotationsManager kotlinFakeAnnotationsManager = createFakeAnnotationsManager(kotlinAnnotationsRoot);
|
||||||
|
final CoreExternalAnnotationsManager ideaFakeAnnotationsManager = createFakeAnnotationsManager(ideaAnnotationsRoot);
|
||||||
|
|
||||||
|
final Set<PsiModifierListOwner> declarationsWithMissingAnnotations = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
|
for (FqName classFqName : JdkAnnotationsSanityTest.getAffectedClasses("jar://ideaSDK/lib/jdkAnnotations.jar!/")) {
|
||||||
|
if (new FqName("org.jdom").equals(classFqName.parent())) continue; // filter unrelated jdom annotations
|
||||||
|
if (new FqName("java.util.concurrent.TransferQueue").equals(classFqName)) continue; // filter JDK7-specific class
|
||||||
|
|
||||||
|
PsiClass psiClass = javaPsiFacade.findClass(classFqName.getFqName(), allScope);
|
||||||
|
assertNotNull("Class has annotation, but it is not found: " + classFqName, psiClass);
|
||||||
|
|
||||||
|
psiClass.accept(new JavaRecursiveElementVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitMethod(PsiMethod method) {
|
||||||
|
super.visitMethod(method);
|
||||||
|
if (method.getReturnType() != null) { // disabled for constructors
|
||||||
|
check(method, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitField(PsiField field) {
|
||||||
|
super.visitField(field);
|
||||||
|
check(field, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitParameter(PsiParameter parameter) {
|
||||||
|
super.visitParameter(parameter);
|
||||||
|
PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
|
||||||
|
assert method != null;
|
||||||
|
if (method.getReturnType() != null) { // disabled for constructors
|
||||||
|
check(parameter, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check(@NotNull PsiModifierListOwner ideaOwner, @NotNull PsiModifierListOwner kotlinOwner) {
|
||||||
|
if (hasAnnotation(ideaFakeAnnotationsManager, ideaOwner, AnnotationUtil.NOT_NULL)) {
|
||||||
|
boolean kotlinHasNotNull = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, AnnotationUtil.NOT_NULL);
|
||||||
|
boolean kotlinHasKotlinSignature = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner,
|
||||||
|
JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName());
|
||||||
|
if (kotlinOwner == ideaOwner && kotlinHasNotNull || kotlinHasKotlinSignature) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
declarationsWithMissingAnnotations.add(kotlinOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasAnnotation(
|
||||||
|
@NotNull CoreExternalAnnotationsManager annotationsManager,
|
||||||
|
@NotNull PsiModifierListOwner owner,
|
||||||
|
@NotNull String annotationFqName
|
||||||
|
) {
|
||||||
|
return annotationsManager.findExternalAnnotation(owner, annotationFqName) != null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!declarationsWithMissingAnnotations.isEmpty()) {
|
||||||
|
StringBuilder builder = new StringBuilder("Annotations missing for JDK items:\n");
|
||||||
|
for (PsiModifierListOwner declaration : declarationsWithMissingAnnotations) {
|
||||||
|
builder.append(PsiFormatUtil.getExternalName(declaration)).append("\n");
|
||||||
|
}
|
||||||
|
fail(builder.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,24 +16,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.jvm.compiler;
|
package org.jetbrains.jet.jvm.compiler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.codeInsight.AnnotationUtil;
|
|
||||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||||
|
import com.intellij.openapi.Disposable;
|
||||||
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.io.StreamUtil;
|
import com.intellij.openapi.util.io.StreamUtil;
|
||||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
|
||||||
import com.intellij.psi.util.PsiFormatUtil;
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.ConfigurationKind;
|
import org.jetbrains.jet.ConfigurationKind;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.TestJdkKind;
|
import org.jetbrains.jet.TestJdkKind;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.CoreExternalAnnotationsManager;
|
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -41,8 +40,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMap;
|
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMap;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinTestWithEnvironment;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
@@ -54,171 +51,105 @@ import java.util.Set;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class JdkAnnotationsSanityTest extends KotlinTestWithEnvironment {
|
public class JdkAnnotationsSanityTest extends UsefulTestCase {
|
||||||
private VirtualFile kotlinAnnotationsRoot;
|
|
||||||
private VirtualFile ideaAnnotationsRoot;
|
|
||||||
|
|
||||||
@Override
|
private static final int CLASSES_IN_CHUNK = 500;
|
||||||
protected JetCoreEnvironment createEnvironment() {
|
|
||||||
|
private static JetCoreEnvironment createEnvironment(Disposable parentDisposable) {
|
||||||
return JetTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
|
return JetTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
|
||||||
myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK);
|
parentDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
kotlinAnnotationsRoot = VirtualFileManager.getInstance().findFileByUrl("file://jdk-annotations");
|
|
||||||
ideaAnnotationsRoot = VirtualFileManager.getInstance().findFileByUrl("jar://ideaSDK/lib/jdkAnnotations.jar!/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
ideaAnnotationsRoot = null;
|
|
||||||
kotlinAnnotationsRoot = null;
|
|
||||||
super.tearDown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoErrorsInAlternativeSignatures() {
|
public void testNoErrorsInAlternativeSignatures() {
|
||||||
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(getProject());
|
List<FqName> affectedClasses = getAffectedClasses("file://jdk-annotations");
|
||||||
|
|
||||||
final BindingContext bindingContext = injector.getBindingTrace().getBindingContext();
|
final Map<String, List<String>> errors = Maps.newHashMap();
|
||||||
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
|
||||||
|
|
||||||
final Map<DeclarationDescriptor, List<String>> errors = Maps.newHashMap();
|
for (int chunkIndex = 0; chunkIndex < affectedClasses.size() / CLASSES_IN_CHUNK + 1; chunkIndex++) {
|
||||||
|
Disposable parentDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||||
|
|
||||||
Iterable<FqName> affectedClasses = getAffectedClasses(kotlinAnnotationsRoot);
|
try {
|
||||||
AlternativeSignatureErrorFindingVisitor visitor = new AlternativeSignatureErrorFindingVisitor(bindingContext, errors);
|
JetCoreEnvironment commonEnvironment = createEnvironment(parentDisposable);
|
||||||
for (FqName javaClass : affectedClasses) {
|
|
||||||
ClassDescriptor topLevelClass = javaDescriptorResolver.resolveClass(javaClass);
|
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(commonEnvironment.getProject());
|
||||||
NamespaceDescriptor topLevelNamespace = javaDescriptorResolver.resolveNamespace(javaClass);
|
|
||||||
if (topLevelClass == null) {
|
BindingContext bindingContext = injector.getBindingTrace().getBindingContext();
|
||||||
continue;
|
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||||
|
|
||||||
|
AlternativeSignatureErrorFindingVisitor visitor = new AlternativeSignatureErrorFindingVisitor(bindingContext, errors);
|
||||||
|
|
||||||
|
int chunkStart = chunkIndex * CLASSES_IN_CHUNK;
|
||||||
|
for (FqName javaClass : affectedClasses.subList(chunkStart, Math.min(chunkStart + CLASSES_IN_CHUNK, affectedClasses.size()))) {
|
||||||
|
ClassDescriptor topLevelClass = javaDescriptorResolver.resolveClass(javaClass);
|
||||||
|
NamespaceDescriptor topLevelNamespace = javaDescriptorResolver.resolveNamespace(javaClass);
|
||||||
|
if (topLevelClass == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
topLevelClass.acceptVoid(visitor);
|
||||||
|
|
||||||
|
if (topLevelNamespace != null) {
|
||||||
|
topLevelNamespace.acceptVoid(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
topLevelClass.acceptVoid(visitor);
|
Disposer.dispose(parentDisposable);
|
||||||
|
|
||||||
if (topLevelNamespace != null) {
|
|
||||||
topLevelNamespace.acceptVoid(visitor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
StringBuilder sb = new StringBuilder("Error(s) in JDK alternative signatures: \n");
|
StringBuilder sb = new StringBuilder("Error(s) in JDK alternative signatures: \n");
|
||||||
for (Map.Entry<DeclarationDescriptor, List<String>> entry : errors.entrySet()) {
|
for (Map.Entry<String, List<String>> entry : errors.entrySet()) {
|
||||||
sb.append(DescriptorRenderer.TEXT.render(entry.getKey())).append(" : ").append(entry.getValue()).append("\n");
|
sb.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
|
||||||
}
|
}
|
||||||
fail(sb.toString());
|
fail(sb.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CoreExternalAnnotationsManager createFakeAnnotationsManager(VirtualFile annotationsRoot) {
|
static List<FqName> getAffectedClasses(final String rootUrl) {
|
||||||
CoreExternalAnnotationsManager annotationsManager = new CoreExternalAnnotationsManager(PsiManager.getInstance(getProject()));
|
Disposable myDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||||
annotationsManager.addExternalAnnotationsRoot(annotationsRoot);
|
|
||||||
return annotationsManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllIdeaJdkAnnotationsAreReflected() {
|
try {
|
||||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(getProject());
|
createEnvironment(myDisposable);
|
||||||
GlobalSearchScope allScope = GlobalSearchScope.allScope(getProject());
|
|
||||||
|
|
||||||
final CoreExternalAnnotationsManager kotlinFakeAnnotationsManager = createFakeAnnotationsManager(kotlinAnnotationsRoot);
|
VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(rootUrl);
|
||||||
final CoreExternalAnnotationsManager ideaFakeAnnotationsManager = createFakeAnnotationsManager(ideaAnnotationsRoot);
|
assert root != null;
|
||||||
|
|
||||||
final Set<PsiModifierListOwner> declarationsWithMissingAnnotations = Sets.newLinkedHashSet();
|
final Set<FqName> result = Sets.newLinkedHashSet();
|
||||||
|
VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor() {
|
||||||
for (FqName classFqName : getAffectedClasses(ideaAnnotationsRoot)) {
|
|
||||||
if (new FqName("org.jdom").equals(classFqName.parent())) continue; // filter unrelated jdom annotations
|
|
||||||
if (new FqName("java.util.concurrent.TransferQueue").equals(classFqName)) continue; // filter JDK7-specific class
|
|
||||||
|
|
||||||
PsiClass psiClass = javaPsiFacade.findClass(classFqName.getFqName(), allScope);
|
|
||||||
assertNotNull("Class has annotation, but it is not found: " + classFqName, psiClass);
|
|
||||||
|
|
||||||
psiClass.accept(new JavaRecursiveElementVisitor() {
|
|
||||||
@Override
|
@Override
|
||||||
public void visitMethod(PsiMethod method) {
|
public boolean visitFile(@NotNull VirtualFile file) {
|
||||||
super.visitMethod(method);
|
if (ExternalAnnotationsManager.ANNOTATIONS_XML.equals(file.getName())) {
|
||||||
if (method.getReturnType() != null) { // disabled for constructors
|
try {
|
||||||
check(method, method);
|
String text = StreamUtil.readText(file.getInputStream());
|
||||||
}
|
Matcher matcher = Pattern.compile("<item name=['\"]([\\w\\d\\.]+)[\\s'\"]").matcher(text);
|
||||||
}
|
while (matcher.find()) {
|
||||||
|
result.add(new FqName(matcher.group(1)));
|
||||||
@Override
|
}
|
||||||
public void visitField(PsiField field) {
|
|
||||||
super.visitField(field);
|
|
||||||
check(field, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitParameter(PsiParameter parameter) {
|
|
||||||
super.visitParameter(parameter);
|
|
||||||
PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
|
|
||||||
assert method != null;
|
|
||||||
if (method.getReturnType() != null) { // disabled for constructors
|
|
||||||
check(parameter, method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void check(@NotNull PsiModifierListOwner ideaOwner, @NotNull PsiModifierListOwner kotlinOwner) {
|
|
||||||
if (hasAnnotation(ideaFakeAnnotationsManager, ideaOwner, AnnotationUtil.NOT_NULL)) {
|
|
||||||
boolean kotlinHasNotNull = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, AnnotationUtil.NOT_NULL);
|
|
||||||
boolean kotlinHasKotlinSignature = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner,
|
|
||||||
JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName());
|
|
||||||
if (kotlinOwner == ideaOwner && kotlinHasNotNull || kotlinHasKotlinSignature) {
|
|
||||||
// good
|
|
||||||
}
|
}
|
||||||
else {
|
catch (IOException e) {
|
||||||
declarationsWithMissingAnnotations.add(kotlinOwner);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
|
|
||||||
private boolean hasAnnotation(
|
|
||||||
@NotNull CoreExternalAnnotationsManager annotationsManager,
|
|
||||||
@NotNull PsiModifierListOwner owner,
|
|
||||||
@NotNull String annotationFqName
|
|
||||||
) {
|
|
||||||
return annotationsManager.findExternalAnnotation(owner, annotationFqName) != null;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return Lists.newArrayList(result);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Disposer.dispose(myDisposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!declarationsWithMissingAnnotations.isEmpty()) {
|
|
||||||
StringBuilder builder = new StringBuilder("Annotations missing for JDK items:\n");
|
|
||||||
for (PsiModifierListOwner declaration : declarationsWithMissingAnnotations) {
|
|
||||||
builder.append(PsiFormatUtil.getExternalName(declaration)).append("\n");
|
|
||||||
}
|
|
||||||
fail(builder.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Iterable<FqName> getAffectedClasses(final VirtualFile root) {
|
|
||||||
final Set<FqName> result = Sets.newLinkedHashSet();
|
|
||||||
VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor() {
|
|
||||||
@Override
|
|
||||||
public boolean visitFile(@NotNull VirtualFile file) {
|
|
||||||
if (ExternalAnnotationsManager.ANNOTATIONS_XML.equals(file.getName())) {
|
|
||||||
try {
|
|
||||||
String text = StreamUtil.readText(file.getInputStream());
|
|
||||||
Matcher matcher = Pattern.compile("<item name=['\"]([\\w\\d\\.]+)[\\s'\"]").matcher(text);
|
|
||||||
while (matcher.find()) {
|
|
||||||
result.add(new FqName(matcher.group(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AlternativeSignatureErrorFindingVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, Void> {
|
private static class AlternativeSignatureErrorFindingVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, Void> {
|
||||||
private final BindingContext bindingContext;
|
private final BindingContext bindingContext;
|
||||||
private final Map<DeclarationDescriptor, List<String>> errors;
|
private final Map<String, List<String>> errors;
|
||||||
|
|
||||||
public AlternativeSignatureErrorFindingVisitor(BindingContext bindingContext, Map<DeclarationDescriptor, List<String>> errors) {
|
public AlternativeSignatureErrorFindingVisitor(BindingContext bindingContext, Map<String, List<String>> errors) {
|
||||||
this.bindingContext = bindingContext;
|
this.bindingContext = bindingContext;
|
||||||
this.errors = errors;
|
this.errors = errors;
|
||||||
}
|
}
|
||||||
@@ -251,7 +182,7 @@ public class JdkAnnotationsSanityTest extends KotlinTestWithEnvironment {
|
|||||||
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||||
List<String> errors = bindingContext.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor);
|
List<String> errors = bindingContext.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor);
|
||||||
if (errors != null) {
|
if (errors != null) {
|
||||||
this.errors.put(descriptor, errors);
|
this.errors.put(DescriptorRenderer.TEXT.render(descriptor), errors);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user