Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-09-28 14:15:41 +04:00
39 changed files with 468 additions and 91 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.DeferredType;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
@@ -61,7 +62,7 @@ public class JetPluginUtil {
JetScope libraryScope = standardLibrary.getLibraryScope();
DeclarationDescriptor declaration = type.getMemberScope().getContainingDeclaration();
if (declaration instanceof JavaClassDescriptor) {
if (declaration instanceof JavaClassDescriptor || ErrorUtils.isError(declaration)) {
return false;
}
while (!(declaration instanceof NamespaceDescriptor)) {
@@ -0,0 +1,52 @@
package org.jetbrains.jet.plugin.quickfix;
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.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
/**
* @author svtk
*/
public class AddPrimaryConstructorFix extends JetIntentionAction<JetClass> {
public AddPrimaryConstructorFix(@NotNull JetClass element) {
super(element);
}
@NotNull
@Override
public String getText() {
return "Add primary constructor to " + element.getName();
}
@NotNull
@Override
public String getFamilyName() {
return "Add primary constructor";
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
JetClass newClass = (JetClass) element.copy();
assert !newClass.hasPrimaryConstructor();
PsiElement primaryConstructor = JetPsiFactory.createPrimaryConstructor(project);
newClass.addAfter(primaryConstructor, newClass.getNameIdentifier());
element.replace(newClass);
}
public static JetIntentionActionFactory<JetClass> createFactory() {
return new JetIntentionActionFactory<JetClass>() {
@Override
public JetIntentionAction<JetClass> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetClass;
return new AddPrimaryConstructorFix((JetClass) diagnostic.getPsiElement());
}
};
}
}
@@ -48,7 +48,6 @@ public class ChangeAccessorTypeFix extends JetIntentionAction<JetPropertyAccesso
JetTypeReference returnTypeReference = newElement.getReturnTypeReference();
assert returnTypeReference != null;
CodeEditUtil.replaceChild(newElement.getNode(), returnTypeReference.getNode(), newTypeReference.getNode());
element.replace(newElement);
}
else {
JetParameter parameter = newElement.getParameter();
@@ -56,8 +55,8 @@ public class ChangeAccessorTypeFix extends JetIntentionAction<JetPropertyAccesso
JetTypeReference typeReference = parameter.getTypeReference();
assert typeReference != null;
CodeEditUtil.replaceChild(parameter.getNode(), typeReference.getNode(), newTypeReference.getNode());
element.replace(newElement);
}
ImportClassHelper.perform(type, element, newElement);
}
public static JetIntentionActionFactory<JetPropertyAccessor> createFactory() {
@@ -3,6 +3,7 @@ package org.jetbrains.jet.plugin.quickfix;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetPluginUtil;
@@ -21,7 +22,7 @@ public class ImportClassHelper {
JetNamespace namespace = (JetNamespace) parent;
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
if (JetPluginUtil.checkTypeIsStandard(type, element.getProject())) {
if (JetPluginUtil.checkTypeIsStandard(type, element.getProject()) || ErrorUtils.isError(type.getMemberScope().getContainingDeclaration())) {
element.replace(newElement);
return;
}
@@ -12,14 +12,14 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElementImpl;
public class QuickFixUtil {
private QuickFixUtil() {}
public static <T extends PsiElement> JetIntentionActionFactory<T> createFactoryRedirectingAdditionalInfoToAnotherFactory(final JetIntentionActionFactory<T> factory, final DiagnosticParameter<T> parameter) {
return new JetIntentionActionFactory<T>() {
public static <T extends PsiElement, P extends T> JetIntentionActionFactory<PsiElement> createFactoryRedirectingAdditionalInfoToAnotherFactory(final JetIntentionActionFactory<T> factory, final DiagnosticParameter<P> parameter) {
return new JetIntentionActionFactory<PsiElement>() {
@Override
public JetIntentionAction<T> createAction(DiagnosticWithPsiElement diagnostic) {
public JetIntentionAction<PsiElement> createAction(DiagnosticWithPsiElement diagnostic) {
DiagnosticWithParameters<PsiElement> diagnosticWithParameters = JetIntentionAction.assertAndCastToDiagnosticWithParameters(diagnostic, parameter);
T element = diagnosticWithParameters.getParameter(parameter);
return factory.createAction(new DiagnosticWithPsiElementImpl<T>(diagnostic.getFactory(), diagnostic.getSeverity(), diagnostic.getMessage(), element));
return (JetIntentionAction<PsiElement>) factory.createAction(new DiagnosticWithPsiElementImpl<T>(diagnostic.getFactory(), diagnostic.getSeverity(), diagnostic.getMessage(), element));
}
};
}
@@ -6,10 +6,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.diagnostics.PsiElementOnlyDiagnosticFactory;
import org.jetbrains.jet.lang.psi.JetFunctionOrPropertyAccessor;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
@@ -53,7 +50,7 @@ public class QuickFixes {
add(Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT, addAbstractModifierFactory);
add(Errors.REDUNDANT_ABSTRACT, removeAbstractModifierFactory);
JetIntentionActionFactory<JetModifierListOwner> addAbstractToClassFactory = QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addAbstractModifierFactory, DiagnosticParameters.CLASS);
JetIntentionActionFactory<PsiElement> addAbstractToClassFactory = QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addAbstractModifierFactory, DiagnosticParameters.CLASS);
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory);
@@ -89,6 +86,12 @@ public class QuickFixes {
add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallToDotCall.createFactory());
add(Errors.REDUNDANT_MODIFIER, RemoveRedundantModifierFix.createFactory());
add(Errors.PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR, RemovePartsFromPropertyFix.createRemoveInitializerFactory());
JetIntentionActionFactory<JetClass> addPrimaryConstructorFactory = AddPrimaryConstructorFix.createFactory();
add(Errors.PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR, QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addPrimaryConstructorFactory, DiagnosticParameters.CLASS));
add(Errors.PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY, addPrimaryConstructorFactory);
}
}
@@ -2,15 +2,16 @@ package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.DeferredType;
import org.jetbrains.jet.lang.types.JetType;
/**
@@ -18,39 +19,46 @@ import org.jetbrains.jet.lang.types.JetType;
*/
public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty> {
private final JetType type;
private final String partsToRemove;
private final boolean removeInitializer;
private final boolean removeGetter;
private final boolean removeSetter;
private RemovePartsFromPropertyFix(@NotNull JetProperty element, JetType type) {
private RemovePartsFromPropertyFix(@NotNull JetProperty element, @Nullable JetType type, boolean removeInitializer, boolean removeGetter, boolean removeSetter) {
super(element);
if (type instanceof DeferredType) {
this.type = ((DeferredType) type).getActualType();
}
else {
this.type = type;
}
partsToRemove = partsToRemove(element.getGetter() != null && element.getGetter().getBodyExpression() != null,
element.getSetter() != null && element.getSetter().getBodyExpression() != null,
element.getInitializer() != null);
this.type = type;
this.removeInitializer = removeInitializer;
this.removeGetter = removeGetter;
this.removeSetter = removeSetter;
}
private RemovePartsFromPropertyFix(@NotNull JetProperty element, @Nullable JetType type) {
this(element, type, element.getInitializer() != null,
element.getGetter() != null && element.getGetter().getBodyExpression() != null,
element.getSetter() != null && element.getSetter().getBodyExpression() != null);
}
private static String partsToRemove(boolean hasGetter, boolean hasSetter, boolean hasInitializer) {
private RemovePartsFromPropertyFix(@NotNull JetProperty element, boolean removeInitializer, boolean removeGetter, boolean removeSetter) {
this(element, null, removeInitializer, removeGetter, removeSetter);
}
private static String partsToRemove(boolean getter, boolean setter, boolean initializer) {
StringBuilder sb = new StringBuilder();
if (hasGetter) {
if (getter) {
sb.append("getter");
if (hasSetter && hasInitializer) {
if (setter && initializer) {
sb.append(", ");
}
else if (hasSetter || hasInitializer) {
else if (setter || initializer) {
sb.append(" and ");
}
}
if (hasSetter) {
if (setter) {
sb.append("setter");
if (hasInitializer) {
if (initializer) {
sb.append(" and ");
}
}
if (hasInitializer) {
if (initializer) {
sb.append("initializer");
}
return sb.toString();
@@ -59,7 +67,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
@NotNull
@Override
public String getText() {
return "Remove " + partsToRemove + " from property";
return "Remove " + partsToRemove(removeGetter, removeSetter, removeInitializer) + " from property";
}
@NotNull
@@ -77,23 +85,23 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
JetProperty newElement = (JetProperty) element.copy();
JetPropertyAccessor getter = newElement.getGetter();
if (getter != null) {
if (removeGetter && getter != null) {
newElement.deleteChildInternal(getter.getNode());
}
JetPropertyAccessor setter = newElement.getSetter();
if (setter != null) {
if (removeSetter && setter != null) {
newElement.deleteChildInternal(setter.getNode());
}
JetExpression initializer = newElement.getInitializer();
boolean needImport = false;
if (initializer != null) {
if (removeInitializer && initializer != null) {
PsiElement nameIdentifier = newElement.getNameIdentifier();
assert nameIdentifier != null;
PsiElement nextSibling = nameIdentifier.getNextSibling();
assert nextSibling != null;
newElement.deleteChildRange(nextSibling, initializer);
if (newElement.getPropertyTypeRef() == null) {
if (newElement.getPropertyTypeRef() == null && type != null) {
newElement = addPropertyType(project, newElement, type);
needImport = true;
}
@@ -108,13 +116,11 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
public static JetProperty addPropertyType(Project project, JetProperty property, JetType type) {
JetProperty newProperty = (JetProperty) property.copy();
JetTypeReference typeReference = JetPsiFactory.createType(project, type.toString());
PsiElement[] colon = JetPsiFactory.createColon(project);
Pair<PsiElement, PsiElement> colon = JetPsiFactory.createColon(project);
PsiElement nameIdentifier = newProperty.getNameIdentifier();
assert nameIdentifier != null;
newProperty.addAfter(typeReference, nameIdentifier);
for (int i = colon.length - 1; i >= 0; i--) {
newProperty.addAfter(colon[i], nameIdentifier);
}
newProperty.addRangeAfter(colon.getFirst(), colon.getSecond(), nameIdentifier);
return newProperty;
}
@@ -129,4 +135,14 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
}
};
}
public static JetIntentionActionFactory<JetProperty> createRemoveInitializerFactory() {
return new JetIntentionActionFactory<JetProperty>() {
@Override
public JetIntentionAction<JetProperty> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetProperty;
return new RemovePartsFromPropertyFix((JetProperty) diagnostic.getPsiElement(), true, false, false);
}
};
}
}
@@ -36,7 +36,6 @@ public class ReplaceSafeCallToDotCall extends JetIntentionAction<JetElement> {
JetSafeQualifiedExpression safeQualifiedExpression = (JetSafeQualifiedExpression) element;
JetDotQualifiedExpression newElement = (JetDotQualifiedExpression) JetPsiFactory.createExpression(project, "x.foo");
//TODO check for null
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getSelectorExpression().getNode(), safeQualifiedExpression.getSelectorExpression().getNode());
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getReceiverExpression().getNode(), safeQualifiedExpression.getReceiverExpression().getNode());
@@ -0,0 +1,25 @@
namespace test
class List<T>() {
val a : Array<T> = Array<T>(1)
}
fun box() : String {
val a = List<String>()
a.a[0] = "1"
println(a.a[0])
val b = List<Int?>()
b.a[0] = 10
println(b.a[0])
val c = List<Array<Int>>()
c.a[0] = Array<Int>(4)
println(c.a[0].size)
return "OK"
}
fun println(s : Any?) {
System.out?.println(s);
}
@@ -0,0 +1,6 @@
// "Add primary constructor to A" "true"
namespace a
class A() {
var i : Int = <caret>1
}
@@ -0,0 +1,6 @@
// "Add primary constructor to A" "true"
namespace a
class A<caret>() {
var i : Int = 1
}
@@ -0,0 +1,6 @@
// "Add primary constructor to A" "true"
namespace a
class A {
var i : Int = <caret>1
}
@@ -0,0 +1,6 @@
// "Add primary constructor to A" "true"
namespace a
class A<caret> {
var i : Int = 1
}
@@ -0,0 +1,15 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
namespace b {
import java.util.List
class M {
trait A {
val l : <caret>List<Int>?
}
}
}
@@ -0,0 +1,8 @@
// "Remove initializer from property" "true"
namespace a
class M {
trait A {
abstract val e : <caret>Exception
}
}
@@ -0,0 +1,8 @@
// "Remove initializer from property" "true"
namespace a
class M {
trait A {
abstract val i : <caret>Int
}
}
@@ -0,0 +1,11 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
import java.util.List
class M {
trait A {
abstract val l : <caret>List<Int>?
}
}
@@ -0,0 +1,15 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
namespace b {
import java.util.List
class M {
trait A {
abstract val l : <caret>List<Int>?
}
}
}
@@ -0,0 +1,15 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
namespace b {
import java.util.List
class M {
trait A {
val l = <caret>Collections.emptyList<Int>()
}
}
}
@@ -0,0 +1,8 @@
// "Remove initializer from property" "true"
namespace a
class M {
trait A {
abstract val e = <caret>Exception("")
}
}
@@ -0,0 +1,8 @@
// "Remove initializer from property" "true"
namespace a
class M {
trait A {
abstract val i = <caret>10
}
}
@@ -0,0 +1,10 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
class M {
trait A {
abstract val l = <caret>Collections.emptyList<Int>()
}
}
@@ -0,0 +1,13 @@
// "Remove initializer from property" "true"
namespace a
import java.util.Collections
namespace b {
class M {
trait A {
abstract val l = <caret>Collections.emptyList<Int>()
}
}
}
@@ -0,0 +1,49 @@
package org.jetbrains.jet.codegen;
import java.lang.reflect.Method;
public class ArrayGenTest extends CodegenTestCase {
public void testKt238 () throws Exception {
blackBoxFile("regressions/kt238.jet");
}
public void testKt326 () throws Exception {
blackBoxFile("regressions/kt326.jet");
}
public void testCreateMultiInt () throws Exception {
loadText("fun foo() = Array<Array<Int>> (5)");
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof int[][]);
}
public void testCreateMultiString () throws Exception {
loadText("fun foo() = Array<Array<String>> (5)");
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof String[][]);
}
public void testCreateMultiGenerics () throws Exception {
/*
loadText("class L<T>() { val a = Array<T>(5) } fun foo() = L<Int>.a");
System.out.println(generateToText());
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof Integer[]);
*/
}
public void testIntGenerics () throws Exception {
loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a");
System.out.println(generateToText());
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
assertTrue(invoke instanceof Integer);
}
}
@@ -1,7 +0,0 @@
package org.jetbrains.jet.codegen;
public class ArrayGenTestCase extends CodegenTestCase {
public void testKt238 () throws Exception {
blackBoxFile("regressions/kt238.jet");
}
}
@@ -0,0 +1,24 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
import org.jetbrains.jet.JetTestCaseBase;
/**
* @author svtk
*/
public class AddPrimaryConstructorTest extends LightQuickFixTestCase {
public void test() throws Exception {
doAllTests();
}
@Override
protected String getBasePath() {
return "/quickfix/addPrimaryConstructor";
}
@Override
protected String getTestDataPath() {
return JetTestCaseBase.getTestDataPathBase();
}
}
@@ -0,0 +1,32 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
import com.intellij.openapi.projectRoots.Sdk;
import org.jetbrains.jet.JetTestCaseBase;
/**
* @author svtk
*/
public class ClassImportTests extends LightQuickFixTestCase {
public void test() throws Exception {
doAllTests();
}
@Override
protected String getBasePath() {
return "/quickfix/classImport";
}
@Override
protected String getTestDataPath() {
return JetTestCaseBase.getTestDataPathBase();
}
@Override
protected Sdk getProjectJDK() {
return JetTestCaseBase.jdkFromIdeaHome();
}
}