You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
6.4 KiB
240 lines
6.4 KiB
/*
|
|
* Copyright (C) 2019 The Dagger Authors.
|
|
*
|
|
* 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 dagger.internal.codegen;
|
|
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
|
|
import com.google.testing.compile.CompilationRule;
|
|
import dagger.internal.codegen.langmodel.DaggerElements;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
import javax.lang.model.element.TypeElement;
|
|
import javax.lang.model.util.ElementFilter;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.JUnit4;
|
|
|
|
@RunWith(JUnit4.class)
|
|
public class ElementDescriptorsTest {
|
|
|
|
@Rule public CompilationRule compilation = new CompilationRule();
|
|
|
|
static class TestClassA<T> {
|
|
int field1;
|
|
String field2;
|
|
T field3;
|
|
List<String> field4;
|
|
}
|
|
|
|
@Test
|
|
public void fieldDescriptor() {
|
|
assertThat(getFieldDescriptors(TestClassA.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"field1:I",
|
|
"field2:Ljava/lang/String;",
|
|
"field3:Ljava/lang/Object;",
|
|
"field4:Ljava/util/List;");
|
|
}
|
|
|
|
static class TestClassB<T> {
|
|
void method1(boolean yesOrNo, int number) {}
|
|
|
|
byte method2(char letter) {
|
|
return 0;
|
|
}
|
|
|
|
void method3(double realNumber1, float realNummber2) {}
|
|
|
|
void method4(long bigNumber, short littlerNumber) {}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_primitives() {
|
|
assertThat(getMethodDescriptors(TestClassB.class.getCanonicalName()))
|
|
.containsExactly("method1(ZI)V", "method2(C)B", "method3(DF)V", "method4(JS)V");
|
|
}
|
|
|
|
static class TestClassC<T> {
|
|
void method1(Object something) {}
|
|
|
|
Object method2() {
|
|
return null;
|
|
}
|
|
|
|
List<String> method3(ArrayList<Integer> list) {
|
|
return null;
|
|
}
|
|
|
|
Map<String, Object> method4() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_javaTypes() {
|
|
assertThat(getMethodDescriptors(TestClassC.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"method1(Ljava/lang/Object;)V",
|
|
"method2()Ljava/lang/Object;",
|
|
"method3(Ljava/util/ArrayList;)Ljava/util/List;",
|
|
"method4()Ljava/util/Map;");
|
|
}
|
|
|
|
static class TestClassD<T> {
|
|
void method1(TestDataClass data) {}
|
|
|
|
TestDataClass method2() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_testTypes() {
|
|
assertThat(getMethodDescriptors(TestClassD.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"method1(Ldagger/internal/codegen/TestDataClass;)V",
|
|
"method2()Ldagger/internal/codegen/TestDataClass;");
|
|
}
|
|
|
|
static class TestClassE<T> {
|
|
void method1(TestDataClass[] data) {}
|
|
|
|
TestDataClass[] method2() {
|
|
return null;
|
|
}
|
|
|
|
void method3(int[] array) {}
|
|
|
|
void method4(int... array) {}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_arrays() {
|
|
assertThat(getMethodDescriptors(TestClassE.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"method1([Ldagger/internal/codegen/TestDataClass;)V",
|
|
"method2()[Ldagger/internal/codegen/TestDataClass;",
|
|
"method3([I)V",
|
|
"method4([I)V");
|
|
}
|
|
|
|
static class TestClassF<T> {
|
|
void method1(TestDataClass.MemberInnerData data) {}
|
|
|
|
void method2(TestDataClass.StaticInnerData data) {}
|
|
|
|
void method3(TestDataClass.EnumData enumData) {}
|
|
|
|
TestDataClass.StaticInnerData method4() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_innerTestType() {
|
|
assertThat(getMethodDescriptors(TestClassF.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"method1(Ldagger/internal/codegen/TestDataClass$MemberInnerData;)V",
|
|
"method2(Ldagger/internal/codegen/TestDataClass$StaticInnerData;)V",
|
|
"method3(Ldagger/internal/codegen/TestDataClass$EnumData;)V",
|
|
"method4()Ldagger/internal/codegen/TestDataClass$StaticInnerData;");
|
|
}
|
|
|
|
@SuppressWarnings("TypeParameterUnusedInFormals")
|
|
static class TestClassG<T> {
|
|
void method1(T something) {}
|
|
|
|
T method2() {
|
|
return null;
|
|
}
|
|
|
|
List<? extends String> method3() {
|
|
return null;
|
|
}
|
|
|
|
Map<T, String> method4() {
|
|
return null;
|
|
}
|
|
|
|
ArrayList<Map<T, String>> method5() {
|
|
return null;
|
|
}
|
|
|
|
static <I, O extends I> O method6(I input) {
|
|
return null;
|
|
}
|
|
|
|
static <I, O extends String> O method7(I input) {
|
|
return null;
|
|
}
|
|
|
|
static <P extends Collection<String> & Comparable<String>> P method8() {
|
|
return null;
|
|
}
|
|
|
|
static <P extends String & List<Character>> P method9() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void methodDescriptor_erasure() {
|
|
assertThat(getMethodDescriptors(TestClassG.class.getCanonicalName()))
|
|
.containsExactly(
|
|
"method1(Ljava/lang/Object;)V",
|
|
"method2()Ljava/lang/Object;",
|
|
"method3()Ljava/util/List;",
|
|
"method4()Ljava/util/Map;",
|
|
"method5()Ljava/util/ArrayList;",
|
|
"method6(Ljava/lang/Object;)Ljava/lang/Object;",
|
|
"method7(Ljava/lang/Object;)Ljava/lang/String;",
|
|
"method8()Ljava/util/Collection;",
|
|
"method9()Ljava/lang/String;");
|
|
}
|
|
|
|
private Set<String> getFieldDescriptors(String className) {
|
|
TypeElement testElement = compilation.getElements().getTypeElement(className);
|
|
return ElementFilter.fieldsIn(testElement.getEnclosedElements()).stream()
|
|
.map(DaggerElements::getFieldDescriptor)
|
|
.collect(Collectors.toSet());
|
|
}
|
|
|
|
private Set<String> getMethodDescriptors(String className) {
|
|
TypeElement testElement = compilation.getElements().getTypeElement(className);
|
|
return ElementFilter.methodsIn(testElement.getEnclosedElements()).stream()
|
|
.map(DaggerElements::getMethodDescriptor)
|
|
.collect(Collectors.toSet());
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("ClassCanBeStatic")
|
|
class TestDataClass {
|
|
class MemberInnerData {}
|
|
|
|
static class StaticInnerData {}
|
|
|
|
enum EnumData {
|
|
VALUE1,
|
|
VALUE2
|
|
}
|
|
}
|