JavaDescriptorSignatureResolver
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorSignatureResolver;
|
||||
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -46,6 +47,7 @@ public class InjectorForJavaSemanticServices {
|
||||
private CompilerSpecialMode compilerSpecialMode;
|
||||
private final Project project;
|
||||
private JavaTypeTransformer javaTypeTransformer;
|
||||
private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver;
|
||||
private NamespaceFactoryImpl namespaceFactory;
|
||||
|
||||
public InjectorForJavaSemanticServices(
|
||||
@@ -62,6 +64,7 @@ public class InjectorForJavaSemanticServices {
|
||||
this.compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
|
||||
this.project = project;
|
||||
this.javaTypeTransformer = new JavaTypeTransformer();
|
||||
this.javaDescriptorSignatureResolver = new JavaDescriptorSignatureResolver();
|
||||
this.namespaceFactory = new NamespaceFactoryImpl();
|
||||
|
||||
this.javaSemanticServices.setDescriptorResolver(javaDescriptorResolver);
|
||||
@@ -69,6 +72,7 @@ public class InjectorForJavaSemanticServices {
|
||||
this.javaSemanticServices.setTrace(bindingTrace);
|
||||
this.javaSemanticServices.setTypeTransformer(javaTypeTransformer);
|
||||
|
||||
this.javaDescriptorResolver.setJavaDescriptorSignatureResolver(javaDescriptorSignatureResolver);
|
||||
this.javaDescriptorResolver.setNamespaceFactory(namespaceFactory);
|
||||
this.javaDescriptorResolver.setProject(project);
|
||||
this.javaDescriptorResolver.setPsiClassFinder(psiClassFinderForJvm);
|
||||
@@ -85,6 +89,9 @@ public class InjectorForJavaSemanticServices {
|
||||
javaTypeTransformer.setJavaSemanticServices(javaSemanticServices);
|
||||
javaTypeTransformer.setResolver(javaDescriptorResolver);
|
||||
|
||||
javaDescriptorSignatureResolver.setJavaDescriptorResolver(javaDescriptorResolver);
|
||||
javaDescriptorSignatureResolver.setJavaSemanticServices(javaSemanticServices);
|
||||
|
||||
namespaceFactory.setConfiguration(javaBridgeConfiguration);
|
||||
namespaceFactory.setModuleDescriptor(moduleDescriptor);
|
||||
namespaceFactory.setTrace(bindingTrace);
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptBodyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorSignatureResolver;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -92,6 +93,7 @@ public class InjectorForTopDownAnalyzerForJvm {
|
||||
private ScriptBodyResolver scriptBodyResolver;
|
||||
private JavaSemanticServices javaSemanticServices;
|
||||
private JavaTypeTransformer javaTypeTransformer;
|
||||
private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver;
|
||||
|
||||
public InjectorForTopDownAnalyzerForJvm(
|
||||
@NotNull Project project,
|
||||
@@ -132,6 +134,7 @@ public class InjectorForTopDownAnalyzerForJvm {
|
||||
this.scriptBodyResolver = new ScriptBodyResolver();
|
||||
this.javaSemanticServices = new JavaSemanticServices();
|
||||
this.javaTypeTransformer = new JavaTypeTransformer();
|
||||
this.javaDescriptorSignatureResolver = new JavaDescriptorSignatureResolver();
|
||||
|
||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||
this.topDownAnalyzer.setContext(topDownAnalysisContext);
|
||||
@@ -169,6 +172,7 @@ public class InjectorForTopDownAnalyzerForJvm {
|
||||
this.javaBridgeConfiguration.setMode(compilerSpecialMode);
|
||||
this.javaBridgeConfiguration.setProject(project);
|
||||
|
||||
javaDescriptorResolver.setJavaDescriptorSignatureResolver(javaDescriptorSignatureResolver);
|
||||
javaDescriptorResolver.setNamespaceFactory(namespaceFactory);
|
||||
javaDescriptorResolver.setProject(project);
|
||||
javaDescriptorResolver.setPsiClassFinder(psiClassFinderForJvm);
|
||||
@@ -246,6 +250,9 @@ public class InjectorForTopDownAnalyzerForJvm {
|
||||
javaTypeTransformer.setJavaSemanticServices(javaSemanticServices);
|
||||
javaTypeTransformer.setResolver(javaDescriptorResolver);
|
||||
|
||||
javaDescriptorSignatureResolver.setJavaDescriptorResolver(javaDescriptorResolver);
|
||||
javaDescriptorSignatureResolver.setJavaSemanticServices(javaSemanticServices);
|
||||
|
||||
javaBridgeConfiguration.init();
|
||||
|
||||
psiClassFinderForJvm.initialize();
|
||||
|
||||
+14
-302
@@ -77,40 +77,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
}
|
||||
};
|
||||
|
||||
private enum TypeParameterDescriptorOrigin {
|
||||
JAVA,
|
||||
KOTLIN,
|
||||
}
|
||||
|
||||
public static class TypeParameterDescriptorInitialization {
|
||||
@NotNull
|
||||
private final TypeParameterDescriptorOrigin origin;
|
||||
@NotNull
|
||||
final TypeParameterDescriptorImpl descriptor;
|
||||
final PsiTypeParameter psiTypeParameter;
|
||||
@Nullable
|
||||
private final List<JetType> upperBoundsForKotlin;
|
||||
@Nullable
|
||||
private final List<JetType> lowerBoundsForKotlin;
|
||||
|
||||
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||
this.origin = TypeParameterDescriptorOrigin.JAVA;
|
||||
this.descriptor = descriptor;
|
||||
this.psiTypeParameter = psiTypeParameter;
|
||||
this.upperBoundsForKotlin = null;
|
||||
this.lowerBoundsForKotlin = null;
|
||||
}
|
||||
|
||||
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter,
|
||||
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
|
||||
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
|
||||
this.descriptor = descriptor;
|
||||
this.psiTypeParameter = psiTypeParameter;
|
||||
this.upperBoundsForKotlin = upperBoundsForKotlin;
|
||||
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static abstract class ResolverScopeData {
|
||||
@Nullable
|
||||
@@ -185,7 +151,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
|
||||
/** Class with instance members */
|
||||
static class ResolverBinaryClassData extends ResolverScopeData {
|
||||
private final ClassDescriptorFromJvmBytecode classDescriptor;
|
||||
final ClassDescriptorFromJvmBytecode classDescriptor;
|
||||
|
||||
ResolverBinaryClassData(@NotNull PsiClass psiClass, @NotNull FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) {
|
||||
super(psiClass, null, fqName, false, classDescriptor);
|
||||
@@ -199,7 +165,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
|
||||
static final ResolverBinaryClassData NEGATIVE = new ResolverBinaryClassData(true);
|
||||
|
||||
List<TypeParameterDescriptorInitialization> typeParameters;
|
||||
List<JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization> typeParameters;
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getClassDescriptor() {
|
||||
@@ -247,6 +213,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
private NamespaceFactory namespaceFactory;
|
||||
private BindingTrace trace;
|
||||
private PsiClassFinder psiClassFinder;
|
||||
private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver;
|
||||
|
||||
@Inject
|
||||
public void setProject(Project project) {
|
||||
@@ -273,6 +240,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
this.psiClassFinder = psiClassFinder;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setJavaDescriptorSignatureResolver(JavaDescriptorSignatureResolver javaDescriptorSignatureResolver) {
|
||||
this.javaDescriptorSignatureResolver = javaDescriptorSignatureResolver;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@@ -371,10 +342,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
|
||||
List<JetType> supertypes = new ArrayList<JetType>();
|
||||
|
||||
classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData);
|
||||
classData.typeParameters = javaDescriptorSignatureResolver.createUninitializedClassTypeParameters(psiClass, classData);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
for (TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) {
|
||||
for (JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) {
|
||||
typeParameters.add(typeParameter.descriptor);
|
||||
}
|
||||
|
||||
@@ -394,7 +365,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
classData.classDescriptor.createTypeConstructor();
|
||||
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(semanticServices, classData));
|
||||
|
||||
initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName());
|
||||
javaDescriptorSignatureResolver.initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName());
|
||||
|
||||
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
|
||||
supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData, classData.getTypeParameters()));
|
||||
@@ -576,166 +547,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
return classData.classDescriptor;
|
||||
}
|
||||
|
||||
private List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData) {
|
||||
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
|
||||
|
||||
if (jetClassAnnotation.signature().length() > 0) {
|
||||
return resolveClassTypeParametersFromJetSignature(
|
||||
jetClassAnnotation.signature(), psiClass, classData.classDescriptor);
|
||||
}
|
||||
|
||||
return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
|
||||
for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
|
||||
if (typeParameter.getName().equals(name)) {
|
||||
return typeParameter;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
|
||||
}
|
||||
|
||||
|
||||
private boolean isJavaLangObject(JetType type) {
|
||||
static boolean isJavaLangObject(JetType type) {
|
||||
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
return classifierDescriptor instanceof ClassDescriptor &&
|
||||
DescriptorUtils.getFQName(classifierDescriptor).equalsTo(JdkNames.JL_OBJECT.getFqName());
|
||||
}
|
||||
|
||||
|
||||
private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
|
||||
|
||||
@NotNull
|
||||
private final PsiTypeParameterListOwner psiOwner;
|
||||
@NotNull
|
||||
private final String name;
|
||||
@NotNull
|
||||
private final TypeVariableResolver typeVariableResolver;
|
||||
@NotNull
|
||||
private final TypeParameterDescriptorImpl typeParameterDescriptor;
|
||||
|
||||
protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
|
||||
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor)
|
||||
{
|
||||
if (name.isEmpty()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
this.psiOwner = psiOwner;
|
||||
this.name = name;
|
||||
this.typeVariableResolver = typeVariableResolver;
|
||||
this.typeParameterDescriptor = typeParameterDescriptor;
|
||||
}
|
||||
|
||||
List<JetType> upperBounds = new ArrayList<JetType>();
|
||||
List<JetType> lowerBounds = new ArrayList<JetType>();
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitClassBound() {
|
||||
return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
if (isJavaLangObject(jetType)) {
|
||||
return;
|
||||
}
|
||||
upperBounds.add(jetType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterfaceBound() {
|
||||
return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
upperBounds.add(jetType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFormalTypeParameterEnd() {
|
||||
PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
|
||||
TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds, lowerBounds);
|
||||
done(typeParameterDescriptorInitialization);
|
||||
}
|
||||
|
||||
protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor);
|
||||
}
|
||||
|
||||
private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter {
|
||||
@NotNull
|
||||
private final DeclarationDescriptor containingDeclaration;
|
||||
@NotNull
|
||||
private final PsiTypeParameterListOwner psiOwner;
|
||||
|
||||
private final List<TypeParameterDescriptor> previousTypeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
// note changes state in this method
|
||||
private final TypeVariableResolver typeVariableResolver;
|
||||
|
||||
|
||||
private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) {
|
||||
this.containingDeclaration = containingDeclaration;
|
||||
this.psiOwner = psiOwner;
|
||||
|
||||
this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
|
||||
previousTypeParameters,
|
||||
containingDeclaration,
|
||||
context);
|
||||
}
|
||||
|
||||
private int formalTypeParameterIndex = 0;
|
||||
|
||||
|
||||
List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
|
||||
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
containingDeclaration,
|
||||
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
||||
reified,
|
||||
JetSignatureUtils.translateVariance(variance),
|
||||
Name.identifier(name),
|
||||
formalTypeParameterIndex++);
|
||||
|
||||
previousTypeParameters.add(typeParameter);
|
||||
|
||||
return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) {
|
||||
@Override
|
||||
protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) {
|
||||
r.add(typeParameterDescriptor);
|
||||
previousTypeParameters.add(typeParameterDescriptor.descriptor);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiClass clazz, final ClassDescriptor classDescriptor) {
|
||||
String context = "class " + clazz.getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) {
|
||||
@Override
|
||||
public JetSignatureVisitor visitSuperclass() {
|
||||
// TODO
|
||||
return new JetSignatureAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterface() {
|
||||
// TODO
|
||||
return new JetSignatureAdapter();
|
||||
}
|
||||
};
|
||||
new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor);
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassOrNamespaceDescriptor resolveParentDescriptor(@NotNull PsiClass psiClass) {
|
||||
FqName fqName = new FqName(psiClass.getQualifiedName());
|
||||
@@ -757,75 +575,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
return ns;
|
||||
}
|
||||
|
||||
private List<TypeParameterDescriptorInitialization> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
|
||||
List<TypeParameterDescriptorInitialization> result = Lists.newArrayList();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter);
|
||||
result.add(typeParameterDescriptor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
containingDeclaration,
|
||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||
false,
|
||||
Variance.INVARIANT,
|
||||
Name.identifier(psiTypeParameter.getName()),
|
||||
psiTypeParameter.getIndex()
|
||||
);
|
||||
return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter);
|
||||
}
|
||||
|
||||
private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor;
|
||||
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
|
||||
List<?> upperBounds = typeParameter.upperBoundsForKotlin;
|
||||
if (upperBounds.size() == 0){
|
||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||
}
|
||||
else {
|
||||
for (JetType upperBound : typeParameter.upperBoundsForKotlin) {
|
||||
typeParameterDescriptor.addUpperBound(upperBound);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: lower bounds
|
||||
}
|
||||
else {
|
||||
PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
|
||||
if (referencedTypes.length == 0){
|
||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||
}
|
||||
else if (referencedTypes.length == 1) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
else {
|
||||
for (PsiClassType referencedType : referencedTypes) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
typeParameterDescriptor.setInitialized();
|
||||
}
|
||||
|
||||
private void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
|
||||
List<TypeParameterDescriptor> prevTypeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
|
||||
for (TypeParameterDescriptorInitialization typeParameterDescriptor : typeParametersInitialization) {
|
||||
typeParameters.add(typeParameterDescriptor.descriptor);
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
|
||||
prevTypeParameters.add(psiTypeParameter.descriptor);
|
||||
initializeTypeParameter(psiTypeParameter,
|
||||
TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, typeParametersOwner, context));
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<JetType> getSupertypes(PsiClassWrapper psiClass, ResolverBinaryClassData classData, List<TypeParameterDescriptor> typeParameters) {
|
||||
ClassDescriptor classDescriptor = classData.classDescriptor;
|
||||
|
||||
@@ -1365,14 +1114,14 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember();
|
||||
|
||||
if (anyMember == members.setter) {
|
||||
typeParameters = resolveMethodTypeParameters(method, propertyDescriptor);
|
||||
typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
if (members.getter != null) {
|
||||
PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember();
|
||||
|
||||
if (anyMember == members.getter) {
|
||||
typeParameters = resolveMethodTypeParameters(method, propertyDescriptor);
|
||||
typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,7 +1336,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
|
||||
String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();
|
||||
|
||||
List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
|
||||
List<TypeParameterDescriptor> methodTypeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, functionDescriptorImpl);
|
||||
|
||||
TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters, functionDescriptorImpl, context);
|
||||
|
||||
@@ -1792,43 +1541,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
}
|
||||
}
|
||||
|
||||
private List<TypeParameterDescriptor> resolveMethodTypeParameters(
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull DeclarationDescriptor functionDescriptor) {
|
||||
|
||||
List<TypeParameterDescriptorInitialization> typeParametersIntialization;
|
||||
if (method.getJetMethod().typeParameters().length() > 0) {
|
||||
typeParametersIntialization = resolveMethodTypeParametersFromJetSignature(
|
||||
method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor);
|
||||
}
|
||||
else {
|
||||
typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
|
||||
}
|
||||
|
||||
String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName();
|
||||
initializeTypeParameters(typeParametersIntialization, functionDescriptor, context);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size());
|
||||
|
||||
for (TypeParameterDescriptorInitialization tpdi : typeParametersIntialization) {
|
||||
typeParameters.add(tpdi.descriptor);
|
||||
}
|
||||
|
||||
return typeParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiMethod method, final DeclarationDescriptor functionDescriptor)
|
||||
{
|
||||
String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context);
|
||||
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor);
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method,
|
||||
@NotNull TypeVariableResolver typeVariableResolver) {
|
||||
|
||||
|
||||
+373
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.PsiTypeParameterListOwner;
|
||||
import jet.typeinfo.TypeInfoVariance;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
|
||||
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
|
||||
import org.jetbrains.jet.rt.signature.JetSignatureReader;
|
||||
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class JavaDescriptorSignatureResolver {
|
||||
|
||||
@NotNull
|
||||
private JavaDescriptorResolver javaDescriptorResolver;
|
||||
@NotNull
|
||||
private JavaSemanticServices semanticServices;
|
||||
|
||||
@Inject
|
||||
public void setJavaDescriptorResolver(@NotNull JavaDescriptorResolver javaDescriptorResolver) {
|
||||
this.javaDescriptorResolver = javaDescriptorResolver;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setJavaSemanticServices(@NotNull JavaSemanticServices javaSemanticServices) {
|
||||
this.semanticServices = javaSemanticServices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private enum TypeParameterDescriptorOrigin {
|
||||
JAVA,
|
||||
KOTLIN,
|
||||
}
|
||||
|
||||
public static class TypeParameterDescriptorInitialization {
|
||||
@NotNull
|
||||
private final TypeParameterDescriptorOrigin origin;
|
||||
@NotNull
|
||||
final TypeParameterDescriptorImpl descriptor;
|
||||
final PsiTypeParameter psiTypeParameter;
|
||||
@Nullable
|
||||
private final List<JetType> upperBoundsForKotlin;
|
||||
@Nullable
|
||||
private final List<JetType> lowerBoundsForKotlin;
|
||||
|
||||
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||
this.origin = TypeParameterDescriptorOrigin.JAVA;
|
||||
this.descriptor = descriptor;
|
||||
this.psiTypeParameter = psiTypeParameter;
|
||||
this.upperBoundsForKotlin = null;
|
||||
this.lowerBoundsForKotlin = null;
|
||||
}
|
||||
|
||||
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter,
|
||||
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
|
||||
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
|
||||
this.descriptor = descriptor;
|
||||
this.psiTypeParameter = psiTypeParameter;
|
||||
this.upperBoundsForKotlin = upperBoundsForKotlin;
|
||||
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
private static PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
|
||||
for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
|
||||
if (typeParameter.getName().equals(name)) {
|
||||
return typeParameter;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
|
||||
|
||||
@NotNull
|
||||
private final PsiTypeParameterListOwner psiOwner;
|
||||
@NotNull
|
||||
private final String name;
|
||||
@NotNull
|
||||
private final TypeVariableResolver typeVariableResolver;
|
||||
@NotNull
|
||||
private final TypeParameterDescriptorImpl typeParameterDescriptor;
|
||||
|
||||
protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
|
||||
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor)
|
||||
{
|
||||
if (name.isEmpty()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
this.psiOwner = psiOwner;
|
||||
this.name = name;
|
||||
this.typeVariableResolver = typeVariableResolver;
|
||||
this.typeParameterDescriptor = typeParameterDescriptor;
|
||||
}
|
||||
|
||||
List<JetType> upperBounds = new ArrayList<JetType>();
|
||||
List<JetType> lowerBounds = new ArrayList<JetType>();
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitClassBound() {
|
||||
return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
if (JavaDescriptorResolver.isJavaLangObject(jetType)) {
|
||||
return;
|
||||
}
|
||||
upperBounds.add(jetType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterfaceBound() {
|
||||
return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
upperBounds.add(jetType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFormalTypeParameterEnd() {
|
||||
PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
|
||||
TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds, lowerBounds);
|
||||
done(typeParameterDescriptorInitialization);
|
||||
}
|
||||
|
||||
protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor);
|
||||
}
|
||||
|
||||
private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter {
|
||||
@NotNull
|
||||
private final DeclarationDescriptor containingDeclaration;
|
||||
@NotNull
|
||||
private final PsiTypeParameterListOwner psiOwner;
|
||||
|
||||
private final List<TypeParameterDescriptor> previousTypeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
// note changes state in this method
|
||||
private final TypeVariableResolver typeVariableResolver;
|
||||
|
||||
|
||||
private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) {
|
||||
this.containingDeclaration = containingDeclaration;
|
||||
this.psiOwner = psiOwner;
|
||||
|
||||
this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
|
||||
previousTypeParameters,
|
||||
containingDeclaration,
|
||||
context);
|
||||
}
|
||||
|
||||
private int formalTypeParameterIndex = 0;
|
||||
|
||||
|
||||
List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
|
||||
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
containingDeclaration,
|
||||
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
||||
reified,
|
||||
JetSignatureUtils.translateVariance(variance),
|
||||
Name.identifier(name),
|
||||
formalTypeParameterIndex++);
|
||||
|
||||
previousTypeParameters.add(typeParameter);
|
||||
|
||||
return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) {
|
||||
@Override
|
||||
protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) {
|
||||
r.add(typeParameterDescriptor);
|
||||
previousTypeParameters.add(typeParameterDescriptor.descriptor);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiClass clazz, final ClassDescriptor classDescriptor) {
|
||||
String context = "class " + clazz.getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) {
|
||||
@Override
|
||||
public JetSignatureVisitor visitSuperclass() {
|
||||
// TODO
|
||||
return new JetSignatureAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterface() {
|
||||
// TODO
|
||||
return new JetSignatureAdapter();
|
||||
}
|
||||
};
|
||||
new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor);
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
|
||||
private List<TypeParameterDescriptorInitialization> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
|
||||
List<TypeParameterDescriptorInitialization> result = Lists.newArrayList();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter);
|
||||
result.add(typeParameterDescriptor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
containingDeclaration,
|
||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||
false,
|
||||
Variance.INVARIANT,
|
||||
Name.identifier(psiTypeParameter.getName()),
|
||||
psiTypeParameter.getIndex()
|
||||
);
|
||||
return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter);
|
||||
}
|
||||
|
||||
private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor;
|
||||
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
|
||||
List<?> upperBounds = typeParameter.upperBoundsForKotlin;
|
||||
if (upperBounds.size() == 0){
|
||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||
}
|
||||
else {
|
||||
for (JetType upperBound : typeParameter.upperBoundsForKotlin) {
|
||||
typeParameterDescriptor.addUpperBound(upperBound);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: lower bounds
|
||||
}
|
||||
else {
|
||||
PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
|
||||
if (referencedTypes.length == 0){
|
||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||
}
|
||||
else if (referencedTypes.length == 1) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
else {
|
||||
for (PsiClassType referencedType : referencedTypes) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
typeParameterDescriptor.setInitialized();
|
||||
}
|
||||
|
||||
void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
|
||||
List<TypeParameterDescriptor> prevTypeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
|
||||
for (TypeParameterDescriptorInitialization typeParameterDescriptor : typeParametersInitialization) {
|
||||
typeParameters.add(typeParameterDescriptor.descriptor);
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
|
||||
prevTypeParameters.add(psiTypeParameter.descriptor);
|
||||
initializeTypeParameter(psiTypeParameter,
|
||||
TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, typeParametersOwner, context));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, JavaDescriptorResolver.ResolverBinaryClassData classData) {
|
||||
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
|
||||
|
||||
if (jetClassAnnotation.signature().length() > 0) {
|
||||
return resolveClassTypeParametersFromJetSignature(
|
||||
jetClassAnnotation.signature(), psiClass, classData.classDescriptor);
|
||||
}
|
||||
|
||||
return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
|
||||
}
|
||||
|
||||
|
||||
List<TypeParameterDescriptor> resolveMethodTypeParameters(
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull DeclarationDescriptor functionDescriptor) {
|
||||
|
||||
List<TypeParameterDescriptorInitialization> typeParametersIntialization;
|
||||
if (method.getJetMethod().typeParameters().length() > 0) {
|
||||
typeParametersIntialization = resolveMethodTypeParametersFromJetSignature(
|
||||
method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor);
|
||||
}
|
||||
else {
|
||||
typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
|
||||
}
|
||||
|
||||
String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName();
|
||||
initializeTypeParameters(typeParametersIntialization, functionDescriptor, context);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size());
|
||||
|
||||
for (TypeParameterDescriptorInitialization tpdi : typeParametersIntialization) {
|
||||
typeParameters.add(tpdi.descriptor);
|
||||
}
|
||||
|
||||
return typeParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiMethod method, final DeclarationDescriptor functionDescriptor)
|
||||
{
|
||||
String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context);
|
||||
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor);
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user