mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] substitute generic types by name in compiled traits
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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 com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class DelegateSubstitutor implements PsiSubstitutor {
|
||||
|
||||
private final @NotNull PsiSubstitutor myDelegate;
|
||||
|
||||
public DelegateSubstitutor(@NotNull PsiSubstitutor delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiType substitute(@NotNull PsiTypeParameter typeParameter) {
|
||||
return myDelegate.substitute(typeParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType substitute(@Nullable PsiType type) {
|
||||
return myDelegate.substitute(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType substituteWithBoundsPromotion(@NotNull PsiTypeParameter typeParameter) {
|
||||
return myDelegate.substituteWithBoundsPromotion(typeParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiSubstitutor put(@NotNull PsiTypeParameter classParameter, PsiType mapping) {
|
||||
return myDelegate.put(classParameter, mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiSubstitutor putAll(@NotNull PsiClass parentClass, PsiType[] mappings) {
|
||||
return myDelegate.putAll(parentClass, mappings);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiSubstitutor putAll(@NotNull PsiSubstitutor another) {
|
||||
return myDelegate.putAll(another);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<PsiTypeParameter, PsiType> getSubstitutionMap() {
|
||||
return myDelegate.getSubstitutionMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myDelegate.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureValid() {
|
||||
myDelegate.ensureValid();
|
||||
}
|
||||
}
|
||||
+35
-12
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.SimpleModificationTracker;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.DelegateSubstitutor;
|
||||
import com.intellij.psi.impl.compiled.ClsClassImpl;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.*;
|
||||
@@ -278,22 +279,44 @@ public class GrTypeDefinitionMembersCache {
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(trait.getProject());
|
||||
final String helperFQN = trait.getQualifiedName();
|
||||
final PsiClass traitHelper = psiFacade.findClass(helperFQN + "$Trait$Helper", trait.getResolveScope());
|
||||
if (traitHelper != null) {
|
||||
final PsiType classType = TypesUtil.createJavaLangClassType(
|
||||
psiFacade.getElementFactory().createType(trait), trait.getProject(), trait.getResolveScope()
|
||||
);
|
||||
for (PsiMethod method : traitHelper.getMethods()) {
|
||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length <= 0) continue;
|
||||
final PsiParameter self = parameters[0];
|
||||
if (self.getType().equals(classType)) {
|
||||
addCandidate(GrGdkMethodImpl.createGdkMethod(method, true, "via @Trait"), substitutor);
|
||||
}
|
||||
if (traitHelper == null) return;
|
||||
final PsiType classType = TypesUtil.createJavaLangClassType(
|
||||
psiFacade.getElementFactory().createType(trait), trait.getProject(), trait.getResolveScope()
|
||||
);
|
||||
final PsiSubstitutor delegateSubstitutor = getSubstitutor(substitutor, trait);
|
||||
for (PsiMethod method : traitHelper.getMethods()) {
|
||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length <= 0) continue;
|
||||
final PsiParameter self = parameters[0];
|
||||
if (self.getType().equals(classType)) {
|
||||
addCandidate(GrGdkMethodImpl.createGdkMethod(method, true, "via @Trait"), delegateSubstitutor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DelegateSubstitutor getSubstitutor(@NotNull final PsiSubstitutor substitutor,
|
||||
@NotNull final PsiClass trait) {
|
||||
final Map<String, PsiType> substitutionMap = ContainerUtil.newTroveMap();
|
||||
for (PsiTypeParameter parameter : trait.getTypeParameters()) {
|
||||
substitutionMap.put(parameter.getName(), substitutor.substitute(parameter));
|
||||
}
|
||||
return new DelegateSubstitutor(substitutor) {
|
||||
@Override
|
||||
public PsiType substitute(@Nullable PsiType type) {
|
||||
final PsiType substituted = super.substitute(type);
|
||||
if (type != null && (substituted == null || substituted.equals(type))) {
|
||||
final PsiType byName = substitutionMap.get(type.getCanonicalText());
|
||||
return byName == null ? substituted : byName;
|
||||
}
|
||||
else {
|
||||
return substituted;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}.getResult();
|
||||
for (CandidateInfo candidateInfo : concreteTraitMethods) {
|
||||
List<GrMethod> methodsToAdd = getExpandingMethods(candidateInfo);
|
||||
|
||||
Reference in New Issue
Block a user