Merge remote branch 'origin/master'
This commit is contained in:
@@ -619,6 +619,11 @@ public class JetTypeMapper {
|
|||||||
signatureVisitor.writeInterfaceBoundEnd();
|
signatureVisitor.writeInterfaceBoundEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
||||||
|
signatureVisitor.writeInterfaceBound();
|
||||||
|
mapType(jetType, signatureVisitor);
|
||||||
|
signatureVisitor.writeInterfaceBoundEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signatureVisitor.writeFormalTypeParameterEnd();
|
signatureVisitor.writeFormalTypeParameterEnd();
|
||||||
|
|||||||
+132
-24
@@ -166,8 +166,17 @@ public class JavaDescriptorResolver {
|
|||||||
);
|
);
|
||||||
classDescriptor.setName(name);
|
classDescriptor.setName(name);
|
||||||
|
|
||||||
|
class OuterClassTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||||
|
throw new IllegalStateException("not implemented"); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<JetType> supertypes = new ArrayList<JetType>();
|
List<JetType> supertypes = new ArrayList<JetType>();
|
||||||
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor);
|
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor, new OuterClassTypeVariableResolver());
|
||||||
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
|
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
@@ -225,7 +234,10 @@ public class JavaDescriptorResolver {
|
|||||||
classDescriptor,
|
classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
false);
|
false);
|
||||||
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters());
|
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
|
||||||
|
constructor.getParameterList().getParameters(),
|
||||||
|
new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too
|
||||||
|
);
|
||||||
if (valueParameterDescriptors.receiverType != null) {
|
if (valueParameterDescriptors.receiverType != null) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@@ -242,14 +254,14 @@ public class JavaDescriptorResolver {
|
|||||||
return classDescriptor;
|
return classDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) {
|
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor, TypeVariableResolver typeVariableResolver) {
|
||||||
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
|
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
|
||||||
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
|
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
|
||||||
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
|
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
|
||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
String typeParametersString = (String) attributeValue.getValue();
|
String typeParametersString = (String) attributeValue.getValue();
|
||||||
if (typeParametersString != null) {
|
if (typeParametersString != null) {
|
||||||
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor);
|
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor, typeVariableResolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,14 +302,20 @@ public class JavaDescriptorResolver {
|
|||||||
private final PsiTypeParameterListOwner psiOwner;
|
private final PsiTypeParameterListOwner psiOwner;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final TypeInfoVariance variance;
|
private final TypeInfoVariance variance;
|
||||||
|
private final TypeVariableResolver typeVariableResolver;
|
||||||
|
|
||||||
protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
|
protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
|
||||||
String name, TypeInfoVariance variance)
|
String name, TypeInfoVariance variance, TypeVariableResolver typeVariableResolver)
|
||||||
{
|
{
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
this.containingDeclaration = containingDeclaration;
|
this.containingDeclaration = containingDeclaration;
|
||||||
this.psiOwner = psiOwner;
|
this.psiOwner = psiOwner;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.variance = variance;
|
this.variance = variance;
|
||||||
|
this.typeVariableResolver = typeVariableResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -307,7 +325,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitClassBound() {
|
public JetSignatureVisitor visitClassBound() {
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
if (isJavaLangObject(jetType)) {
|
if (isJavaLangObject(jetType)) {
|
||||||
@@ -320,7 +338,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitInterfaceBound() {
|
public JetSignatureVisitor visitInterfaceBound() {
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
upperBounds.add(jetType);
|
upperBounds.add(jetType);
|
||||||
@@ -348,12 +366,28 @@ public class JavaDescriptorResolver {
|
|||||||
/**
|
/**
|
||||||
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
|
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
|
||||||
*/
|
*/
|
||||||
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, final JavaClassDescriptor classDescriptor) {
|
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz,
|
||||||
|
final JavaClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) {
|
||||||
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
||||||
|
|
||||||
|
class MyTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||||
|
for (TypeParameterDescriptor typeParameter : r) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outerClassTypeVariableResolver.getTypeVariable(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
|
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
||||||
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) {
|
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance, new MyTypeVariableResolver()) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
r.add(typeParameterDescriptor);
|
r.add(typeParameterDescriptor);
|
||||||
@@ -548,12 +582,13 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
|
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration,
|
||||||
|
PsiParameter[] parameters, TypeVariableResolver typeVariableResolver) {
|
||||||
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
||||||
JetType receiverType = null;
|
JetType receiverType = null;
|
||||||
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
|
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
|
||||||
PsiParameter parameter = parameters[i];
|
PsiParameter parameter = parameters[i];
|
||||||
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter);
|
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter, typeVariableResolver);
|
||||||
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
|
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
|
||||||
// TODO
|
// TODO
|
||||||
} else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
|
} else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
|
||||||
@@ -601,7 +636,8 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
|
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i,
|
||||||
|
PsiParameter parameter, TypeVariableResolver typeVariableResolver) {
|
||||||
PsiType psiType = parameter.getType();
|
PsiType psiType = parameter.getType();
|
||||||
|
|
||||||
JetType varargElementType;
|
JetType varargElementType;
|
||||||
@@ -663,7 +699,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
JetType outType;
|
JetType outType;
|
||||||
if (typeFromAnnotation != null && typeFromAnnotation.length() > 0) {
|
if (typeFromAnnotation != null && typeFromAnnotation.length() > 0) {
|
||||||
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation);
|
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
|
||||||
} else {
|
} else {
|
||||||
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
||||||
}
|
}
|
||||||
@@ -750,6 +786,26 @@ public class JavaDescriptorResolver {
|
|||||||
return typeSubstitutor;
|
return typeSubstitutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TypeParameterListTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
|
private final List<TypeParameterDescriptor> typeParameters;
|
||||||
|
|
||||||
|
private TypeParameterListTypeVariableResolver(List<TypeParameterDescriptor> typeParameters) {
|
||||||
|
this.typeParameters = typeParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||||
|
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) {
|
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) {
|
||||||
PsiType returnType = method.getReturnType();
|
PsiType returnType = method.getReturnType();
|
||||||
@@ -763,7 +819,17 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
}
|
}
|
||||||
DeclarationDescriptor classDescriptor = method.hasModifierProperty(PsiModifier.STATIC) ? resolveNamespace(method.getContainingClass()) : resolveClass(method.getContainingClass());
|
DeclarationDescriptor classDescriptor;
|
||||||
|
final List<TypeParameterDescriptor> classTypeParameters;
|
||||||
|
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||||
|
classDescriptor = resolveNamespace(method.getContainingClass());
|
||||||
|
classTypeParameters = Collections.emptyList();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ClassDescriptor classClassDescriptor = resolveClass(method.getContainingClass());
|
||||||
|
classDescriptor = classClassDescriptor;
|
||||||
|
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
|
||||||
|
}
|
||||||
if (classDescriptor == null) {
|
if (classDescriptor == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -774,14 +840,39 @@ public class JavaDescriptorResolver {
|
|||||||
method.getName()
|
method.getName()
|
||||||
);
|
);
|
||||||
methodDescriptorCache.put(method, functionDescriptorImpl);
|
methodDescriptorCache.put(method, functionDescriptorImpl);
|
||||||
List<TypeParameterDescriptor> typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
|
|
||||||
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters);
|
// TODO: add outer classes
|
||||||
|
TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters);
|
||||||
|
|
||||||
|
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
|
||||||
|
|
||||||
|
class MethodTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||||
|
for (TypeParameterDescriptor typeParameter : methodTypeParameters) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (TypeParameterDescriptor typeParameter : classTypeParameters) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters, new MethodTypeVariableResolver());
|
||||||
functionDescriptorImpl.initialize(
|
functionDescriptorImpl.initialize(
|
||||||
valueParameterDescriptors.receiverType,
|
valueParameterDescriptors.receiverType,
|
||||||
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
||||||
typeParameters,
|
methodTypeParameters,
|
||||||
valueParameterDescriptors.descriptors,
|
valueParameterDescriptors.descriptors,
|
||||||
makeReturnType(returnType, method),
|
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
|
||||||
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
|
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
|
||||||
resolveVisibilityFromPsiModifiers(method)
|
resolveVisibilityFromPsiModifiers(method)
|
||||||
);
|
);
|
||||||
@@ -793,14 +884,14 @@ public class JavaDescriptorResolver {
|
|||||||
return substitutedFunctionDescriptor;
|
return substitutedFunctionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeParameterDescriptor> resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) {
|
private List<TypeParameterDescriptor> resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl, TypeVariableResolver classTypeVariableResolver) {
|
||||||
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
|
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
|
||||||
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
|
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
|
||||||
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
|
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
|
||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
String typeParametersString = (String) attributeValue.getValue();
|
String typeParametersString = (String) attributeValue.getValue();
|
||||||
if (typeParametersString != null) {
|
if (typeParametersString != null) {
|
||||||
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl);
|
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl, classTypeVariableResolver);
|
||||||
initializeTypeParameters(method);
|
initializeTypeParameters(method);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -816,13 +907,30 @@ public class JavaDescriptorResolver {
|
|||||||
/**
|
/**
|
||||||
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor)
|
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor)
|
||||||
*/
|
*/
|
||||||
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, final FunctionDescriptor functionDescriptor) {
|
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method,
|
||||||
|
final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver)
|
||||||
|
{
|
||||||
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
||||||
|
|
||||||
|
class MyTypeVariableResolver implements TypeVariableResolver {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||||
|
for (TypeParameterDescriptor typeParameter : r) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return classTypeVariableResolver.getTypeVariable(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
|
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
||||||
|
|
||||||
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) {
|
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance, new MyTypeVariableResolver()) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
r.add(typeParameterDescriptor);
|
r.add(typeParameterDescriptor);
|
||||||
@@ -834,7 +942,7 @@ public class JavaDescriptorResolver {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JetType makeReturnType(PsiType returnType, PsiMethod method) {
|
private JetType makeReturnType(PsiType returnType, PsiMethod method, TypeVariableResolver typeVariableResolver) {
|
||||||
boolean changeNullable = false;
|
boolean changeNullable = false;
|
||||||
boolean nullable = true;
|
boolean nullable = true;
|
||||||
|
|
||||||
@@ -859,7 +967,7 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
JetType transformedType;
|
JetType transformedType;
|
||||||
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation.length() > 0) {
|
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation.length() > 0) {
|
||||||
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation);
|
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
|
||||||
} else {
|
} else {
|
||||||
transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
|
transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -59,9 +59,9 @@ public class JavaTypeTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType transformToType(@NotNull String kotlinSignature) {
|
public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) {
|
||||||
final JetType[] r = new JetType[1];
|
final JetType[] r = new JetType[1];
|
||||||
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary) {
|
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary, typeVariableResolver) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
r[0] = jetType;
|
r[0] = jetType;
|
||||||
|
|||||||
+8
-5
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
@@ -25,10 +26,12 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
|
|
||||||
private final JavaDescriptorResolver javaDescriptorResolver;
|
private final JavaDescriptorResolver javaDescriptorResolver;
|
||||||
private final JetStandardLibrary jetStandardLibrary;
|
private final JetStandardLibrary jetStandardLibrary;
|
||||||
|
private final TypeVariableResolver typeVariableResolver;
|
||||||
|
|
||||||
public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary) {
|
public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) {
|
||||||
this.javaDescriptorResolver = javaDescriptorResolver;
|
this.javaDescriptorResolver = javaDescriptorResolver;
|
||||||
this.jetStandardLibrary = jetStandardLibrary;
|
this.jetStandardLibrary = jetStandardLibrary;
|
||||||
|
this.typeVariableResolver = typeVariableResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
|
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
|
||||||
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
|
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
@@ -122,7 +125,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitArrayType(final boolean nullable) {
|
public JetSignatureVisitor visitArrayType(final boolean nullable) {
|
||||||
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
|
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
|
||||||
@Override
|
@Override
|
||||||
protected void done(@NotNull JetType jetType) {
|
protected void done(@NotNull JetType jetType) {
|
||||||
JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable);
|
JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable);
|
||||||
@@ -133,8 +136,8 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTypeVariable(String name, boolean nullable) {
|
public void visitTypeVariable(String name, boolean nullable) {
|
||||||
// TODO: need a way to get type TypeParameterDescriptor by name
|
JetType r = TypeUtils.makeNullableAsSpecified(typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable);
|
||||||
throw new IllegalStateException();
|
done(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public interface TypeVariableResolver {
|
||||||
|
@NotNull
|
||||||
|
TypeParameterDescriptor getTypeVariable(@NotNull String name);
|
||||||
|
}
|
||||||
@@ -280,7 +280,7 @@ public interface Errors {
|
|||||||
ParameterizedDiagnosticFactory1<JetType> UNSAFE_CALL = ParameterizedDiagnosticFactory1.create(ERROR, "Only safe calls (?.) are allowed on a nullable receiver of type {0}");
|
ParameterizedDiagnosticFactory1<JetType> UNSAFE_CALL = ParameterizedDiagnosticFactory1.create(ERROR, "Only safe calls (?.) are allowed on a nullable receiver of type {0}");
|
||||||
SimpleDiagnosticFactory AMBIGUOUS_LABEL = SimpleDiagnosticFactory.create(ERROR, "Ambiguous label");
|
SimpleDiagnosticFactory AMBIGUOUS_LABEL = SimpleDiagnosticFactory.create(ERROR, "Ambiguous label");
|
||||||
ParameterizedDiagnosticFactory1<String> UNSUPPORTED = ParameterizedDiagnosticFactory1.create(ERROR, "Unsupported [{0}]");
|
ParameterizedDiagnosticFactory1<String> UNSUPPORTED = ParameterizedDiagnosticFactory1.create(ERROR, "Unsupported [{0}]");
|
||||||
PsiElementOnlyDiagnosticFactory1<JetElement, JetType> UNNECESSARY_SAFE_CALL = PsiElementOnlyDiagnosticFactory1.create(WARNING, "Unnecessary safe call on a non-null receiver of type {0}");
|
ParameterizedDiagnosticFactory1<JetType> UNNECESSARY_SAFE_CALL = ParameterizedDiagnosticFactory1.create(WARNING, "Unnecessary safe call on a non-null receiver of type {0}");
|
||||||
ParameterizedDiagnosticFactory2<JetTypeConstraint, JetTypeParameterListOwner> NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER = new ParameterizedDiagnosticFactory2<JetTypeConstraint, JetTypeParameterListOwner>(ERROR, "{0} does not refer to a type parameter of {1}") {
|
ParameterizedDiagnosticFactory2<JetTypeConstraint, JetTypeParameterListOwner> NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER = new ParameterizedDiagnosticFactory2<JetTypeConstraint, JetTypeParameterListOwner>(ERROR, "{0} does not refer to a type parameter of {1}") {
|
||||||
@Override
|
@Override
|
||||||
protected String makeMessageForA(@NotNull JetTypeConstraint jetTypeConstraint) {
|
protected String makeMessageForA(@NotNull JetTypeConstraint jetTypeConstraint) {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassParamReferencesParam<A, B : A>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassParamReferencesParam<A, in B : A>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassTwoParams<P, Q>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassTwoParams<out P, Q>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassParamUsedInFun<in T> {
|
||||||
|
fun f(t: T) = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class ClassParamUsedInFun<T> {
|
||||||
|
fun f(t: T) = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <P> funParamParam(a: Int, b: P) = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <P, Q : P> funParamReferencesParam() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <in P, Q : P> funParamReferencesParam() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <P> funParamVarargParam(a: Int, vararg b: P) = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <P, Q> funTwoTypeParams() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun <P, in Q> funTwoTypeParams() = 1
|
||||||
@@ -403,7 +403,7 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
List<String> list = new ArrayList<String>();
|
List<String> list = new ArrayList<String>();
|
||||||
for (JetType upper : param.getUpperBounds()) {
|
for (JetType upper : param.getUpperBounds()) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
new Serializer(sb).serialize(upper);
|
new ValueParameterSerializer(sb).serialize(upper);
|
||||||
list.add(sb.toString());
|
list.add(sb.toString());
|
||||||
}
|
}
|
||||||
Collections.sort(list);
|
Collections.sort(list);
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ public class QuickFixes {
|
|||||||
|
|
||||||
add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory());
|
add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory());
|
||||||
|
|
||||||
add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallWithDotCall.createFactory());
|
|
||||||
|
|
||||||
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true);
|
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true);
|
||||||
add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory);
|
add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory);
|
||||||
@@ -109,7 +108,7 @@ public class QuickFixes {
|
|||||||
add(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory);
|
add(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory);
|
||||||
add(Errors.REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory);
|
add(Errors.REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory);
|
||||||
add(Errors.ILLEGAL_MODIFIER, removeModifierFactory);
|
add(Errors.ILLEGAL_MODIFIER, removeModifierFactory);
|
||||||
|
|
||||||
add(Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory());
|
add(Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory());
|
||||||
|
|
||||||
JetIntentionActionFactory<JetSimpleNameExpression> changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory();
|
JetIntentionActionFactory<JetSimpleNameExpression> changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory();
|
||||||
@@ -127,6 +126,7 @@ public class QuickFixes {
|
|||||||
actionMap.put(Errors.VAL_WITH_SETTER, changeVariableMutabilityFix);
|
actionMap.put(Errors.VAL_WITH_SETTER, changeVariableMutabilityFix);
|
||||||
actionMap.put(Errors.VAL_REASSIGNMENT, changeVariableMutabilityFix);
|
actionMap.put(Errors.VAL_REASSIGNMENT, changeVariableMutabilityFix);
|
||||||
|
|
||||||
actionMap.put(Errors.UNSAFE_CALL, new ReplaceDotCallWithSafeCall());
|
actionMap.put(Errors.UNNECESSARY_SAFE_CALL, new ReplaceCallFix(false));
|
||||||
|
actionMap.put(Errors.UNSAFE_CALL, new ReplaceCallFix(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.jetbrains.jet.plugin.quickfix;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiFile;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.plugin.JetBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author svtk
|
||||||
|
*/
|
||||||
|
public class ReplaceCallFix implements IntentionAction {
|
||||||
|
private final boolean toSafe;
|
||||||
|
|
||||||
|
public ReplaceCallFix(boolean toSafe) {
|
||||||
|
this.toSafe = toSafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return toSafe ? JetBundle.message("replace.with.safe.call") : JetBundle.message("replace.with.dot.call");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getFamilyName() {
|
||||||
|
return toSafe ? JetBundle.message("replace.with.safe.call") : JetBundle.message("replace.with.dot.call");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||||
|
if (file instanceof JetFile) {
|
||||||
|
return getCallExpression(editor, (JetFile) file) != null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JetQualifiedExpression getCallExpression(@NotNull Editor editor, @NotNull JetFile file) {
|
||||||
|
final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
|
||||||
|
return PsiTreeUtil.getParentOfType(elementAtCaret, toSafe ? JetDotQualifiedExpression.class : JetSafeQualifiedExpression.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||||
|
JetQualifiedExpression callExpression = getCallExpression(editor, (JetFile) file);
|
||||||
|
assert callExpression != null;
|
||||||
|
|
||||||
|
JetExpression selector = callExpression.getSelectorExpression();
|
||||||
|
if (selector != null) {
|
||||||
|
JetQualifiedExpression newElement = (JetQualifiedExpression) JetPsiFactory.createExpression(
|
||||||
|
project, callExpression.getReceiverExpression().getText() + (toSafe ? "?." : ".") + selector.getText());
|
||||||
|
|
||||||
|
callExpression.replace(newElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean startInWriteAction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package org.jetbrains.jet.plugin.quickfix;
|
|
||||||
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
|
||||||
import com.intellij.util.IncorrectOperationException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
|
||||||
import org.jetbrains.jet.plugin.JetBundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ignatov
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("IntentionDescriptionNotFoundInspection")
|
|
||||||
public class ReplaceDotCallWithSafeCall implements IntentionAction {
|
|
||||||
public ReplaceDotCallWithSafeCall() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return JetBundle.message("replace.with.safe.call");
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getFamilyName() {
|
|
||||||
return JetBundle.message("replace.with.safe.call");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
|
||||||
if (file instanceof JetFile) {
|
|
||||||
return getDotCallExpression(editor, (JetFile) file) != null;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JetDotQualifiedExpression getDotCallExpression(@NotNull Editor editor, @NotNull JetFile file) {
|
|
||||||
final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
|
|
||||||
return PsiTreeUtil.getParentOfType(elementAtCaret, JetDotQualifiedExpression.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
|
||||||
JetDotQualifiedExpression dotCallExpression = getDotCallExpression(editor, (JetFile) file);
|
|
||||||
assert dotCallExpression != null;
|
|
||||||
|
|
||||||
JetExpression selector = dotCallExpression.getSelectorExpression();
|
|
||||||
if (selector != null) {
|
|
||||||
JetSafeQualifiedExpression newElement = (JetSafeQualifiedExpression) JetPsiFactory.createExpression(
|
|
||||||
project, dotCallExpression.getReceiverExpression().getText() + "?." + selector.getText());
|
|
||||||
|
|
||||||
dotCallExpression.replace(newElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean startInWriteAction() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package org.jetbrains.jet.plugin.quickfix;
|
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
|
||||||
import com.intellij.util.IncorrectOperationException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
|
||||||
import org.jetbrains.jet.plugin.JetBundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author svtk
|
|
||||||
*/
|
|
||||||
public class ReplaceSafeCallWithDotCall extends JetIntentionAction<JetElement> {
|
|
||||||
|
|
||||||
public ReplaceSafeCallWithDotCall(@NotNull JetElement element) {
|
|
||||||
super(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return JetBundle.message("replace.with.dot.call");
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getFamilyName() {
|
|
||||||
return JetBundle.message("replace.with.dot.call");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
|
||||||
if (element instanceof JetSafeQualifiedExpression) {
|
|
||||||
JetSafeQualifiedExpression safeQualifiedExpression = (JetSafeQualifiedExpression) element;
|
|
||||||
JetDotQualifiedExpression newElement = (JetDotQualifiedExpression) JetPsiFactory.createExpression(project, "x.foo");
|
|
||||||
|
|
||||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getSelectorExpression().getNode(), safeQualifiedExpression.getSelectorExpression().getNode());
|
|
||||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getReceiverExpression().getNode(), safeQualifiedExpression.getReceiverExpression().getNode());
|
|
||||||
|
|
||||||
element.replace(newElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JetIntentionActionFactory<JetElement> createFactory() {
|
|
||||||
return new JetIntentionActionFactory<JetElement>() {
|
|
||||||
@Override
|
|
||||||
public JetIntentionAction<JetElement> createAction(DiagnosticWithPsiElement diagnostic) {
|
|
||||||
assert diagnostic.getPsiElement() instanceof JetElement;
|
|
||||||
return new ReplaceSafeCallWithDotCall((JetElement) diagnostic.getPsiElement());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with dot call" "true"
|
// "Replace with dot call" "true"
|
||||||
fun foo(a: Any) {
|
fun foo(a: Any) {
|
||||||
<caret>a.equals(0)
|
a<caret>.equals(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,4 +82,4 @@ fun <T> java.lang.Iterable<T>.contains(item : T) : Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ fun measureTimeNano(block: () -> Unit) : Long {
|
|||||||
val start = System.nanoTime()
|
val start = System.nanoTime()
|
||||||
block()
|
block()
|
||||||
return System.nanoTime() - start
|
return System.nanoTime() - start
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,11 @@ public class JetSignatureReader {
|
|||||||
if (end < 0) {
|
if (end < 0) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(signature.substring(pos, end), variance);
|
String typeParameterName = signature.substring(pos, end);
|
||||||
|
if (typeParameterName.isEmpty()) {
|
||||||
|
throw new IllegalStateException("incorrect signature: " + signature);
|
||||||
|
}
|
||||||
|
JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(typeParameterName, variance);
|
||||||
pos = end + 1;
|
pos = end + 1;
|
||||||
|
|
||||||
c = signature.charAt(pos);
|
c = signature.charAt(pos);
|
||||||
@@ -71,12 +75,14 @@ public class JetSignatureReader {
|
|||||||
pos = parseType(signature, pos, parameterVisitor.visitClassBound());
|
pos = parseType(signature, pos, parameterVisitor.visitClassBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((c = signature.charAt(pos++)) == ':') {
|
while ((c = signature.charAt(pos)) == ':') {
|
||||||
|
++pos;
|
||||||
pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound());
|
pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
parameterVisitor.visitFormalTypeParameterEnd();
|
parameterVisitor.visitFormalTypeParameterEnd();
|
||||||
} while (c != '>');
|
} while (c != '>');
|
||||||
|
++pos;
|
||||||
} else {
|
} else {
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user