[groovy] use compiled parameter mirror (IDEA-186457)

This commit is contained in:
Daniil Ovchinnikov
2018-02-16 20:17:17 +03:00
parent 5818c8336a
commit d072c7cad2
5 changed files with 44 additions and 14 deletions
@@ -0,0 +1,13 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiType
private open class PsiParameterMirror(original: PsiParameter) : PsiParameter by original
fun PsiParameter.withType(newType: PsiType): PsiParameter {
return object : PsiParameterMirror(this) {
override fun getType(): PsiType = newType
}
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.util;
import com.intellij.codeInsight.AnnotationUtil;
@@ -9,6 +7,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.impl.light.LightMethodBuilder;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.InheritanceUtil;
@@ -22,7 +21,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightField;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.resolve.GroovyTraitFieldsFileIndex;
import org.jetbrains.plugins.groovy.lang.resolve.GroovyTraitFieldsFileIndex.TraitFieldDescriptor;
import org.jetbrains.plugins.groovy.lang.resolve.GroovyTraitMethodsFileIndex;
@@ -33,6 +31,7 @@ import java.util.Map;
import static com.intellij.psi.PsiModifier.ABSTRACT;
import static org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags.*;
import static org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.MirrorsKt.withType;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_TRAIT;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_TRAIT_IMPLEMENTED;
@@ -120,12 +119,12 @@ public class GrTraitUtil {
}
private static PsiMethod createTraitMethodFromCompiledHelperMethod(PsiMethod compiledMethod, ClsClassImpl trait) {
final GrLightMethodBuilder result = new GrLightMethodBuilder(trait.getManager(), compiledMethod.getName());
final LightMethodBuilder result = new LightMethodBuilder(trait.getManager(), compiledMethod.getName());
result.setOriginInfo("via @Trait");
result.addModifier(PsiModifier.STATIC);
for (PsiTypeParameter parameter : compiledMethod.getTypeParameters()) {
result.getTypeParameterList().addParameter(parameter);
result.addTypeParameter(parameter);
}
final PsiTypeVisitor<PsiType> corrector = createCorrector(compiledMethod, trait);
@@ -134,18 +133,16 @@ public class GrTraitUtil {
for (int i = 1; i < methodParameters.length; i++) {
final PsiParameter originalParameter = methodParameters[i];
final PsiType correctedType = originalParameter.getType().accept(corrector);
final String name = originalParameter.getName();
assert name != null : compiledMethod;
result.addParameter(name, correctedType, false);
result.addParameter(withType(originalParameter, correctedType));
}
for (PsiClassType type : compiledMethod.getThrowsList().getReferencedTypes()) {
final PsiType correctedType = type.accept(corrector);
result.getThrowsList().addReference(correctedType instanceof PsiClassType ? (PsiClassType)correctedType : type);
result.addException(correctedType instanceof PsiClassType ? (PsiClassType)correctedType : type);
}
final PsiType originalType = compiledMethod.getReturnType();
result.setReturnType(originalType == null ? null : originalType.accept(corrector));
result.setMethodReturnType(originalType == null ? null : originalType.accept(corrector));
final PsiClass traitSource = trait.getSourceMirrorClass();
final PsiMethod sourceMethod = traitSource == null ? null : traitSource.findMethodBySignature(result, false);
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve
import com.intellij.openapi.module.Module
@@ -305,6 +303,28 @@ class CC implements somepackage.TT {
)
}
void 'test static trait method with @DelegatesTo(type)'() {
configureTraitInheritor()
def method = resolveByText '''\
def usage(ExternalConcrete ec) {
ec.delegatesTo { <caret>toUpperCase() }
}
''', PsiMethod
assert method.name == 'toUpperCase'
assert method.containingClass.qualifiedName == 'java.lang.String'
}
void 'test static trait method with @ClosureParams(FromString)'() {
configureTraitInheritor()
def method = resolveByText '''\
def usage(ExternalConcrete ec) {
ec.closureParams { it.<caret>toUpperCase() }
}
''', PsiMethod
assert method.name == 'toUpperCase'
assert method.containingClass.qualifiedName == 'java.lang.String'
}
private PsiClass configureTraitInheritor() {
myFixture.addFileToProject "inheritors.groovy", '''\
class PojoInheritor extends somepackage.Pojo {}
Binary file not shown.
Binary file not shown.