validating android annotations
This commit is contained in:
committed by
Andrey Breslav
parent
1ee64f8186
commit
ea40389e34
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -267,6 +267,10 @@ public class JetTestUtils {
|
|||||||
return new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK/jre/lib/rt.jar");
|
return new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK/jre/lib/rt.jar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File findAndroidApiJar() {
|
||||||
|
return new File(JetTestCaseBuilder.getHomeDirectory(), "dependencies/android.jar");
|
||||||
|
}
|
||||||
|
|
||||||
public static File getAnnotationsJar() {
|
public static File getAnnotationsJar() {
|
||||||
return new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK/jre/lib/annotations.jar");
|
return new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK/jre/lib/annotations.jar");
|
||||||
}
|
}
|
||||||
@@ -280,6 +284,15 @@ public class JetTestUtils {
|
|||||||
return jdkAnnotations;
|
return jdkAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static File getAndroidSdkAnnotationsJar() {
|
||||||
|
File androidSdkAnnotations = new File("dependencies/annotations/kotlin-android-sdk-annotations.jar");
|
||||||
|
if (!androidSdkAnnotations.exists()) {
|
||||||
|
throw new RuntimeException("Kotlin Android SDK annotations jar not found; please run 'ant dist' to build it");
|
||||||
|
}
|
||||||
|
return androidSdkAnnotations;
|
||||||
|
}
|
||||||
|
|
||||||
public static void mkdirs(File file) throws IOException {
|
public static void mkdirs(File file) throws IOException {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
return;
|
return;
|
||||||
@@ -369,6 +382,9 @@ public class JetTestUtils {
|
|||||||
if (jdkKind == TestJdkKind.MOCK_JDK) {
|
if (jdkKind == TestJdkKind.MOCK_JDK) {
|
||||||
configuration.add(CLASSPATH_KEY, findMockJdkRtJar());
|
configuration.add(CLASSPATH_KEY, findMockJdkRtJar());
|
||||||
}
|
}
|
||||||
|
else if (jdkKind == TestJdkKind.ANDROID_API) {
|
||||||
|
configuration.add(CLASSPATH_KEY, findAndroidApiJar());
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
configuration.addAll(CLASSPATH_KEY, PathUtil.getJdkClassesRoots());
|
configuration.addAll(CLASSPATH_KEY, PathUtil.getJdkClassesRoots());
|
||||||
}
|
}
|
||||||
@@ -378,7 +394,11 @@ public class JetTestUtils {
|
|||||||
configuration.addAll(CLASSPATH_KEY, extraClasspath);
|
configuration.addAll(CLASSPATH_KEY, extraClasspath);
|
||||||
|
|
||||||
if (configurationKind == ALL || configurationKind == JDK_AND_ANNOTATIONS) {
|
if (configurationKind == ALL || configurationKind == JDK_AND_ANNOTATIONS) {
|
||||||
configuration.add(ANNOTATIONS_PATH_KEY, getJdkAnnotationsJar());
|
if (jdkKind == TestJdkKind.ANDROID_API) {
|
||||||
|
configuration.add(ANNOTATIONS_PATH_KEY, getAndroidSdkAnnotationsJar());
|
||||||
|
} else {
|
||||||
|
configuration.add(ANNOTATIONS_PATH_KEY, getJdkAnnotationsJar());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,4 +19,5 @@ package org.jetbrains.jet;
|
|||||||
public enum TestJdkKind {
|
public enum TestJdkKind {
|
||||||
MOCK_JDK,
|
MOCK_JDK,
|
||||||
FULL_JDK,
|
FULL_JDK,
|
||||||
|
ANDROID_API,
|
||||||
}
|
}
|
||||||
|
|||||||
+164
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.Maps;
|
||||||
|
import com.intellij.openapi.Disposable;
|
||||||
|
import com.intellij.openapi.util.Disposer;
|
||||||
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
|
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver;
|
||||||
|
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.TypeTransformingVisitor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class AbstractSdkAnnotationsValidityTest extends UsefulTestCase {
|
||||||
|
|
||||||
|
private static final int CLASSES_IN_CHUNK = 100;
|
||||||
|
|
||||||
|
protected abstract JetCoreEnvironment createEnvironment(Disposable parentDisposable);
|
||||||
|
|
||||||
|
protected abstract List<FqName> getClassesToValidate() throws IOException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
TypeTransformingVisitor.setStrictMode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
TypeTransformingVisitor.setStrictMode(false);
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoErrorsInAlternativeSignatures() throws IOException {
|
||||||
|
List<FqName> affectedClasses = getClassesToValidate();
|
||||||
|
|
||||||
|
Map<String, List<String>> errors = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
for (int chunkIndex = 0; chunkIndex < affectedClasses.size() / CLASSES_IN_CHUNK + 1; chunkIndex++) {
|
||||||
|
Disposable parentDisposable = Disposer.newDisposable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
JetCoreEnvironment commonEnvironment = createEnvironment(parentDisposable);
|
||||||
|
|
||||||
|
BindingTrace trace = new BindingTraceContext();
|
||||||
|
InjectorForJavaDescriptorResolver injector =
|
||||||
|
InjectorForJavaDescriptorResolverUtil.create(commonEnvironment.getProject(), trace);
|
||||||
|
|
||||||
|
BindingContext bindingContext = trace.getBindingContext();
|
||||||
|
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);
|
||||||
|
PackageViewDescriptor topLevelPackage = injector.getModule().getPackage(javaClass);
|
||||||
|
if (topLevelClass == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
topLevelClass.acceptVoid(visitor);
|
||||||
|
|
||||||
|
if (topLevelPackage != null) {
|
||||||
|
topLevelPackage.acceptVoid(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Disposer.dispose(parentDisposable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
StringBuilder sb = new StringBuilder("Error(s) in SDK alternative signatures: \n");
|
||||||
|
for (Map.Entry<String, List<String>> entry : errors.entrySet()) {
|
||||||
|
sb.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
|
||||||
|
}
|
||||||
|
fail(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AlternativeSignatureErrorFindingVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, Void> {
|
||||||
|
private final BindingContext bindingContext;
|
||||||
|
private final Map<String, List<String>> errors;
|
||||||
|
|
||||||
|
public AlternativeSignatureErrorFindingVisitor(BindingContext bindingContext, Map<String, List<String>> errors) {
|
||||||
|
this.bindingContext = bindingContext;
|
||||||
|
this.errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitPackageViewDescriptor(PackageViewDescriptor descriptor, Void data) {
|
||||||
|
return visitDeclarationRecursively(descriptor, descriptor.getMemberScope());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitClassDescriptor(ClassDescriptor descriptor, Void data) {
|
||||||
|
// skip java.util.Collection, etc.
|
||||||
|
if (!JavaToKotlinClassMap.getInstance().mapPlatformClass(DescriptorUtils.getFqNameSafe(descriptor)).isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return visitDeclarationRecursively(descriptor, descriptor.getDefaultType().getMemberScope());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) {
|
||||||
|
return visitDeclaration(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) {
|
||||||
|
return visitDeclaration(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
List<String> errors = bindingContext.get(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor);
|
||||||
|
if (errors != null) {
|
||||||
|
this.errors.put(DescriptorRenderer.TEXT.render(descriptor), errors);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Void visitDeclarationRecursively(@NotNull DeclarationDescriptor descriptor, @NotNull JetScope memberScope) {
|
||||||
|
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
|
||||||
|
member.acceptVoid(this);
|
||||||
|
}
|
||||||
|
return visitDeclaration(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.openapi.Disposable;
|
||||||
|
import org.jetbrains.jet.ConfigurationKind;
|
||||||
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
|
import org.jetbrains.jet.TestJdkKind;
|
||||||
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
|
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
|
public class AndroidSdkAnnotationsValidityTest extends AbstractSdkAnnotationsValidityTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JetCoreEnvironment createEnvironment(Disposable parentDisposable) {
|
||||||
|
CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests(
|
||||||
|
ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.ANDROID_API, JetTestUtils.getAnnotationsJar());
|
||||||
|
return JetCoreEnvironment.createForTests(parentDisposable, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<FqName> getClassesToValidate() throws IOException {
|
||||||
|
JarFile jar = new JarFile(JetTestUtils.findAndroidApiJar());
|
||||||
|
try {
|
||||||
|
Enumeration<JarEntry> entries = jar.entries();
|
||||||
|
Set<FqName> result = Sets.newLinkedHashSet();
|
||||||
|
while (entries.hasMoreElements()){
|
||||||
|
JarEntry entry = entries.nextElement();
|
||||||
|
String entryName = entry.getName();
|
||||||
|
if (!entry.isDirectory() && entryName.endsWith(".class")) {
|
||||||
|
String className = entryName.substring(0, entryName.length() - ".class".length()).replace("/", ".").replace("$", ".");
|
||||||
|
result.add(new FqName(className));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Lists.newArrayList(result);
|
||||||
|
} finally {
|
||||||
|
jar.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.jet.jvm.compiler;
|
package org.jetbrains.jet.jvm.compiler;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
@@ -27,7 +26,6 @@ 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.testFramework.UsefulTestCase;
|
|
||||||
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;
|
||||||
@@ -35,31 +33,18 @@ import org.jetbrains.jet.TestJdkKind;
|
|||||||
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||||
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver;
|
|
||||||
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.TypeTransformingVisitor;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
|
|
||||||
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.renderer.DescriptorRenderer;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
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 JdkAnnotationsValidityTest extends UsefulTestCase {
|
public class JdkAnnotationsValidityTest extends AbstractSdkAnnotationsValidityTest {
|
||||||
|
|
||||||
private static final int CLASSES_IN_CHUNK = 500;
|
|
||||||
|
|
||||||
// KT-4359 Alternative signature checking problem: Set<?> is incompatible with Set<Object>
|
// KT-4359 Alternative signature checking problem: Set<?> is incompatible with Set<Object>
|
||||||
//
|
//
|
||||||
@@ -81,7 +66,7 @@ public class JdkAnnotationsValidityTest extends UsefulTestCase {
|
|||||||
// [Incompatible types in superclasses: [Any?, Any, Any], Incompatible projection kinds in type arguments of super methods' return types: [out Any?, Any, Any]]
|
// [Incompatible types in superclasses: [Any?, Any, Any], Incompatible projection kinds in type arguments of super methods' return types: [out Any?, Any, Any]]
|
||||||
private static final Set<String> classesToIgnore = new HashSet<String>(Arrays.asList("javax.management.openmbean.TabularDataSupport"));
|
private static final Set<String> classesToIgnore = new HashSet<String>(Arrays.asList("javax.management.openmbean.TabularDataSupport"));
|
||||||
|
|
||||||
private static JetCoreEnvironment createEnvironment(Disposable parentDisposable) {
|
private static JetCoreEnvironment createFullJdkEnvironment(Disposable parentDisposable) {
|
||||||
CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests(
|
CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests(
|
||||||
ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK, JetTestUtils.getAnnotationsJar());
|
ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK, JetTestUtils.getAnnotationsJar());
|
||||||
configuration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, new File("ideaSDK/lib/jdkAnnotations.jar"));
|
configuration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, new File("ideaSDK/lib/jdkAnnotations.jar"));
|
||||||
@@ -89,72 +74,20 @@ public class JdkAnnotationsValidityTest extends UsefulTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected JetCoreEnvironment createEnvironment(Disposable parentDisposable) {
|
||||||
super.setUp();
|
return createFullJdkEnvironment(parentDisposable);
|
||||||
TypeTransformingVisitor.setStrictMode(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected List<FqName> getClassesToValidate() throws IOException {
|
||||||
TypeTransformingVisitor.setStrictMode(false);
|
return getAffectedClasses("jar://dependencies/annotations/kotlin-jdk-annotations.jar!/");
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNoErrorsInAlternativeSignatures() {
|
|
||||||
List<FqName> affectedClasses = getAffectedClasses("jar://dependencies/annotations/kotlin-jdk-annotations.jar!/");
|
|
||||||
|
|
||||||
Map<String, List<String>> errors = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
for (int chunkIndex = 0; chunkIndex < affectedClasses.size() / CLASSES_IN_CHUNK + 1; chunkIndex++) {
|
|
||||||
Disposable parentDisposable = Disposer.newDisposable();
|
|
||||||
|
|
||||||
try {
|
|
||||||
JetCoreEnvironment commonEnvironment = createEnvironment(parentDisposable);
|
|
||||||
|
|
||||||
BindingTrace trace = new BindingTraceContext();
|
|
||||||
InjectorForJavaDescriptorResolver injector =
|
|
||||||
InjectorForJavaDescriptorResolverUtil.create(commonEnvironment.getProject(), trace);
|
|
||||||
|
|
||||||
BindingContext bindingContext = trace.getBindingContext();
|
|
||||||
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);
|
|
||||||
PackageViewDescriptor topLevelPackage = injector.getModule().getPackage(javaClass);
|
|
||||||
if (topLevelClass == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
topLevelClass.acceptVoid(visitor);
|
|
||||||
|
|
||||||
if (topLevelPackage != null) {
|
|
||||||
topLevelPackage.acceptVoid(visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Disposer.dispose(parentDisposable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
StringBuilder sb = new StringBuilder("Error(s) in JDK alternative signatures: \n");
|
|
||||||
for (Map.Entry<String, List<String>> entry : errors.entrySet()) {
|
|
||||||
sb.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
|
|
||||||
}
|
|
||||||
fail(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<FqName> getAffectedClasses(String rootUrl) {
|
static List<FqName> getAffectedClasses(String rootUrl) {
|
||||||
Disposable myDisposable = Disposer.newDisposable();
|
Disposable myDisposable = Disposer.newDisposable();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
createEnvironment(myDisposable);
|
createFullJdkEnvironment(myDisposable);
|
||||||
|
|
||||||
VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(rootUrl);
|
VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(rootUrl);
|
||||||
assert root != null;
|
assert root != null;
|
||||||
@@ -189,58 +122,4 @@ public class JdkAnnotationsValidityTest extends UsefulTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AlternativeSignatureErrorFindingVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, Void> {
|
|
||||||
private final BindingContext bindingContext;
|
|
||||||
private final Map<String, List<String>> errors;
|
|
||||||
|
|
||||||
public AlternativeSignatureErrorFindingVisitor(BindingContext bindingContext, Map<String, List<String>> errors) {
|
|
||||||
this.bindingContext = bindingContext;
|
|
||||||
this.errors = errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitPackageViewDescriptor(PackageViewDescriptor descriptor, Void data) {
|
|
||||||
return visitDeclarationRecursively(descriptor, descriptor.getMemberScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitClassDescriptor(ClassDescriptor descriptor, Void data) {
|
|
||||||
// skip java.util.Collection, etc.
|
|
||||||
if (!JavaToKotlinClassMap.getInstance().mapPlatformClass(DescriptorUtils.getFqNameSafe(descriptor)).isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return visitDeclarationRecursively(descriptor, descriptor.getDefaultType().getMemberScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) {
|
|
||||||
return visitDeclaration(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) {
|
|
||||||
return visitDeclaration(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
List<String> errors = bindingContext.get(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor);
|
|
||||||
if (errors != null) {
|
|
||||||
this.errors.put(DescriptorRenderer.TEXT.render(descriptor), errors);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Void visitDeclarationRecursively(@NotNull DeclarationDescriptor descriptor, @NotNull JetScope memberScope) {
|
|
||||||
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
|
|
||||||
if (member instanceof DeclarationDescriptorWithVisibility
|
|
||||||
&& ((DeclarationDescriptorWithVisibility) member).getVisibility().isPublicAPI()) {
|
|
||||||
member.acceptVoid(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return visitDeclaration(descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,16 @@
|
|||||||
<mapper type="merge" to="closure-compiler.jar"/>
|
<mapper type="merge" to="closure-compiler.jar"/>
|
||||||
</unzip>
|
</unzip>
|
||||||
|
|
||||||
|
<delete file="dependencies/android.jar" failonerror="false"/>
|
||||||
|
<get src="http://dl-ssl.google.com/android/repository/android-19_r02.zip"
|
||||||
|
dest="dependencies/download/android-sdk.zip" usetimestamp="true"/>
|
||||||
|
<unzip src="dependencies/download/android-sdk.zip" dest="dependencies">
|
||||||
|
<patternset>
|
||||||
|
<include name="**/android.jar"/>
|
||||||
|
</patternset>
|
||||||
|
<mapper type="flatten"/>
|
||||||
|
</unzip>
|
||||||
|
|
||||||
<!-- Bootstrap compiler -->
|
<!-- Bootstrap compiler -->
|
||||||
<get src="http://teamcity.jetbrains.com/guestAuth/repository/download/bt345/bootstrap.tcbuildtag/kotlin-plugin-{build.number}.zip"
|
<get src="http://teamcity.jetbrains.com/guestAuth/repository/download/bt345/bootstrap.tcbuildtag/kotlin-plugin-{build.number}.zip"
|
||||||
dest="dependencies/download/bootstrap-compiler.zip" usetimestamp="true"/>
|
dest="dependencies/download/bootstrap-compiler.zip" usetimestamp="true"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user