Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-12-27 21:29:48 +04:00
51 changed files with 283 additions and 162 deletions
@@ -619,6 +619,11 @@ public class JetTypeMapper {
signatureVisitor.writeInterfaceBoundEnd();
}
}
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
signatureVisitor.writeInterfaceBound();
mapType(jetType, signatureVisitor);
signatureVisitor.writeInterfaceBoundEnd();
}
}
signatureVisitor.writeFormalTypeParameterEnd();
@@ -166,8 +166,17 @@ public class JavaDescriptorResolver {
);
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<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor);
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor, new OuterClassTypeVariableResolver());
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
@@ -225,7 +234,10 @@ public class JavaDescriptorResolver {
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
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) {
throw new IllegalStateException();
}
@@ -242,14 +254,14 @@ public class JavaDescriptorResolver {
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()) {
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
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 String name;
private final TypeInfoVariance variance;
private final TypeVariableResolver typeVariableResolver;
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.psiOwner = psiOwner;
this.name = name;
this.variance = variance;
this.typeVariableResolver = typeVariableResolver;
}
int index = 0;
@@ -307,7 +325,7 @@ public class JavaDescriptorResolver {
@Override
public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
if (isJavaLangObject(jetType)) {
@@ -320,7 +338,7 @@ public class JavaDescriptorResolver {
@Override
public JetSignatureVisitor visitInterfaceBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
upperBounds.add(jetType);
@@ -348,12 +366,28 @@ public class JavaDescriptorResolver {
/**
* @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>();
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() {
@Override
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
protected void done(TypeParameterDescriptor 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>();
JetType receiverType = null;
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
PsiParameter parameter = parameters[i];
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter);
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter, typeVariableResolver);
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
// TODO
} else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
@@ -601,7 +636,8 @@ public class JavaDescriptorResolver {
}
@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();
JetType varargElementType;
@@ -663,7 +699,7 @@ public class JavaDescriptorResolver {
JetType outType;
if (typeFromAnnotation != null && typeFromAnnotation.length() > 0) {
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation);
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
} else {
outType = semanticServices.getTypeTransformer().transformToType(psiType);
}
@@ -750,6 +786,26 @@ public class JavaDescriptorResolver {
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
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) {
PsiType returnType = method.getReturnType();
@@ -763,7 +819,17 @@ public class JavaDescriptorResolver {
}
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) {
return null;
}
@@ -774,14 +840,39 @@ public class JavaDescriptorResolver {
method.getName()
);
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(
valueParameterDescriptors.receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
typeParameters,
methodTypeParameters,
valueParameterDescriptors.descriptors,
makeReturnType(returnType, method),
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(method)
);
@@ -793,14 +884,14 @@ public class JavaDescriptorResolver {
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()) {
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl);
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl, classTypeVariableResolver);
initializeTypeParameters(method);
return r;
}
@@ -816,13 +907,30 @@ public class JavaDescriptorResolver {
/**
* @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>();
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() {
@Override
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
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
r.add(typeParameterDescriptor);
@@ -834,7 +942,7 @@ public class JavaDescriptorResolver {
return r;
}
private JetType makeReturnType(PsiType returnType, PsiMethod method) {
private JetType makeReturnType(PsiType returnType, PsiMethod method, TypeVariableResolver typeVariableResolver) {
boolean changeNullable = false;
boolean nullable = true;
@@ -859,7 +967,7 @@ public class JavaDescriptorResolver {
}
JetType transformedType;
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation.length() > 0) {
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation);
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
} else {
transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
}
@@ -59,9 +59,9 @@ public class JavaTypeTransformer {
}
@NotNull
public JetType transformToType(@NotNull String kotlinSignature) {
public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) {
final JetType[] r = new JetType[1];
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary) {
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
r[0] = jetType;
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
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.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardClasses;
@@ -25,10 +26,12 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
private final JavaDescriptorResolver javaDescriptorResolver;
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.jetStandardLibrary = jetStandardLibrary;
this.typeVariableResolver = typeVariableResolver;
}
@@ -111,7 +114,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
@@ -122,7 +125,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public JetSignatureVisitor visitArrayType(final boolean nullable) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable);
@@ -133,8 +136,8 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public void visitTypeVariable(String name, boolean nullable) {
// TODO: need a way to get type TypeParameterDescriptor by name
throw new IllegalStateException();
JetType r = TypeUtils.makeNullableAsSpecified(typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable);
done(r);
}
@Override
@@ -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}");
SimpleDiagnosticFactory AMBIGUOUS_LABEL = SimpleDiagnosticFactory.create(ERROR, "Ambiguous label");
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}") {
@Override
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>();
for (JetType upper : param.getUpperBounds()) {
StringBuilder sb = new StringBuilder();
new Serializer(sb).serialize(upper);
new ValueParameterSerializer(sb).serialize(upper);
list.add(sb.toString());
}
Collections.sort(list);
@@ -87,7 +87,6 @@ public class QuickFixes {
add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory());
add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallWithDotCall.createFactory());
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true);
add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory);
@@ -109,7 +108,7 @@ public class QuickFixes {
add(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory);
add(Errors.REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory);
add(Errors.ILLEGAL_MODIFIER, removeModifierFactory);
add(Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory());
JetIntentionActionFactory<JetSimpleNameExpression> changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory();
@@ -127,6 +126,7 @@ public class QuickFixes {
actionMap.put(Errors.VAL_WITH_SETTER, 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"
fun foo(a: Any) {
<caret>a.equals(0)
a<caret>.equals(0)
}
+1 -1
View File
@@ -82,4 +82,4 @@ fun <T> java.lang.Iterable<T>.contains(item : T) : Boolean {
}
return false
}
}
+1 -1
View File
@@ -16,4 +16,4 @@ fun measureTimeNano(block: () -> Unit) : Long {
val start = System.nanoTime()
block()
return System.nanoTime() - start
}
}
@@ -63,7 +63,11 @@ public class JetSignatureReader {
if (end < 0) {
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;
c = signature.charAt(pos);
@@ -71,12 +75,14 @@ public class JetSignatureReader {
pos = parseType(signature, pos, parameterVisitor.visitClassBound());
}
while ((c = signature.charAt(pos++)) == ':') {
while ((c = signature.charAt(pos)) == ':') {
++pos;
pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound());
}
parameterVisitor.visitFormalTypeParameterEnd();
} while (c != '>');
++pos;
} else {
pos = 0;
}