JavaDescriptorResolver: Add resolve for annotation parameters (array, annotation, enum)

Temporary change testData for LoadJavaTest because enums in parameters of annotations in kotlin files is now unsupported
This commit is contained in:
Natalia.Ukhorskaya
2012-08-29 13:10:03 +04:00
parent 92a782ce6c
commit 19221e3ba6
18 changed files with 883 additions and 30 deletions
@@ -0,0 +1,319 @@
/*
* 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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
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.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.constants.AnnotationValue;
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
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.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.jetbrains.jet.test.TestCaseWithTmpdir;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver.getValueParameterDescriptorForAnnotationParameter;
/**
* @author Natalia Ukhorskaya
*/
public class AnnotationJavaDescriptorResolverTest extends TestCaseWithTmpdir {
private static final String PATH = "compiler/testData/javaDescriptorResolver/annotations/";
private static final String DEFAULT_PACKAGE = "annotations";
private JavaDescriptorResolver javaDescriptorResolver;
public void testCustomAnnotationWithKotlinEnum() throws IOException {
File testFile = new File(PATH + "kotlinEnum.kt");
LoadDescriptorUtil.compileKotlinToDirAndGetAnalyzeExhaust(testFile, tmpdir, myTestRootDisposable);
StringBuilder builder = new StringBuilder(tmpdir.getAbsolutePath());
builder.append(File.pathSeparator);
File runtimePath = PathUtil.getDefaultRuntimePath();
if (runtimePath != null) {
builder.append(runtimePath.getAbsolutePath());
builder.append(File.pathSeparator);
}
File annotationsPath = PathUtil.getJdkAnnotationsPath();
if (annotationsPath != null) {
builder.append(annotationsPath.getAbsolutePath());
}
setUpJavaDescriptorResolver();
compileJavaFile("customAnnotationWithKotlinEnum.java", builder.toString());
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
AnnotationDescriptor annotation = getAnnotationInClassByType("testClass", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
checkSimpleCompileTimeConstant(actualCompileTimeConstant, DEFAULT_PACKAGE + ".MyEnum", "MyEnum.ONE");
}
public void testCustomAnnotation() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("customAnnotation.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
AnnotationDescriptor annotation = getAnnotationInClassByType("MyTest", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
checkSimpleCompileTimeConstant(actualCompileTimeConstant, DEFAULT_PACKAGE + ".MyEnum", "MyEnum.ONE");
}
public void testCustomAnnotationWithDefaultParameter() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("customAnnotationWithDefaultParameter.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
AnnotationDescriptor annotation = getAnnotationInClassByType("MyTest", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "first");
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "jet.String", "\"f\"");
actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "second");
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "jet.String", "\"s\"");
}
public void testAnnotationWithAnnotationInParam() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("annotationWithAnnotationInParam.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotationWithParam";
AnnotationDescriptor annotation = getAnnotationInClassByType("A",
annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
DEFAULT_PACKAGE + ".MyAnnotation", "jet.String", "\"test\"");
String annotationTypeName2 = DEFAULT_PACKAGE + ".MyAnnotationWithParam2";
AnnotationDescriptor annotation2 = getAnnotationInClassByType("B", annotationTypeName2);
actualCompileTimeConstant = getCompileTimeConstant(annotation2, annotationTypeName2, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
DEFAULT_PACKAGE + ".MyAnnotation2", "jet.Array<jet.String?>?", "[\"test\", \"test2\"]");
String annotationTypeName3 = DEFAULT_PACKAGE + ".MyAnnotationWithParam3";
AnnotationDescriptor annotation3 = getAnnotationInClassByType("C", annotationTypeName3);
actualCompileTimeConstant = getCompileTimeConstant(annotation3, annotationTypeName3, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "first",
DEFAULT_PACKAGE + ".MyAnnotation3", "jet.String", "\"f\"");
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "second",
DEFAULT_PACKAGE + ".MyAnnotation3", "jet.String", "\"s\"");
}
public void testRecursiveAnnotation() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("recursiveAnnotation.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".B";
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
DEFAULT_PACKAGE + ".A", "jet.String", "\"test\"");
AnnotationDescriptor annotation2 = getAnnotationInClassByType("B", annotationTypeName);
actualCompileTimeConstant = getCompileTimeConstant(annotation2, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
DEFAULT_PACKAGE + ".A", "jet.String", "\"test\"");
}
public void testRecursiveAnnotation2() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("recursiveAnnotation2.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".A";
AnnotationDescriptor annotation = getAnnotationInClassByType("B", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof AnnotationValue;
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
DEFAULT_PACKAGE + ".B", "jet.String", "\"test\"");
}
public void testAnnotationWithEnumInParam() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("annotationWithEnumInParam.java", null);
String annotationTypeName = "java.lang.annotation.Retention";
AnnotationDescriptor annotation = getAnnotationInClassByType("retentionAnnotation", annotationTypeName);
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "java.lang.annotation.RetentionPolicy", "RetentionPolicy.RUNTIME");
}
public void testAnnotationWithArrayOfEnumInParam() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("annotationWithArrayOfEnumInParam.java", null);
String annotationTypeName = "java.lang.annotation.Target";
AnnotationDescriptor annotation = getAnnotationInClassByType("targetAnnotation", annotationTypeName);
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
String[] values = new String[] {"ElementType.FIELD", "ElementType.CONSTRUCTOR"};
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof ArrayValue;
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<java.lang.annotation.ElementType?>?",
"java.lang.annotation.ElementType", values);
}
public void testAnnotationWithArrayOfStringInParam() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("annotationWithArrayOfStringInParam.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
String[] values = new String[] {"\"a\"", "\"b\"", "\"c\""};
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof ArrayValue;
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<jet.String?>?", "jet.String", values);
}
public void testAnnotationWithEmptyArrayInParam() throws IOException {
setUpJavaDescriptorResolver();
compileJavaFile("annotationWithEmptyArrayInParam.java", null);
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
String[] values = new String[] {};
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
assert actualCompileTimeConstant instanceof ArrayValue;
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<jet.String?>?", "jet.String", values);
}
private void compileJavaFile(@NotNull String fileRelativePath, @Nullable String classPath)
throws IOException {
File javaFile = new File(PATH + fileRelativePath);
assertNotNull(javaFile);
List<String> options = new ArrayList<String>();
options.add("-d");
options.add(tmpdir.getPath());
if (classPath != null) {
options.add("-cp");
options.add(classPath);
}
JetTestUtils.compileJavaFiles(Collections.singleton(javaFile), options);
}
private void setUpJavaDescriptorResolver() {
JetCoreEnvironment jetCoreEnvironment =
new JetCoreEnvironment(myTestRootDisposable, CompileCompilerDependenciesTest.compilerConfigurationForTests(
ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), tmpdir));
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(BuiltinsScopeExtensionMode.ALL,
jetCoreEnvironment.getProject());
javaDescriptorResolver = injector.getJavaDescriptorResolver();
}
private static void compareJetTypeWithClass(@NotNull JetType actualType, @NotNull String expectedType) {
assertEquals(expectedType, DescriptorRenderer.TEXT.renderType(actualType));
}
@NotNull
private CompileTimeConstant<?> getCompileTimeConstant(
@NotNull AnnotationDescriptor annotationDescriptor,
@NotNull String annotationType,
@NotNull String parameterName
) {
ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptor(annotationType, parameterName);
CompileTimeConstant<?> actualCompileTimeValue = annotationDescriptor.getValueArgument(valueParameterDescriptor);
assertNotNull(actualCompileTimeValue);
return actualCompileTimeValue;
}
@NotNull
private ValueParameterDescriptor getValueParameterDescriptor(@NotNull String annotationTypeName, @NotNull String parameterName) {
ClassDescriptor clazz = javaDescriptorResolver.resolveClass(new FqName(annotationTypeName));
assertNotNull("Cannot resolve class with name " + annotationTypeName, clazz);
ValueParameterDescriptor valueParameterDescriptor =
getValueParameterDescriptorForAnnotationParameter(Name.identifier(parameterName), clazz);
assertNotNull("Cannot resolve value parameter for " + parameterName, valueParameterDescriptor);
return valueParameterDescriptor;
}
@NotNull
private AnnotationDescriptor getAnnotationInClassByType(@NotNull String className, @NotNull String type) throws IOException {
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(DEFAULT_PACKAGE + "." + className));
assertNotNull("Cannot resolve class with name " + className, classDescriptor);
List<AnnotationDescriptor> annotations = classDescriptor.getAnnotations();
assertEquals(annotations.size(), 1);
for (AnnotationDescriptor annotation : annotations) {
if (type.endsWith(annotation.getType().toString())) {
compareJetTypeWithClass(annotation.getType(), type);
return annotation;
}
}
fail("Cannot find annotation for class " + className + ", type " + type);
return null;
}
private static void checkSimpleCompileTimeConstant(@NotNull CompileTimeConstant<?> actual, @NotNull String expectedType, @NotNull String expectedValue) {
assertEquals(expectedValue, actual.toString());
compareJetTypeWithClass(actual.getType(JetStandardLibrary.getInstance()), expectedType);
}
private void checkAnnotationCompileTimeConstant(
@NotNull AnnotationValue actual,
@NotNull String parameterName,
@NotNull String expectedType,
@NotNull String expectedParameterType,
@NotNull String expectedParameterValue
) {
compareJetTypeWithClass(actual.getType(JetStandardLibrary.getInstance()), expectedType);
CompileTimeConstant<?> innerAnnotation = getCompileTimeConstant(actual.getValue(), expectedType, parameterName);
checkSimpleCompileTimeConstant(innerAnnotation, expectedParameterType, expectedParameterValue);
}
private static void checkArrayCompileTimeConstant(
@NotNull ArrayValue actual,
@NotNull String expectedType,
@NotNull String expectedArgumentType,
@NotNull String[] expectedValues
) {
JetType actualType = actual.getType(JetStandardLibrary.getInstance());
compareJetTypeWithClass(actualType, expectedType);
List<CompileTimeConstant<?>> arrayValuesCompileTimeConst = actual.getValue();
assertEquals("Number of arguments is incorrect", expectedValues.length, arrayValuesCompileTimeConst.size());
int i = 0;
for (CompileTimeConstant<?> constant : arrayValuesCompileTimeConst) {
checkSimpleCompileTimeConstant(constant, expectedArgumentType, expectedValues[i]);
i++;
}
}
}