Validate descriptors loaded in tests
This commit is contained in:
+2
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.test.TestCaseWithTmpdir;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||
import org.junit.Assert;
|
||||
|
||||
@@ -70,6 +71,7 @@ public abstract class AbstractCompileKotlinAgainstCustomJavaTest extends TestCas
|
||||
NamespaceDescriptor namespaceDescriptor = bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, namespaceFqn);
|
||||
assertNotNull("Failed to find namespace: " + namespaceFqn, namespaceDescriptor);
|
||||
|
||||
DescriptorValidator.validate(namespaceDescriptor);
|
||||
compareNamespaceWithFile(namespaceDescriptor, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.test.TestCaseWithTmpdir;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||
|
||||
import java.io.File;
|
||||
@@ -55,8 +56,12 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir
|
||||
TEST_PACKAGE_FQNAME);
|
||||
assert namespaceFromSource != null;
|
||||
Assert.assertEquals("test", namespaceFromSource.getName().asString());
|
||||
|
||||
DescriptorValidator.validate(namespaceFromSource);
|
||||
|
||||
NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot(
|
||||
tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first;
|
||||
|
||||
compareNamespaces(namespaceFromSource, namespaceFromClass,
|
||||
NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT
|
||||
.checkPrimaryConstructors(true)
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.test.TestCaseWithTmpdir;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
@@ -164,6 +165,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
LoadDescriptorUtil.TEST_PACKAGE_FQNAME, DescriptorSearchRule.INCLUDE_KOTLIN);
|
||||
assert namespaceDescriptor != null : "Test namespace not found";
|
||||
|
||||
DescriptorValidator.validate(namespaceDescriptor);
|
||||
checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.GenerationUtils;
|
||||
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
@@ -42,13 +42,15 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.jet.JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations;
|
||||
import static org.jetbrains.jet.lang.psi.JetPsiFactory.createFile;
|
||||
|
||||
public final class LoadDescriptorUtil {
|
||||
|
||||
@@ -105,6 +107,8 @@ public final class LoadDescriptorUtil {
|
||||
NamespaceDescriptor namespaceDescriptor =
|
||||
javaDescriptorResolver.resolveNamespace(TEST_PACKAGE_FQNAME, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||
assert namespaceDescriptor != null;
|
||||
|
||||
DescriptorValidator.validate(namespaceDescriptor);
|
||||
return Pair.create(namespaceDescriptor, injector.getBindingTrace().getBindingContext());
|
||||
}
|
||||
|
||||
@@ -137,6 +141,7 @@ public final class LoadDescriptorUtil {
|
||||
NamespaceDescriptor namespace =
|
||||
fileAndExhaust.getExhaust().getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, TEST_PACKAGE_FQNAME);
|
||||
assert namespace != null: TEST_PACKAGE_FQNAME + " package not found in " + ktFile.getName();
|
||||
DescriptorValidator.validate(namespace);
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.test.TestCaseWithTmpdir;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||
|
||||
import java.io.File;
|
||||
@@ -44,7 +45,6 @@ public final class LoadKotlinCustomTest extends TestCaseWithTmpdir {
|
||||
throws Exception {
|
||||
NamespaceDescriptor namespaceFromClass =
|
||||
compileKotlinAndLoadTestNamespaceDescriptorFromBinary(kotlinFile, tmpdir, myTestRootDisposable, ConfigurationKind.JDK_ONLY);
|
||||
|
||||
compareNamespaceWithFile(namespaceFromClass, DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ public final class LoadKotlinCustomTest extends TestCaseWithTmpdir {
|
||||
NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR,
|
||||
TEST_PACKAGE_FQNAME);
|
||||
assert namespaceFromSource != null;
|
||||
DescriptorValidator.validate(namespaceFromSource);
|
||||
compareNamespaceWithFile(namespaceFromSource, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.checkPrimaryConstructors(true),
|
||||
expectedFile);
|
||||
}
|
||||
|
||||
+2
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -46,6 +47,7 @@ public abstract class AbstractLazyResolveDiagnosticsTest extends AbstractJetDiag
|
||||
String path = JetTestUtils.getFilePath(new File(FileUtil.getRelativePath(TEST_DATA_DIR, testDataFile)));
|
||||
NamespaceDescriptor expected = eagerModule.getNamespace(FqName.ROOT);
|
||||
NamespaceDescriptor actual = lazyModule.getNamespace(FqName.ROOT);
|
||||
DescriptorValidator.validate(expected, actual);
|
||||
|
||||
String txtFileRelativePath = path.replaceAll("\\.kt$|\\.ktscript", ".txt");
|
||||
File txtFile = new File("compiler/testData/lazyResolve/diagnostics/" + txtFileRelativePath);
|
||||
|
||||
+3
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||
import org.junit.Assert;
|
||||
|
||||
@@ -77,6 +78,8 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe
|
||||
|
||||
File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt");
|
||||
|
||||
DescriptorValidator.validate(expected, actual);
|
||||
|
||||
NamespaceComparator.compareNamespaces(
|
||||
expected, actual, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion(
|
||||
new Predicate<FqNameUnsafe>() {
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
@@ -36,6 +37,7 @@ public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment {
|
||||
@Test
|
||||
public void testBuiltIns() throws Exception {
|
||||
NamespaceDescriptor builtInsPackage = KotlinBuiltIns.getInstance().getBuiltInsPackage();
|
||||
DescriptorValidator.validate(builtInsPackage);
|
||||
compareNamespaceWithFile(builtInsPackage, RECURSIVE, new File("compiler/testData/builtin-classes.txt"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
import org.jetbrains.jet.test.util.NamespaceComparator;
|
||||
|
||||
import java.io.File;
|
||||
@@ -59,6 +60,7 @@ public class LazyResolveStdlibLoadingTest extends KotlinTestWithEnvironmentManag
|
||||
for (Name name : namespaceShortNames) {
|
||||
NamespaceDescriptor eager = module.getNamespace(FqName.topLevel(name));
|
||||
NamespaceDescriptor lazy = lazyModule.getNamespace(FqName.topLevel(name));
|
||||
DescriptorValidator.validate(eager, lazy);
|
||||
NamespaceComparator.compareNamespaces(eager, lazy, NamespaceComparator.RECURSIVE, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.test.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class DescriptorValidator {
|
||||
|
||||
private DescriptorValidator() {}
|
||||
|
||||
public static void validate(DeclarationDescriptor... descriptors) {
|
||||
validate(Arrays.asList(descriptors));
|
||||
}
|
||||
|
||||
public static void validate(@NotNull Collection<DeclarationDescriptor> descriptors) {
|
||||
DiagnosticCollectorForTests collector = new DiagnosticCollectorForTests();
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
validate(descriptor, collector);
|
||||
}
|
||||
collector.done();
|
||||
}
|
||||
|
||||
public static void validate(@NotNull Collection<? extends DeclarationDescriptor> descriptors, @NotNull DiagnosticCollector collector) {
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
validate(descriptor, collector);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validate(@NotNull DeclarationDescriptor descriptor, @NotNull DiagnosticCollector collector) {
|
||||
RecursiveDescriptorProcessor.process(descriptor, collector, ValidationVisitor.INSTANCE);
|
||||
}
|
||||
|
||||
public interface DiagnosticCollector {
|
||||
|
||||
void report(@NotNull Diagnostic diagnostic);
|
||||
}
|
||||
|
||||
private static void report(@NotNull DiagnosticCollector collector, @NotNull DeclarationDescriptor descriptor, @NotNull String message) {
|
||||
collector.report(new Diagnostic(descriptor, message));
|
||||
}
|
||||
|
||||
private static class ValidationVisitor implements DeclarationDescriptorVisitor<Boolean, DiagnosticCollector> {
|
||||
|
||||
public static final ValidationVisitor INSTANCE = new ValidationVisitor();
|
||||
|
||||
private ValidationVisitor() {}
|
||||
|
||||
private static void validateScope(@NotNull JetScope scope, @NotNull DiagnosticCollector collector) {
|
||||
for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
||||
descriptor.accept(new ScopeValidatorVisitor(collector), scope);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateType(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@Nullable JetType type,
|
||||
@NotNull DiagnosticCollector collector
|
||||
) {
|
||||
if (type == null) {
|
||||
report(collector, descriptor, "No type");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ErrorUtils.isErrorType(type)) {
|
||||
report(collector, descriptor, "Error type: " + type);
|
||||
return;
|
||||
}
|
||||
|
||||
validateScope(type.getMemberScope(), collector);
|
||||
}
|
||||
|
||||
private static void validateReturnType(CallableDescriptor descriptor, DiagnosticCollector collector) {
|
||||
validateType(descriptor, descriptor.getReturnType(), collector);
|
||||
}
|
||||
|
||||
private static void validateTypeParameters(DiagnosticCollector collector, List<TypeParameterDescriptor> parameters) {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
||||
if (typeParameterDescriptor.getIndex() != i) {
|
||||
report(collector, typeParameterDescriptor, "Incorrect index: " + typeParameterDescriptor.getIndex() + " but must be " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateValueParameters(DiagnosticCollector collector, List<ValueParameterDescriptor> parameters) {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = parameters.get(i);
|
||||
if (valueParameterDescriptor.getIndex() != i) {
|
||||
report(collector, valueParameterDescriptor, "Incorrect index: " + valueParameterDescriptor.getIndex() + " but must be " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateTypes(
|
||||
DeclarationDescriptor descriptor,
|
||||
DiagnosticCollector collector,
|
||||
Collection<JetType> types
|
||||
) {
|
||||
for (JetType type : types) {
|
||||
validateType(descriptor, type, collector);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateCallable(CallableDescriptor descriptor, DiagnosticCollector collector) {
|
||||
validateReturnType(descriptor, collector);
|
||||
validateTypeParameters(collector, descriptor.getTypeParameters());
|
||||
validateValueParameters(collector, descriptor.getValueParameters());
|
||||
}
|
||||
|
||||
private static <T> void assertEquals(
|
||||
DeclarationDescriptor descriptor,
|
||||
DiagnosticCollector collector,
|
||||
String name,
|
||||
T expected,
|
||||
T actual
|
||||
) {
|
||||
if (!expected.equals(actual)) {
|
||||
report(collector, descriptor, "Wrong " + name + ": " + actual + " must be " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateAccessor(
|
||||
PropertyDescriptor descriptor,
|
||||
DiagnosticCollector collector,
|
||||
PropertyAccessorDescriptor accessor,
|
||||
String name
|
||||
) {
|
||||
// TODO
|
||||
//assertEquals(accessor, collector, name + " visibility", descriptor.getVisibility(), accessor.getVisibility());
|
||||
//assertEquals(accessor, collector, name + " modality", descriptor.getModality(), accessor.getModality());
|
||||
assertEquals(accessor, collector, "corresponding property", descriptor, accessor.getCorrespondingProperty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitNamespaceDescriptor(
|
||||
NamespaceDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateScope(descriptor.getMemberScope(), collector);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitVariableDescriptor(
|
||||
VariableDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateReturnType(descriptor, collector);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitFunctionDescriptor(
|
||||
FunctionDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateCallable(descriptor, collector);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeParameterDescriptor(
|
||||
TypeParameterDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateTypes(descriptor, collector, descriptor.getUpperBounds());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitClassDescriptor(
|
||||
ClassDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateTypeParameters(collector, descriptor.getTypeConstructor().getParameters());
|
||||
validateTypes(descriptor, collector, descriptor.getTypeConstructor().getSupertypes());
|
||||
|
||||
validateType(descriptor, descriptor.getDefaultType(), collector);
|
||||
|
||||
validateScope(descriptor.getUnsubstitutedInnerClassesScope(), collector);
|
||||
|
||||
List<ConstructorDescriptor> primary = Lists.newArrayList();
|
||||
for (ConstructorDescriptor constructorDescriptor : descriptor.getConstructors()) {
|
||||
if (constructorDescriptor.isPrimary()) {
|
||||
primary.add(constructorDescriptor);
|
||||
}
|
||||
}
|
||||
if (primary.size() > 1) {
|
||||
report(collector, descriptor, "Many primary constructors: " + primary);
|
||||
}
|
||||
|
||||
ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor();
|
||||
if (primaryConstructor != null) {
|
||||
if (!descriptor.getConstructors().contains(primaryConstructor)) {
|
||||
report(collector, primaryConstructor,
|
||||
"Primary constructor not in getConstructors() result: " + descriptor.getConstructors());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitModuleDeclaration(
|
||||
ModuleDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitConstructorDescriptor(
|
||||
ConstructorDescriptor constructorDescriptor, DiagnosticCollector collector
|
||||
) {
|
||||
visitFunctionDescriptor(constructorDescriptor, collector);
|
||||
|
||||
assertEquals(constructorDescriptor, collector,
|
||||
"return type",
|
||||
constructorDescriptor.getContainingDeclaration().getDefaultType(),
|
||||
constructorDescriptor.getReturnType());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitScriptDescriptor(
|
||||
ScriptDescriptor scriptDescriptor, DiagnosticCollector collector
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyDescriptor(
|
||||
PropertyDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateCallable(descriptor, collector);
|
||||
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
if (getter != null) {
|
||||
assertEquals(getter, collector, "getter return type", descriptor.getType(), getter.getReturnType());
|
||||
validateAccessor(descriptor, collector, getter, "getter");
|
||||
}
|
||||
|
||||
PropertySetterDescriptor setter = descriptor.getSetter();
|
||||
if (setter != null) {
|
||||
assertEquals(setter, collector, "setter parameter count", 1, setter.getValueParameters().size());
|
||||
assertEquals(setter, collector, "setter parameter type", descriptor.getType(), setter.getValueParameters().get(0).getType());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitValueParameterDescriptor(
|
||||
ValueParameterDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
visitVariableDescriptor(descriptor, collector);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyGetterDescriptor(
|
||||
PropertyGetterDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
return visitFunctionDescriptor(descriptor, collector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertySetterDescriptor(
|
||||
PropertySetterDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
return visitFunctionDescriptor(descriptor, collector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitReceiverParameterDescriptor(
|
||||
ReceiverParameterDescriptor descriptor, DiagnosticCollector collector
|
||||
) {
|
||||
validateType(descriptor, descriptor.getType(), collector);
|
||||
|
||||
if (!descriptor.getValue().exists()) {
|
||||
report(collector, descriptor, "Receiver value does not exist: " + descriptor.getValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ScopeValidatorVisitor implements DeclarationDescriptorVisitor<Void, JetScope> {
|
||||
private final DiagnosticCollector collector;
|
||||
|
||||
public ScopeValidatorVisitor(DiagnosticCollector collector) {
|
||||
this.collector = collector;
|
||||
}
|
||||
|
||||
private void report(DeclarationDescriptor expected, String message) {
|
||||
DescriptorValidator.report(collector, expected, message);
|
||||
}
|
||||
|
||||
private void assertFound(
|
||||
@NotNull JetScope scope,
|
||||
@NotNull DeclarationDescriptor expected,
|
||||
@Nullable DeclarationDescriptor found
|
||||
) {
|
||||
if (found == null) {
|
||||
report(expected, "Not found in " + scope);
|
||||
}
|
||||
if (expected != found) {
|
||||
report(expected, "Lookup error in " + scope + ": " + found);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFound(
|
||||
@NotNull JetScope scope,
|
||||
@NotNull DeclarationDescriptor expected,
|
||||
@NotNull Collection<? extends DeclarationDescriptor> found
|
||||
) {
|
||||
if (!found.contains(expected)) {
|
||||
report(expected, "Not found in " + scope + ": " + found);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNamespaceDescriptor(
|
||||
NamespaceDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
assertFound(scope, descriptor, scope.getNamespace(descriptor.getName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitVariableDescriptor(
|
||||
VariableDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
assertFound(scope, descriptor, scope.getProperties(descriptor.getName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFunctionDescriptor(
|
||||
FunctionDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
assertFound(scope, descriptor, scope.getFunctions(descriptor.getName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeParameterDescriptor(
|
||||
TypeParameterDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
assertFound(scope, descriptor, scope.getClassifier(descriptor.getName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClassDescriptor(
|
||||
ClassDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
if (descriptor.getKind().isObject()) {
|
||||
assertFound(scope, descriptor, scope.getObjectDescriptor(descriptor.getName()));
|
||||
}
|
||||
else {
|
||||
assertFound(scope, descriptor, scope.getClassifier(descriptor.getName()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleDeclaration(
|
||||
ModuleDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Module found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitConstructorDescriptor(
|
||||
ConstructorDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Constructor found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitScriptDescriptor(
|
||||
ScriptDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Script found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPropertyDescriptor(
|
||||
PropertyDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
return visitVariableDescriptor(descriptor, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitValueParameterDescriptor(
|
||||
ValueParameterDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
return visitVariableDescriptor(descriptor, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPropertyGetterDescriptor(
|
||||
PropertyGetterDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Getter found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPropertySetterDescriptor(
|
||||
PropertySetterDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Setter found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitReceiverParameterDescriptor(
|
||||
ReceiverParameterDescriptor descriptor, JetScope scope
|
||||
) {
|
||||
report(descriptor, "Receiver parameter found in scope: " + scope);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Diagnostic {
|
||||
|
||||
private final DeclarationDescriptor descriptor;
|
||||
private final String message;
|
||||
private final Throwable stackTrace;
|
||||
|
||||
private Diagnostic(@NotNull DeclarationDescriptor descriptor, @NotNull String message) {
|
||||
this.descriptor = descriptor;
|
||||
this.message = message;
|
||||
this.stackTrace = new Throwable();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DeclarationDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Throwable getStackTrace() {
|
||||
return stackTrace;
|
||||
}
|
||||
|
||||
public void printStackTrace(@NotNull PrintStream out) {
|
||||
out.println(descriptor);
|
||||
out.println(message);
|
||||
stackTrace.printStackTrace(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return descriptor + " > " + message;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DiagnosticCollectorForTests implements DiagnosticCollector {
|
||||
private boolean errorsFound = false;
|
||||
|
||||
@Override
|
||||
public void report(@NotNull Diagnostic diagnostic) {
|
||||
diagnostic.printStackTrace(System.err);
|
||||
errorsFound = true;
|
||||
}
|
||||
|
||||
public void done() {
|
||||
if (errorsFound) {
|
||||
Assert.fail("Descriptor validation failed (see messages above)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.test.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class RecursiveDescriptorProcessor {
|
||||
public static <D> boolean process(
|
||||
@NotNull Collection<? extends DeclarationDescriptor> descriptors,
|
||||
D data,
|
||||
@NotNull DeclarationDescriptorVisitor<Boolean, D> visitor
|
||||
) {
|
||||
RecursiveVisitor<D> recursive = new RecursiveVisitor<D>(visitor);
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
if (!descriptor.accept(visitor, data)) {
|
||||
return false;
|
||||
}
|
||||
descriptor.accept(recursive, data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <D> boolean process(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
D data,
|
||||
@NotNull DeclarationDescriptorVisitor<Boolean, D> visitor
|
||||
) {
|
||||
return process(Collections.singletonList(descriptor), data, visitor);
|
||||
}
|
||||
|
||||
private static class RecursiveVisitor<D> implements DeclarationDescriptorVisitor<Boolean, D> {
|
||||
|
||||
private final DeclarationDescriptorVisitor<Boolean, D> worker;
|
||||
|
||||
private RecursiveVisitor(@NotNull DeclarationDescriptorVisitor<Boolean, D> worker) {
|
||||
this.worker = worker;
|
||||
}
|
||||
|
||||
private boolean doProcess(Collection<? extends DeclarationDescriptor> descriptors, D data) {
|
||||
return process(descriptors, data, worker);
|
||||
}
|
||||
|
||||
private boolean doProcess(@Nullable DeclarationDescriptor receiverParameter, D data) {
|
||||
if (receiverParameter == null) {
|
||||
return true;
|
||||
}
|
||||
return receiverParameter.accept(worker, data);
|
||||
}
|
||||
|
||||
private boolean processCallable(CallableDescriptor descriptor, D data) {
|
||||
return doProcess(descriptor.getTypeParameters(), data)
|
||||
&& doProcess(descriptor.getReceiverParameter(), data)
|
||||
&& doProcess(descriptor.getValueParameters(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitNamespaceDescriptor(NamespaceDescriptor descriptor, D data) {
|
||||
return doProcess(descriptor.getMemberScope().getAllDescriptors(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitVariableDescriptor(VariableDescriptor descriptor, D data) {
|
||||
return processCallable(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, D data) {
|
||||
return processCallable(descriptor, data)
|
||||
&& doProcess(descriptor.getGetter(), data)
|
||||
&& doProcess(descriptor.getSetter(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, D data) {
|
||||
return processCallable(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, D data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitClassDescriptor(ClassDescriptor descriptor, D data) {
|
||||
return doProcess(descriptor.getThisAsReceiverParameter(), data)
|
||||
&& doProcess(descriptor.getConstructors(), data)
|
||||
&& doProcess(descriptor.getTypeConstructor().getParameters(), data)
|
||||
&& doProcess(descriptor.getClassObjectDescriptor(), data)
|
||||
&& doProcess(descriptor.getDefaultType().getMemberScope().getObjectDescriptors(), data)
|
||||
&& doProcess(descriptor.getDefaultType().getMemberScope().getAllDescriptors(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, D data) {
|
||||
return doProcess(descriptor.getNamespace(FqName.ROOT), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data) {
|
||||
return visitFunctionDescriptor(constructorDescriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitScriptDescriptor(ScriptDescriptor scriptDescriptor, D data) {
|
||||
return visitClassDescriptor(scriptDescriptor.getClassDescriptor(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitValueParameterDescriptor(ValueParameterDescriptor descriptor, D data) {
|
||||
return visitVariableDescriptor(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyGetterDescriptor(PropertyGetterDescriptor descriptor, D data) {
|
||||
return visitFunctionDescriptor(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertySetterDescriptor(PropertySetterDescriptor descriptor, D data) {
|
||||
return visitFunctionDescriptor(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitReceiverParameterDescriptor(ReceiverParameterDescriptor descriptor, D data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user