Resolve annotations arguments in body resolver

This commit is contained in:
Natalia.Ukhorskaya
2013-07-04 12:26:04 +04:00
parent 33ddd713b7
commit a5662fe906
15 changed files with 537 additions and 63 deletions
@@ -0,0 +1,282 @@
/*
* 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.resolve.annotation;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.TypeProjection;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AnnotationDescriptorResolveTest extends JetLiteFixture {
private static final String PATH = "compiler/testData/resolveAnnotations/testFile.kt";
private static final FqName NAMESPACE = new FqName("test");
private BindingContext context;
@Override
protected JetCoreEnvironment createEnvironment() {
return JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable());
}
public void testIntAnnotation() throws IOException {
String content = getContent("AnnInt(1)");
String expectedAnnotation = "AnnInt[a = 1.toInt()]";
doTest(content, expectedAnnotation);
}
public void testStringAnnotation() throws IOException {
String content = getContent("AnnString(\"test\")");
String expectedAnnotation = "AnnString[a = \"test\"]";
doTest(content, expectedAnnotation);
}
private void doTest(@NotNull String content, @NotNull String expectedAnnotation) {
NamespaceDescriptor test = getNamespaceDescriptor(content);
ClassDescriptor myClass = getClassDescriptor(test, "MyClass");
checkDescriptor(expectedAnnotation, myClass);
checkDescriptor(expectedAnnotation, getClassObjectDescriptor(myClass));
checkDescriptor(expectedAnnotation, getInnerClassDescriptor(myClass, "InnerClass"));
FunctionDescriptor foo = getFunctionDescriptor(myClass, "foo");
checkDescriptor(expectedAnnotation, foo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(foo, "param"));
checkDescriptor(expectedAnnotation, getLocalClassDescriptor("LocalClass"));
checkDescriptor(expectedAnnotation, getLocalObjectDescriptor("LocalObject"));
checkDescriptor(expectedAnnotation, getLocalFunDescriptor("localFun"));
checkDescriptor(expectedAnnotation, getLocalVarDescriptor("localVar"));
SimpleFunctionDescriptor anonymousFun = getAnonymousFunDescriptor();
if (anonymousFun instanceof AnonymousFunctionDescriptor) {
for (ValueParameterDescriptor descriptor : anonymousFun.getValueParameters()) {
checkDescriptor(expectedAnnotation, descriptor);
}
}
PropertyDescriptor prop = getPropertyDescriptor(myClass, "prop");
checkDescriptor(expectedAnnotation, prop);
checkDescriptor(expectedAnnotation, prop.getGetter());
checkDescriptor(expectedAnnotation, prop.getSetter());
FunctionDescriptor topFoo = getFunctionDescriptor(test, "topFoo");
checkDescriptor(expectedAnnotation, topFoo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(topFoo, "param"));
PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp");
checkDescriptor(expectedAnnotation, topProp);
checkDescriptor(expectedAnnotation, topProp.getGetter());
checkDescriptor(expectedAnnotation, topProp.getSetter());
checkDescriptor(expectedAnnotation, getObjectDescriptor(test, "MyObject"));
}
@NotNull
private static FunctionDescriptor getFunctionDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name functionName = Name.identifier(name);
JetScope memberScope = namespaceDescriptor.getMemberScope();
Collection<FunctionDescriptor> functions = memberScope.getFunctions(functionName);
assert functions.size() == 1 : "Failed to find function " + functionName + " in class" + "." + namespaceDescriptor.getName();
return functions.iterator().next();
}
@NotNull
private static FunctionDescriptor getFunctionDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name functionName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
Collection<FunctionDescriptor> functions = memberScope.getFunctions(functionName);
assert functions.size() == 1 : "Failed to find function " + functionName + " in class" + "." + classDescriptor.getName();
return functions.iterator().next();
}
@NotNull
private static PropertyDescriptor getPropertyDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = namespaceDescriptor.getMemberScope();
Collection<VariableDescriptor> properties = memberScope.getProperties(propertyName);
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + namespaceDescriptor.getName();
return (PropertyDescriptor) properties.iterator().next();
}
@NotNull
private static PropertyDescriptor getPropertyDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
Collection<VariableDescriptor> properties = memberScope.getProperties(propertyName);
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + classDescriptor.getName();
return (PropertyDescriptor) properties.iterator().next();
}
@NotNull
private static ClassDescriptor getClassDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name className = Name.identifier(name);
ClassifierDescriptor aClass = namespaceDescriptor.getMemberScope().getClassifier(className);
assertNotNull("Failed to find class: " + namespaceDescriptor.getName() + "." + className, aClass);
assert aClass instanceof ClassDescriptor;
return (ClassDescriptor) aClass;
}
@NotNull
private static ClassDescriptor getObjectDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name className = Name.identifier(name);
ClassDescriptor aClass = namespaceDescriptor.getMemberScope().getObjectDescriptor(className);
assertNotNull("Failed to find class: " + namespaceDescriptor.getName() + "." + className, aClass);
return aClass;
}
@NotNull
private static ClassDescriptor getClassObjectDescriptor(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor objectDescriptor = classDescriptor.getClassObjectDescriptor();
assert objectDescriptor != null : "Cannot find class object for class " + classDescriptor.getName();
return objectDescriptor;
}
@NotNull
private static ClassDescriptor getInnerClassDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
ClassifierDescriptor innerClass = memberScope.getClassifier(propertyName);
assert innerClass instanceof ClassDescriptor : "Failed to find inner class " +
propertyName +
" in class " +
classDescriptor.getName();
return (ClassDescriptor) innerClass;
}
@NotNull
private ClassDescriptor getLocalClassDescriptor(@NotNull String name) {
for (ClassDescriptor descriptor : context.getSliceContents(BindingContext.CLASS).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local class " + name);
return null;
}
@NotNull
private ClassDescriptor getLocalObjectDescriptor(@NotNull String name) {
for (ClassDescriptor descriptor : context.getSliceContents(BindingContext.OBJECT_DECLARATION_CLASS).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local object " + name);
return null;
}
@NotNull
private SimpleFunctionDescriptor getLocalFunDescriptor(@NotNull String name) {
for (SimpleFunctionDescriptor descriptor : context.getSliceContents(BindingContext.FUNCTION).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local fun " + name);
return null;
}
@NotNull
private VariableDescriptor getLocalVarDescriptor(@NotNull String name) {
for (VariableDescriptor descriptor : context.getSliceContents(BindingContext.VARIABLE).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local variable " + name);
return null;
}
@NotNull
private SimpleFunctionDescriptor getAnonymousFunDescriptor() {
for (SimpleFunctionDescriptor descriptor : context.getSliceContents(BindingContext.FUNCTION).values()) {
if (descriptor instanceof AnonymousFunctionDescriptor) {
return descriptor;
}
}
fail("Failed to find anonymous fun");
return null;
}
private static ValueParameterDescriptor findValueParameter(List<ValueParameterDescriptor> parameters, String name) {
for (ValueParameterDescriptor parameter : parameters) {
if (parameter.getName().asString().equals(name)) {
return parameter;
}
}
return null;
}
@NotNull
private static ValueParameterDescriptor getFunctionParameterDescriptor(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull String name
) {
ValueParameterDescriptor parameter = findValueParameter(functionDescriptor.getValueParameters(), name);
assertNotNull("Cannot find function parameter with name " + name, parameter);
return parameter;
}
@NotNull
private NamespaceDescriptor getNamespaceDescriptor(@NotNull String content) {
JetFile ktFile = JetTestUtils.createFile("dummy.kt", content, getProject());
context = JetTestUtils.analyzeFile(ktFile).getBindingContext();
NamespaceDescriptor namespaceDescriptor = context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, NAMESPACE);
assertNotNull("Failed to find namespace: " + NAMESPACE, namespaceDescriptor);
return namespaceDescriptor;
}
private static String getContent(@NotNull String annotationText) throws IOException {
File file = new File(PATH);
String content = JetTestUtils.doLoadFile(file).replaceAll("ANNOTATION", annotationText);
return content;
}
private static void checkDescriptor(String expectedAnnotation, DeclarationDescriptor member) {
String actual = StringUtil.join(member.getAnnotations(), new Function<AnnotationDescriptor, String>() {
@Override
public String fun(AnnotationDescriptor annotationDescriptor) {
return annotationDescriptor.toString();
}
}, " ");
assertEquals("Failed to resolve annotation descriptor for " + member.toString(), expectedAnnotation, actual);
}
}