mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixed generic type references when read from cls files (IDEA-141230)
https://github.com/JetBrains/intellij-community/pull/273
This commit is contained in:
committed by
Roman Shevchenko
parent
4b4671f860
commit
8c20a632da
+24
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.compiled;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl;
|
||||
import com.intellij.psi.impl.ResolveScopeManager;
|
||||
@@ -33,6 +32,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -143,7 +143,7 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P
|
||||
final Map<PsiTypeParameter, PsiType> substitutionMap) {
|
||||
final PsiClass containingClass = psiClass.getContainingClass();
|
||||
if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final String outerClassRef = StringUtil.getPackageName(canonicalText);
|
||||
final String outerClassRef = getOuterClassRef(canonicalText);
|
||||
final String[] classParameters = PsiNameHelper.getClassParametersText(outerClassRef);
|
||||
final PsiType[] args = classParameters.length == 0 ? null : new ClsReferenceParameterListImpl(this, classParameters).getTypeArguments();
|
||||
final PsiTypeParameter[] typeParameters = containingClass.getTypeParameters();
|
||||
@@ -156,6 +156,27 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
private static String getOuterClassRef(String ref) {
|
||||
int stack = 0;
|
||||
for (int i = ref.length() - 1; i >= 0; i--) {
|
||||
char c = ref.charAt(i);
|
||||
switch (c) {
|
||||
case '<':
|
||||
stack--;
|
||||
break;
|
||||
case '>':
|
||||
stack++;
|
||||
break;
|
||||
case '.':
|
||||
if (stack == 0) return ref.substring(0, i);
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -22,7 +22,9 @@ import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.impl.JavaPsiFacadeEx
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
@@ -236,4 +238,51 @@ class TestCase {
|
||||
assert method.hierarchicalMethodSignature.superSignatures.size() == 0
|
||||
}
|
||||
|
||||
public void "test nested generic signature from binary"() {
|
||||
myFixture.testDataPath = PathManagerEx.getTestDataPath() + "/libResolve/genericSignature"
|
||||
myFixture.copyDirectoryToProject("", "lib")
|
||||
PsiTestUtil.addLibrary(myModule, "lib", myFixture.tempDirFixture.getFile("").path, "lib");
|
||||
|
||||
def javaPsiFacade = JavaPsiFacadeEx.getInstanceEx(project)
|
||||
def factory = javaPsiFacade.elementFactory
|
||||
|
||||
def parameterizedTypes = JavaPsiFacade.getInstance(project).findClass('pkg.ParameterizedTypes', GlobalSearchScope.allScope(project))
|
||||
assert parameterizedTypes
|
||||
|
||||
def parameterP = parameterizedTypes.typeParameters[0]
|
||||
assert parameterP.name == 'P'
|
||||
|
||||
def classInner = parameterizedTypes.innerClasses[0]
|
||||
assert classInner.name == 'Inner'
|
||||
|
||||
def parameterI = classInner.typeParameters[0]
|
||||
assert parameterI.name == 'I'
|
||||
|
||||
def unspecificMethod = parameterizedTypes.findMethodsByName("getUnspecificInner", false)[0]
|
||||
def unspecificReturnType = unspecificMethod.returnType as PsiClassType
|
||||
assert unspecificReturnType.canonicalText == 'pkg.ParameterizedTypes<P>.Inner<java.lang.String>'
|
||||
|
||||
def unspecificResolveResult = unspecificReturnType.resolveGenerics()
|
||||
assert unspecificResolveResult.element == classInner
|
||||
|
||||
def unspecificOuter = factory.createType(parameterizedTypes, unspecificResolveResult.substitutor);
|
||||
assert unspecificOuter.canonicalText == 'pkg.ParameterizedTypes<P>'
|
||||
|
||||
def specificMethod = parameterizedTypes.findMethodsByName("getSpecificInner", false)[0]
|
||||
def specificReturnType = specificMethod.returnType as PsiClassType
|
||||
assert specificReturnType.canonicalText == 'pkg.ParameterizedTypes<java.lang.Number>.Inner<java.lang.String>'
|
||||
|
||||
def specificResolveResult = specificReturnType.resolveGenerics()
|
||||
assert specificResolveResult.element == classInner
|
||||
|
||||
def substitutor = specificResolveResult.substitutor
|
||||
def substitutionMap = substitutor.substitutionMap
|
||||
assert substitutionMap.containsKey(parameterI)
|
||||
assert substitutionMap.containsKey(parameterP)
|
||||
assert substitutor.substitute(parameterP).canonicalText == 'java.lang.Number'
|
||||
|
||||
def specificOuter = factory.createType(parameterizedTypes, specificResolveResult.substitutor);
|
||||
assert specificOuter.canonicalText == 'pkg.ParameterizedTypes<java.lang.Number>'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user