diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 6b45ea4ef74..c19c5a4968d 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPrope import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassLoadingTest import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassSanityTest import org.jetbrains.kotlin.checkers.* +import org.jetbrains.kotlin.copyright.AbstractUpdateKotlinCopyrightTest import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest import org.jetbrains.kotlin.findUsages.AbstractKotlinFindUsagesWithLibraryTest import org.jetbrains.kotlin.formatter.AbstractFormatterTest @@ -550,6 +551,10 @@ fun main(args: Array) { model("copyPaste/moveDeclarations", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doTest") } + testClass { + model("copyright", pattern = KT_OR_KTS, testMethod = "doTest") + } + testClass { model("exitPoints") } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.183 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.183 index 011f9851c8f..54d96ba5994 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.183 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.183 @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPrope import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassLoadingTest import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassSanityTest import org.jetbrains.kotlin.checkers.* +import org.jetbrains.kotlin.copyright.AbstractUpdateKotlinCopyrightTest import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest import org.jetbrains.kotlin.findUsages.AbstractKotlinFindUsagesWithLibraryTest import org.jetbrains.kotlin.formatter.AbstractFormatterTest @@ -561,6 +562,10 @@ fun main(args: Array) { model("copyPaste/moveDeclarations", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doTest") } + testClass { + model("copyright", pattern = KT_OR_KTS, testMethod = "doTest") + } + testClass { model("exitPoints") } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as33 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as33 index a80ca5c3f79..3e65b3e2fa3 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as33 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as33 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinBinariesCheckerTes import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinSourceCheckerTest import org.jetbrains.kotlin.checkers.AbstractJsCheckerTest import org.jetbrains.kotlin.checkers.AbstractPsiCheckerTest +import org.jetbrains.kotlin.copyright.AbstractUpdateKotlinCopyrightTest import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest import org.jetbrains.kotlin.findUsages.AbstractKotlinFindUsagesWithLibraryTest import org.jetbrains.kotlin.formatter.AbstractFormatterTest @@ -539,6 +540,10 @@ fun main(args: Array) { model("copyPaste/moveDeclarations", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doTest") } + testClass { + model("copyright", pattern = KT_OR_KTS, testMethod = "doTest") + } + testClass { model("exitPoints") } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as34 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as34 index 03b90785eaf..aa0027f08a9 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as34 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as34 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinBinariesCheckerTes import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinSourceCheckerTest import org.jetbrains.kotlin.checkers.AbstractJsCheckerTest import org.jetbrains.kotlin.checkers.AbstractPsiCheckerTest +import org.jetbrains.kotlin.copyright.AbstractUpdateKotlinCopyrightTest import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest import org.jetbrains.kotlin.findUsages.AbstractKotlinFindUsagesWithLibraryTest import org.jetbrains.kotlin.formatter.AbstractFormatterTest @@ -539,6 +540,10 @@ fun main(args: Array) { model("copyPaste/moveDeclarations", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doTest") } + testClass { + model("copyright", pattern = KT_OR_KTS, testMethod = "doTest") + } + testClass { model("exitPoints") } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 index a80ca5c3f79..3e65b3e2fa3 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinBinariesCheckerTes import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinSourceCheckerTest import org.jetbrains.kotlin.checkers.AbstractJsCheckerTest import org.jetbrains.kotlin.checkers.AbstractPsiCheckerTest +import org.jetbrains.kotlin.copyright.AbstractUpdateKotlinCopyrightTest import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest import org.jetbrains.kotlin.findUsages.AbstractKotlinFindUsagesWithLibraryTest import org.jetbrains.kotlin.formatter.AbstractFormatterTest @@ -539,6 +540,10 @@ fun main(args: Array) { model("copyPaste/moveDeclarations", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doTest") } + testClass { + model("copyright", pattern = KT_OR_KTS, testMethod = "doTest") + } + testClass { model("exitPoints") } diff --git a/idea/src/org/jetbrains/kotlin/idea/copyright/UpdateKotlinCopyright.java b/idea/src/org/jetbrains/kotlin/idea/copyright/UpdateKotlinCopyright.java index 7f01d53f4e2..d696021ad84 100644 --- a/idea/src/org/jetbrains/kotlin/idea/copyright/UpdateKotlinCopyright.java +++ b/idea/src/org/jetbrains/kotlin/idea/copyright/UpdateKotlinCopyright.java @@ -21,25 +21,46 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiWhiteSpace; import com.maddyhome.idea.copyright.CopyrightProfile; import com.maddyhome.idea.copyright.psi.UpdatePsiFileCopyright; -import org.jetbrains.kotlin.psi.KtImportList; - -class UpdateKotlinCopyright extends UpdatePsiFileCopyright { +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +public class UpdateKotlinCopyright extends UpdatePsiFileCopyright { UpdateKotlinCopyright(Project project, Module module, VirtualFile root, CopyrightProfile copyrightProfile) { super(project, module, root, copyrightProfile); } @Override protected void scanFile() { - PsiElement first = getFile().getFirstChild(); + PsiRange commentSearchRange = getCommentSearchRange(getFile()); + PsiElement first = commentSearchRange.first; + PsiElement last = commentSearchRange.last; + + if (first != null) { + checkComments(first, last, true); + } + } + + public static class PsiRange { + public final @Nullable PsiElement first; + public final @Nullable PsiElement last; + + public PsiRange(@Nullable PsiElement first, @Nullable PsiElement second) { + this.first = first; + this.last = second; + } + } + + public static @NotNull PsiRange getCommentSearchRange(@NotNull PsiFile psiFile) { + PsiElement first = psiFile.getFirstChild(); PsiElement last = first; PsiElement next = first; while (next != null) { if (next instanceof PsiComment || next instanceof PsiWhiteSpace || next.getText().isEmpty()) { - next = getNextSibling(next); + next = next.getNextSibling(); } else { break; @@ -47,8 +68,6 @@ class UpdateKotlinCopyright extends UpdatePsiFileCopyright { last = next; } - if (first != null) { - checkComments(first, last, true); - } + return new PsiRange(first, last); } } diff --git a/idea/testData/copyright/ClassDocComment.kt b/idea/testData/copyright/ClassDocComment.kt new file mode 100644 index 00000000000..b76027c7e4e --- /dev/null +++ b/idea/testData/copyright/ClassDocComment.kt @@ -0,0 +1,4 @@ +/* ABSENT */ +class Some + +// COMMENTS: 0 \ No newline at end of file diff --git a/idea/testData/copyright/Empty.kt b/idea/testData/copyright/Empty.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/copyright/NoPackage.kt b/idea/testData/copyright/NoPackage.kt new file mode 100644 index 00000000000..5fe1c863189 --- /dev/null +++ b/idea/testData/copyright/NoPackage.kt @@ -0,0 +1,5 @@ +/* PRESENT */ + +fun some() {} + +// COMMENTS: 1 \ No newline at end of file diff --git a/idea/testData/copyright/Simple.kt b/idea/testData/copyright/Simple.kt new file mode 100644 index 00000000000..49d05a9c504 --- /dev/null +++ b/idea/testData/copyright/Simple.kt @@ -0,0 +1,5 @@ +/* PRESENT */ + +package normal + +// COMMENTS: 1 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt b/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt new file mode 100644 index 00000000000..ac6a31105b8 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.copyright + +import com.intellij.psi.PsiComment +import com.intellij.psi.PsiElement +import junit.framework.AssertionFailedError +import org.jetbrains.kotlin.idea.copyright.UpdateKotlinCopyright +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.junit.Assert +import java.io.File + +abstract class AbstractUpdateKotlinCopyrightTest : KotlinLightCodeInsightFixtureTestCase() { + fun doTest(path: String) { + myFixture.configureByFile(path) + + val text = myFixture.file.text.trim() + val expectedNumberOfComments = InTextDirectivesUtils.getPrefixedInt(text, "// COMMENTS: ") ?: run { + if (!text.isEmpty()) { + throw AssertionFailedError("Every test should assert number of comments with `COMMENTS` directive") + } else { + 0 + } + } + + var commentsNumber = 0 + val comments = collectComments(UpdateKotlinCopyright.getCommentSearchRange(myFixture.file)) + for (comment in comments) { + when (comment.text) { + "/* PRESENT */" -> { + ++commentsNumber + } + "/* ABSENT */" -> { + throw AssertionFailedError("Unexpected comment found") + } + else -> { + throw AssertionFailedError("A comment with bad directive found: `$text`") + } + } + } + + Assert.assertEquals("Wrong number of comments found", expectedNumberOfComments, commentsNumber) + } + + override fun getTestDataPath() = File(PluginTestCaseBase.getTestDataPathBase(), "/copyright").path + File.separator + + companion object { + private fun collectComments(range: UpdateKotlinCopyright.PsiRange): List { + val comments = mutableListOf() + val first = range.first + val last = range.last + if (first == null) return listOf() + collectComments(first, last, comments) + return comments + } + + // Copied from UpdatePsiFileCopyright.collectComments() + private fun collectComments(first: PsiElement, last: PsiElement?, comments: MutableList) { + if (first === last && first is PsiComment) { + comments.add(first) + return + } + var elem: PsiElement? = first + while (elem !== last && elem != null) { + if (elem is PsiComment) { + comments.add(elem) + } + + elem = elem.nextSibling + } + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/copyright/UpdateKotlinCopyrightTestGenerated.java b/idea/tests/org/jetbrains/kotlin/copyright/UpdateKotlinCopyrightTestGenerated.java new file mode 100644 index 00000000000..bdee23512da --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/copyright/UpdateKotlinCopyrightTestGenerated.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.copyright; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/copyright") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class UpdateKotlinCopyrightTestGenerated extends AbstractUpdateKotlinCopyrightTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInCopyright() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/copyright"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true); + } + + @TestMetadata("ClassDocComment.kt") + public void testClassDocComment() throws Exception { + runTest("idea/testData/copyright/ClassDocComment.kt"); + } + + @TestMetadata("Empty.kt") + public void testEmpty() throws Exception { + runTest("idea/testData/copyright/Empty.kt"); + } + + @TestMetadata("NoPackage.kt") + public void testNoPackage() throws Exception { + runTest("idea/testData/copyright/NoPackage.kt"); + } + + @TestMetadata("Simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/copyright/Simple.kt"); + } +}