diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt index 3a4f307c5c4..fc7e945caa7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt @@ -110,7 +110,7 @@ abstract public class KtClassOrObject : val file = getContainingKtFile(); if (!isTopLevel() || file.getDeclarations().size() > 1) { - CodeEditUtil.removeChild(getParent().getNode(), getNode()); + super.delete() } else { file.delete(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImpl.java index 63242bf636e..c40da82e601 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImpl.java @@ -24,6 +24,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceService; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.KotlinLanguage; @@ -71,6 +72,12 @@ public class KtElementImpl extends ASTWrapperPsiElement implements KtElement { return visitor.visitKtElement(this, data); } + @Override + public void delete() throws IncorrectOperationException { + KtElementUtilsKt.deleteSemicolon(this); + super.delete(); + } + @Override public PsiReference getReference() { PsiReference[] references = getReferences(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImplStub.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImplStub.java index 97234ee2d3e..3733d683fb3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImplStub.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtElementImplStub.java @@ -23,6 +23,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.StubElement; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementType; @@ -85,6 +86,12 @@ public class KtElementImplStub> extends StubBasedPsiEle return visitor.visitKtElement(this, data); } + @Override + public void delete() throws IncorrectOperationException { + KtElementUtilsKt.deleteSemicolon(this); + super.delete(); + } + @Override public PsiReference getReference() { PsiReference[] references = getReferences(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/ktElementUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/ktElementUtils.kt new file mode 100644 index 00000000000..3dfe1b807ca --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/ktElementUtils.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.psi + +import com.intellij.psi.PsiComment +import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.lexer.KtTokens + +internal fun KtElement.deleteSemicolon() { + if (this is KtEnumEntry) return + + val sibling = PsiTreeUtil.skipSiblingsForward(this, PsiWhiteSpace::class.java, PsiComment::class.java) + if (sibling == null || sibling.node.elementType != KtTokens.SEMICOLON) return + + val lastSiblingToDelete = PsiTreeUtil.skipSiblingsForward(sibling, PsiWhiteSpace::class.java)?.prevSibling ?: sibling + parent?.deleteChildRange(nextSibling, lastSiblingToDelete) +} diff --git a/idea/testData/refactoring/inline/semicolon.kt b/idea/testData/refactoring/inline/semicolon.kt new file mode 100644 index 00000000000..d92ea76ee4e --- /dev/null +++ b/idea/testData/refactoring/inline/semicolon.kt @@ -0,0 +1,4 @@ +fun f() { + val x = 5; + println(x + x) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/semicolon.kt.after b/idea/testData/refactoring/inline/semicolon.kt.after new file mode 100644 index 00000000000..280d57f73eb --- /dev/null +++ b/idea/testData/refactoring/inline/semicolon.kt.after @@ -0,0 +1,3 @@ +fun f() { + println(5 + 5) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt b/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt new file mode 100644 index 00000000000..902d680c0b4 --- /dev/null +++ b/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt @@ -0,0 +1,4 @@ +fun f() { + val x = 5 /**/ ; + println(x + x) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt.after b/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt.after new file mode 100644 index 00000000000..280d57f73eb --- /dev/null +++ b/idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt.after @@ -0,0 +1,3 @@ +fun f() { + println(5 + 5) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java index b1a79139d1e..ffbf3d6c8c7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java @@ -95,6 +95,18 @@ public class InlineTestGenerated extends AbstractInlineTest { doTest(fileName); } + @TestMetadata("semicolon.kt") + public void testSemicolon() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/semicolon.kt"); + doTest(fileName); + } + + @TestMetadata("semicolonWithSpacesAndComments.kt") + public void testSemicolonWithSpacesAndComments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/semicolonWithSpacesAndComments.kt"); + doTest(fileName); + } + @TestMetadata("SeparateInitializer.kt") public void testSeparateInitializer() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/SeparateInitializer.kt");