Implement JavaTypeSubstitutor without PSI

This commit is contained in:
zarechenskiy
2014-06-24 15:24:22 +04:00
committed by Alexander Udalov
parent 97b7768890
commit 0355b1bd53
54 changed files with 1000 additions and 62 deletions
@@ -0,0 +1,8 @@
interface arrayType {
interface SuperArray<T> {
T[] typeForSubstitute();
}
interface MidArray extends SuperArray<Integer> {
}
}
@@ -0,0 +1,8 @@
interface classType {
interface SuperClass<T> {
List<Integer> typeForSubstitute();
}
interface MidClass extends SuperClass {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface classWithWildcard {
interface SuperList<T> {
List<T> typeForSubstitute();
}
interface MidList<U> extends SuperList<List<? extends U>> {
}
}
@@ -0,0 +1,8 @@
interface genericArray {
interface SuperGenericArray<T> {
T typeForSubstitute();
}
interface MidGenericArray<T> extends SuperGenericArray<T[]> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface innerParameter {
interface SuperInnerParam<T> {
<T> T typeForSubstitute();
}
interface MidInnerParam<U> extends SuperInnerParam<U> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface intersectionType {
interface SuperIntersection<T> {
<R extends Enum<R> & List<T>> R typeForSubstitute();
}
interface MidIntersection<U> extends SuperIntersection<U> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface intersectionTypeAsTypeParameter {
interface Super<K> {
<T extends Enum<T> & List<K>> Map<? extends T, K> typeForSubstitute();
}
interface Sub<U> extends Super<U> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface intersectionTypeInEnum {
interface Super<T> {
<R extends Enum<R> & List<T>> Enum<R> typeForSubstitute();
}
interface Sub<U> extends Super<U> {
}
}
@@ -0,0 +1,8 @@
interface intersectionTypeInInterfaceDeclaration {
interface SuperIntersection<T extends Object & Cloneable> {
T typeForSubstitute();
}
interface MidIntersection<U extends Object & Cloneable> extends SuperIntersection<U> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface intersectionTypeInTypeVariableClass {
interface Super<T> {
<R extends Class<R> & List<T>> TypeVariable<R> typeForSubstitute();
}
interface Sub<U> extends Super<U> {
}
}
@@ -0,0 +1,10 @@
import java.util.Map;
interface mapEntry {
interface Super<T, E> {
Map.Entry<T, E> typeForSubstitute();
}
interface Mid<E> extends Super<E, Integer> {
}
}
@@ -0,0 +1,8 @@
interface primitiveType {
interface SuperPrimitive<T> {
int typeForSubstitute();
}
interface MidPrimitive extends SuperPrimitive<Integer> {
}
}
@@ -0,0 +1,8 @@
interface rawArrayType {
interface SuperArray<T> {
T[] typeForSubstitute();
}
interface MidArray extends SuperArray {
}
}
@@ -0,0 +1,8 @@
interface rawArrayTypeParameterWithBound {
interface Super<T extends Cloneable> {
T[] typeForSubstitute();
}
interface Sub extends Super {
}
}
@@ -0,0 +1,8 @@
interface rawEnum {
interface Super<T extends Enum<T>> {
Enum<T> typeForSubstitute();
}
interface Sub extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface rawExtendsWildcard {
interface SuperRawWild<T> {
List<? extends T> typeForSubstitute();
}
interface MidRawWildcard extends SuperRawWild {
}
}
@@ -0,0 +1,8 @@
interface rawIntersectionType {
interface Super<T extends Integer & Cloneable> {
T typeForSubstitute();
}
interface Sub extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface rawSuperWildcard {
interface SuperRawWild<T> {
List<? super T> typeForSubstitute();
}
interface MidRawWildcard extends SuperRawWild {
}
}
@@ -0,0 +1,8 @@
interface rawType {
interface Super<T> {
T typeForSubstitute();
}
interface MidRaw extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface rawTypeInDeclaration {
interface Super<T> {
List typeForSubstitute();
}
interface Sub<U> extends Super<U> {
}
}
@@ -0,0 +1,8 @@
interface rawTypeWithBound {
interface Super<T extends Integer> {
T typeForSubstitute();
}
interface MidRaw extends Super {
}
}
@@ -0,0 +1,8 @@
interface rawTypeWithSelfReferenceBound {
interface Super<T extends Super<T>> {
T typeForSubstitute();
}
interface MidRaw extends Super {
}
}
@@ -0,0 +1,10 @@
import java.lang.reflect.TypeVariable;
interface rawWildcardInTypeVariableClass {
interface Super<T> {
TypeVariable<? super T> typeForSubstitute();
}
interface Sub extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface rawWildcardWithBound {
interface Super<T extends Cloneable> {
List<? extends T> typeForSubstitute();
}
interface Sub extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface selfReference {
interface SuperSelfRef<T extends SuperSelfRef<T>> {
public List<T> typeForSubstitute();
}
interface MidSelfRef extends SuperSelfRef<MidSelfRef> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface twoParameters {
interface SuperTwoParams<T, U> {
Map<T, List<U>> typeForSubstitute();
}
interface MidTwoParams<E> extends SuperTwoParams<Integer, E> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface twoParametersInSubClass {
interface SuperTwoParams<T> {
List<T> typeForSubstitute();
}
interface MidTwoParams<T, S> extends SuperTwoParams<S> {
}
}
@@ -0,0 +1,10 @@
import java.lang.reflect.TypeVariable;
interface typeVariableClass {
interface Super<T> {
TypeVariable<? super T> typeForSubstitute();
}
interface Mid<E> extends Super<E> {
}
}
@@ -0,0 +1,10 @@
import java.lang.reflect.TypeVariable;
interface typeVariableRaw {
interface Super<T extends Class> {
TypeVariable<T> typeForSubstitute();
}
interface Mid extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface unboundedWildcard {
interface Super<T> {
List<?> typeForSubstitute();
}
interface Sub extends Super<Integer> {
}
}
@@ -0,0 +1,8 @@
import java.util.*;
interface unboundedWildcardToTypeParameter {
interface SupList<K> extends List<K> {
@Override
boolean retainAll(Collection<K> c); // error, check that we do not fall
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargArray {
interface Super<T> {
void typeForSubstitute(T... a);
}
interface Sub<Integer> extends Super<Integer[]> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargArrayTypeParameter {
interface Super<T> {
void typeForSubstitute(T... a);
}
interface Sub<E> extends Super<E[]> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargClass {
interface Super<T> {
void typeForSubstitute(List<T>... a);
}
interface Sub extends Super<Integer> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargClassWithWildcard {
interface Super<T> {
void typeForSubstitute(List<? extends T>... a);
}
interface Sub<E> extends Super<List<? extends E>> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargRawType {
interface Super<T> {
void typeForSubstitute(T... a);
}
interface Sub extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargRawTypeWithBound {
interface Super<T extends Integer> {
void typeForSubstitute(T... a);
}
interface Sub<E> extends Super {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargToClass {
interface Super<T> {
void typeForSubstitute(T... a);
}
interface Sub extends Super<Integer> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface varargToClassWithWildcard {
interface Super<T> {
void typeForSubstitute(T... a);
}
interface Sub<E> extends Super<List<? extends E>> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface wildcardExtends {
interface SuperWildcardExtends<T> {
List<? extends T> typeForSubstitute();
}
interface MidWildcardExtends extends SuperWildcardExtends<Integer> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface wildcardExtendsObject {
interface SuperWildcardExtendsObject<T> {
List<? extends T> typeForSubstitute();
}
interface MidWildcardExtendsObject extends SuperWildcardExtendsObject<Object> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface wildcardExtendsTypeParameter {
interface SuperWildcard<T, U> {
Map<? extends T, ? extends U> typeForSubstitute();
}
interface MidWildcard<E, K> extends SuperWildcard<E, K> {
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface wildcardSuper {
interface SuperWildcardSuper<T> {
List<? extends T> typeForSubstitute();
}
interface MidWildcardSuper extends SuperWildcardSuper<Integer> {
}
}
@@ -0,0 +1,8 @@
import java.util.*;
interface wildcardToWildcard {
interface SupList<K> extends List<K> {
@Override
boolean addAll(Collection<? extends K> c);
}
}
@@ -0,0 +1,115 @@
/*
* 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.lang.resolve.java;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter;
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaTypeImpl;
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaTypeParameterImpl;
import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase;
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
public abstract class AbstractJavaTypeSubstitutorTest extends JetLightCodeInsightFixtureTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JetLightProjectDescriptor.INSTANCE;
}
public void doTest(@NotNull String testFile) {
PsiFile psiFile = myFixture.configureByFile(testFile);
Project project = myFixture.getProject();
String javaClassName = psiFile.getName().substring(0, psiFile.getName().length() - ".java".length());
PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(javaClassName, GlobalSearchScope.allScope(project));
assert psiClass != null : "Wrong path to test file: " + testFile;
assert psiClass.getInnerClasses().length > 0;
for (PsiClass innerInterface : psiClass.getInnerClasses()) {
PsiMethod method = getMethodWithTestData(innerInterface);
PsiClassType[] superTypes = innerInterface.getSuperTypes();
for (PsiClassType superType : superTypes) {
if (method.getReturnType() != null) {
doTest(superType, method.getReturnType());
}
if (method.getTypeParameters().length > 0) {
doTest(superType, method.getTypeParameters()[0]);
}
PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length > 0) {
doTest(superType, parameters[0].getType());
}
}
}
}
private static void doTest(@NotNull PsiClassType type, @NotNull PsiTypeParameter typeParameter) {
PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(typeParameter);
JavaClassifierType javaClassifierType = (JavaClassifierType) JavaTypeImpl.create(type);
JavaTypeParameter javaTypeToSubstitute = new JavaTypeParameterImpl(typeParameter);
JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute);
if (actualType == null) {
assertEquals(expectedType, null);
}
else {
assertEquals(expectedType, ((JavaTypeImpl) actualType).getPsi());
}
}
private static void doTest(@NotNull PsiClassType type, @NotNull PsiType psiTypeToSubstitute) {
PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(psiTypeToSubstitute);
JavaClassifierType javaClassifierType = (JavaClassifierType) JavaTypeImpl.create(type);
JavaType javaTypeToSubstitute = JavaTypeImpl.create(psiTypeToSubstitute);
JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute);
if (expectedType instanceof PsiEllipsisType) {
PsiEllipsisType ellipsisType = (PsiEllipsisType) expectedType;
assertEquals(ellipsisType.toArrayType(), ((JavaTypeImpl) actualType).getPsi());
}
else {
assertEquals(expectedType, ((JavaTypeImpl) actualType).getPsi());
}
}
@NotNull
private static PsiMethod getMethodWithTestData(@NotNull PsiClass psiClass) {
String substituteParameterName = "typeForSubstitute";
PsiMethod[] methods = psiClass.findMethodsByName(substituteParameterName, false);
if (methods.length == 0) {
methods = psiClass.findMethodsByName(substituteParameterName, true);
}
if (methods.length == 0) {
methods = psiClass.getMethods();
}
assert methods.length > 0 : "Wrong parameters for test: method typeForSubstitute not found";
return methods[0];
}
}
@@ -0,0 +1,259 @@
/*
* 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.lang.resolve.java;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import java.io.File;
import java.util.regex.Pattern;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.jetbrains.jet.lang.resolve.java.AbstractJavaTypeSubstitutorTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/typeSubstitution")
public class JavaTypeSubstitutorTestGenerated extends AbstractJavaTypeSubstitutorTest {
public void testAllFilesPresentInTypeSubstitution() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/typeSubstitution"), Pattern.compile("^(.+)\\.java$"), true);
}
@TestMetadata("arrayType.java")
public void testArrayType() throws Exception {
doTest("idea/testData/typeSubstitution/arrayType.java");
}
@TestMetadata("classType.java")
public void testClassType() throws Exception {
doTest("idea/testData/typeSubstitution/classType.java");
}
@TestMetadata("classWithWildcard.java")
public void testClassWithWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/classWithWildcard.java");
}
@TestMetadata("genericArray.java")
public void testGenericArray() throws Exception {
doTest("idea/testData/typeSubstitution/genericArray.java");
}
@TestMetadata("innerParameter.java")
public void testInnerParameter() throws Exception {
doTest("idea/testData/typeSubstitution/innerParameter.java");
}
@TestMetadata("intersectionType.java")
public void testIntersectionType() throws Exception {
doTest("idea/testData/typeSubstitution/intersectionType.java");
}
@TestMetadata("intersectionTypeAsTypeParameter.java")
public void testIntersectionTypeAsTypeParameter() throws Exception {
doTest("idea/testData/typeSubstitution/intersectionTypeAsTypeParameter.java");
}
@TestMetadata("intersectionTypeInEnum.java")
public void testIntersectionTypeInEnum() throws Exception {
doTest("idea/testData/typeSubstitution/intersectionTypeInEnum.java");
}
@TestMetadata("intersectionTypeInInterfaceDeclaration.java")
public void testIntersectionTypeInInterfaceDeclaration() throws Exception {
doTest("idea/testData/typeSubstitution/intersectionTypeInInterfaceDeclaration.java");
}
@TestMetadata("intersectionTypeInTypeVariableClass.java")
public void testIntersectionTypeInTypeVariableClass() throws Exception {
doTest("idea/testData/typeSubstitution/intersectionTypeInTypeVariableClass.java");
}
@TestMetadata("mapEntry.java")
public void testMapEntry() throws Exception {
doTest("idea/testData/typeSubstitution/mapEntry.java");
}
@TestMetadata("primitiveType.java")
public void testPrimitiveType() throws Exception {
doTest("idea/testData/typeSubstitution/primitiveType.java");
}
@TestMetadata("rawArrayType.java")
public void testRawArrayType() throws Exception {
doTest("idea/testData/typeSubstitution/rawArrayType.java");
}
@TestMetadata("rawArrayTypeParameterWithBound.java")
public void testRawArrayTypeParameterWithBound() throws Exception {
doTest("idea/testData/typeSubstitution/rawArrayTypeParameterWithBound.java");
}
@TestMetadata("rawEnum.java")
public void testRawEnum() throws Exception {
doTest("idea/testData/typeSubstitution/rawEnum.java");
}
@TestMetadata("rawExtendsWildcard.java")
public void testRawExtendsWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/rawExtendsWildcard.java");
}
@TestMetadata("rawIntersectionType.java")
public void testRawIntersectionType() throws Exception {
doTest("idea/testData/typeSubstitution/rawIntersectionType.java");
}
@TestMetadata("rawSuperWildcard.java")
public void testRawSuperWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/rawSuperWildcard.java");
}
@TestMetadata("rawType.java")
public void testRawType() throws Exception {
doTest("idea/testData/typeSubstitution/rawType.java");
}
@TestMetadata("rawTypeInDeclaration.java")
public void testRawTypeInDeclaration() throws Exception {
doTest("idea/testData/typeSubstitution/rawTypeInDeclaration.java");
}
@TestMetadata("rawTypeWithBound.java")
public void testRawTypeWithBound() throws Exception {
doTest("idea/testData/typeSubstitution/rawTypeWithBound.java");
}
@TestMetadata("rawTypeWithSelfReferenceBound.java")
public void testRawTypeWithSelfReferenceBound() throws Exception {
doTest("idea/testData/typeSubstitution/rawTypeWithSelfReferenceBound.java");
}
@TestMetadata("rawWildcardInTypeVariableClass.java")
public void testRawWildcardInTypeVariableClass() throws Exception {
doTest("idea/testData/typeSubstitution/rawWildcardInTypeVariableClass.java");
}
@TestMetadata("rawWildcardWithBound.java")
public void testRawWildcardWithBound() throws Exception {
doTest("idea/testData/typeSubstitution/rawWildcardWithBound.java");
}
@TestMetadata("selfReference.java")
public void testSelfReference() throws Exception {
doTest("idea/testData/typeSubstitution/selfReference.java");
}
@TestMetadata("twoParameters.java")
public void testTwoParameters() throws Exception {
doTest("idea/testData/typeSubstitution/twoParameters.java");
}
@TestMetadata("twoParametersInSubClass.java")
public void testTwoParametersInSubClass() throws Exception {
doTest("idea/testData/typeSubstitution/twoParametersInSubClass.java");
}
@TestMetadata("typeVariableClass.java")
public void testTypeVariableClass() throws Exception {
doTest("idea/testData/typeSubstitution/typeVariableClass.java");
}
@TestMetadata("typeVariableRaw.java")
public void testTypeVariableRaw() throws Exception {
doTest("idea/testData/typeSubstitution/typeVariableRaw.java");
}
@TestMetadata("unboundedWildcard.java")
public void testUnboundedWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/unboundedWildcard.java");
}
@TestMetadata("unboundedWildcardToTypeParameter.java")
public void testUnboundedWildcardToTypeParameter() throws Exception {
doTest("idea/testData/typeSubstitution/unboundedWildcardToTypeParameter.java");
}
@TestMetadata("varargArray.java")
public void testVarargArray() throws Exception {
doTest("idea/testData/typeSubstitution/varargArray.java");
}
@TestMetadata("varargArrayTypeParameter.java")
public void testVarargArrayTypeParameter() throws Exception {
doTest("idea/testData/typeSubstitution/varargArrayTypeParameter.java");
}
@TestMetadata("varargClass.java")
public void testVarargClass() throws Exception {
doTest("idea/testData/typeSubstitution/varargClass.java");
}
@TestMetadata("varargClassWithWildcard.java")
public void testVarargClassWithWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/varargClassWithWildcard.java");
}
@TestMetadata("varargRawType.java")
public void testVarargRawType() throws Exception {
doTest("idea/testData/typeSubstitution/varargRawType.java");
}
@TestMetadata("varargRawTypeWithBound.java")
public void testVarargRawTypeWithBound() throws Exception {
doTest("idea/testData/typeSubstitution/varargRawTypeWithBound.java");
}
@TestMetadata("varargToClass.java")
public void testVarargToClass() throws Exception {
doTest("idea/testData/typeSubstitution/varargToClass.java");
}
@TestMetadata("varargToClassWithWildcard.java")
public void testVarargToClassWithWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/varargToClassWithWildcard.java");
}
@TestMetadata("wildcardExtends.java")
public void testWildcardExtends() throws Exception {
doTest("idea/testData/typeSubstitution/wildcardExtends.java");
}
@TestMetadata("wildcardExtendsObject.java")
public void testWildcardExtendsObject() throws Exception {
doTest("idea/testData/typeSubstitution/wildcardExtendsObject.java");
}
@TestMetadata("wildcardExtendsTypeParameter.java")
public void testWildcardExtendsTypeParameter() throws Exception {
doTest("idea/testData/typeSubstitution/wildcardExtendsTypeParameter.java");
}
@TestMetadata("wildcardSuper.java")
public void testWildcardSuper() throws Exception {
doTest("idea/testData/typeSubstitution/wildcardSuper.java");
}
@TestMetadata("wildcardToWildcard.java")
public void testWildcardToWildcard() throws Exception {
doTest("idea/testData/typeSubstitution/wildcardToWildcard.java");
}
}