IFT-291 Bundle Features Suggester to Java, Kotlin, Python and JavaScript

IJ-CR-14522

GitOrigin-RevId: 6512d5f061c8004fb3e4f7f3f1f404193f30e1f5
This commit is contained in:
Konstantin Hudyakov
2021-10-19 17:09:17 +03:00
committed by intellij-monorepo-bot
parent 59a6de678d
commit 2986a16262
46 changed files with 120 additions and 785 deletions

View File

@@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
@@ -18,5 +19,6 @@
<orderEntry type="module" module-name="intellij.platform.debugger" /> <orderEntry type="module" module-name="intellij.platform.debugger" />
<orderEntry type="module" module-name="intellij.platform.core.ui" /> <orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.java.debugger.impl" /> <orderEntry type="module" module-name="intellij.java.debugger.impl" />
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
</component> </component>
</module> </module>

View File

@@ -2,5 +2,6 @@
<extensions defaultExtensionNs="training"> <extensions defaultExtensionNs="training">
<ift.language.extension language="JAVA" implementationClass="com.intellij.java.ift.JavaLangSupport"/> <ift.language.extension language="JAVA" implementationClass="com.intellij.java.ift.JavaLangSupport"/>
<ift.learning.course language="JAVA" implementationClass="com.intellij.java.ift.JavaLearningCourse"/> <ift.learning.course language="JAVA" implementationClass="com.intellij.java.ift.JavaLearningCourse"/>
<ifs.languageSupport language="JAVA" implementationClass="com.intellij.java.ifs.JavaLanguageSupport"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>

View File

@@ -1,23 +1,10 @@
package training.featuresSuggester.suggesters.lang // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.ifs
import com.intellij.psi.PsiClass import com.intellij.psi.*
import com.intellij.psi.PsiCodeBlock
import com.intellij.psi.PsiDeclarationStatement
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiExpressionStatement
import com.intellij.psi.PsiField
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiForStatement
import com.intellij.psi.PsiIdentifier
import com.intellij.psi.PsiIfStatement
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiLocalVariable
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiStatement
import com.intellij.psi.PsiWhileStatement
import com.intellij.psi.impl.source.PsiJavaFileImpl import com.intellij.psi.impl.source.PsiJavaFileImpl
import com.intellij.psi.util.descendantsOfType import com.intellij.psi.util.descendantsOfType
import training.featuresSuggester.LanguageSupport
import training.featuresSuggester.getParentByPredicate import training.featuresSuggester.getParentByPredicate
import training.featuresSuggester.getParentOfType import training.featuresSuggester.getParentOfType

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.completionPopup package com.intellij.java.ifs
import training.featuresSuggester.FeatureSuggesterTest import training.featuresSuggester.FeatureSuggesterTest
import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem
@@ -13,6 +13,10 @@ class CompletionPopupSuggesterTest : FeatureSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override val testingSuggesterId = "Completion" override val testingSuggesterId = "Completion"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
fun `testDelete and type dot, complete method call and get suggestion`() { fun `testDelete and type dot, complete method call and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(12, 20) moveCaretToLogicalPosition(12, 20)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.copyPaste package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTest import training.featuresSuggester.FeatureSuggesterTest
@@ -11,6 +11,10 @@ class CopyPasteSuggesterTest : FeatureSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override val testingSuggesterId = "Paste from history" override val testingSuggesterId = "Paste from history"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
fun `testCopy text that contained in clipboard at first index and get suggestion`() { fun `testCopy text that contained in clipboard at first index and get suggestion`() {
with(myFixture) { with(myFixture) {
copyBetweenLogicalPositions(lineStartIndex = 5, columnStartIndex = 8, lineEndIndex = 5, columnEndIndex = 19) copyBetweenLogicalPositions(lineStartIndex = 5, columnStartIndex = 8, lineEndIndex = 5, columnEndIndex = 19)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.fileStructure package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor
@@ -12,6 +12,10 @@ import training.featuresSuggester.NoSuggestion
class FileStructureSuggesterJavaTest : FileStructureSuggesterTest() { class FileStructureSuggesterJavaTest : FileStructureSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
override fun `testFind field and get suggestion`() { override fun `testFind field and get suggestion`() {
with(myFixture) { with(myFixture) {
val fromOffset = logicalPositionToOffset(1, 0) val fromOffset = logicalPositionToOffset(1, 0)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.introduceVariable package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection
@@ -20,6 +20,10 @@ import training.featuresSuggester.NoSuggestion
class IntroduceVariableSuggesterJavaTest : IntroduceVariableSuggesterTest() { class IntroduceVariableSuggesterJavaTest : IntroduceVariableSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
override fun `testIntroduce expression from IF and get suggestion`() { override fun `testIntroduce expression from IF and get suggestion`() {
with(myFixture) { with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 9, columnStartIndex = 23, lineEndIndex = 9, columnEndIndex = 38) cutBetweenLogicalPositions(lineStartIndex = 9, columnStartIndex = 23, lineEndIndex = 9, columnEndIndex = 38)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.lineCommenting package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTest import training.featuresSuggester.FeatureSuggesterTest
@@ -13,6 +13,10 @@ class LineCommentingSuggesterJavaTest : FeatureSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override val testingSuggesterId = "Comment with line comment" override val testingSuggesterId = "Comment with line comment"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
fun `testComment 3 lines in a row and get suggestion`() { fun `testComment 3 lines in a row and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(6, 8) moveCaretToLogicalPosition(6, 8)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.replaceCompletion package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem
@@ -15,6 +15,10 @@ import training.featuresSuggester.ReplaceCompletionSuggesterTest
class ReplaceCompletionSuggesterJavaTest : ReplaceCompletionSuggesterTest() { class ReplaceCompletionSuggesterJavaTest : ReplaceCompletionSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() { override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(12, 20) moveCaretToLogicalPosition(12, 20)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.surroundWith package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt
@@ -13,6 +13,10 @@ import training.featuresSuggester.SurroundWithSuggesterTest
class SurroundWithSuggesterJavaTest : SurroundWithSuggesterTest() { class SurroundWithSuggesterJavaTest : SurroundWithSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
override fun `testSurround one statement with IF and get suggestion`() { override fun `testSurround one statement with IF and get suggestion`() {
with(myFixture) { with(myFixture) {
insertNewLineAt(6) insertNewLineAt(6)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.unwrap package com.intellij.java.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret
@@ -14,6 +14,10 @@ import training.featuresSuggester.UnwrapSuggesterTest
class UnwrapSuggesterJavaTest : UnwrapSuggesterTest() { class UnwrapSuggesterJavaTest : UnwrapSuggesterTest() {
override val testingCodeFileName = "JavaCodeExample.java" override val testingCodeFileName = "JavaCodeExample.java"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/java/java-features-trainer/testData"
}
override fun `testUnwrap IF statement and get suggestion`() { override fun `testUnwrap IF statement and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(11, 9) moveCaretToLogicalPosition(11, 9)

View File

@@ -143,7 +143,7 @@
<extensionPoint name="ifs.languageSupport" <extensionPoint name="ifs.languageSupport"
beanClass="com.intellij.lang.LanguageExtensionPoint" beanClass="com.intellij.lang.LanguageExtensionPoint"
dynamic="true"> dynamic="true">
<with attribute="implementationClass" implements="training.featuresSuggester.suggesters.lang.LanguageSupport"/> <with attribute="implementationClass" implements="training.featuresSuggester.LanguageSupport"/>
</extensionPoint> </extensionPoint>
</extensionPoints> </extensionPoints>

View File

@@ -1,4 +1,5 @@
package training.featuresSuggester.suggesters.lang // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester
import com.intellij.lang.Language import com.intellij.lang.Language
import com.intellij.lang.LanguageExtensionPoint import com.intellij.lang.LanguageExtensionPoint

View File

@@ -46,11 +46,11 @@ internal fun handleAction(project: Project, action: Action) {
} }
} }
internal inline fun <reified T : PsiElement> PsiElement.getParentOfType(): T? { inline fun <reified T : PsiElement> PsiElement.getParentOfType(): T? {
return PsiTreeUtil.getParentOfType(this, T::class.java) return PsiTreeUtil.getParentOfType(this, T::class.java)
} }
internal fun PsiElement.getParentByPredicate(predicate: (PsiElement) -> Boolean): PsiElement? { fun PsiElement.getParentByPredicate(predicate: (PsiElement) -> Boolean): PsiElement? {
return parents(true).find(predicate) return parents(true).find(predicate)
} }

View File

@@ -4,9 +4,9 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiTreeChangeAdapter import com.intellij.psi.PsiTreeChangeAdapter
import com.intellij.psi.PsiTreeChangeEvent import com.intellij.psi.PsiTreeChangeEvent
import training.featuresSuggester.LanguageSupport
import training.featuresSuggester.actions.* import training.featuresSuggester.actions.*
import training.featuresSuggester.handleAction import training.featuresSuggester.handleAction
import training.featuresSuggester.suggesters.lang.LanguageSupport
class PsiActionsListener(private val project: Project) : PsiTreeChangeAdapter() { class PsiActionsListener(private val project: Project) : PsiTreeChangeAdapter() {
override fun beforePropertyChange(event: PsiTreeChangeEvent) { override fun beforePropertyChange(event: PsiTreeChangeEvent) {
@@ -89,14 +89,7 @@ class PsiActionsListener(private val project: Project) : PsiTreeChangeAdapter()
override fun propertyChanged(event: PsiTreeChangeEvent) { override fun propertyChanged(event: PsiTreeChangeEvent) {
if (event.parent == null || !isSourceFile(event.file)) return if (event.parent == null || !isSourceFile(event.file)) return
handleAction( handleAction(project, PropertyChangedAction(psiFile = event.file!!, parent = event.parent, timeMillis = System.currentTimeMillis()))
project,
PropertyChangedAction(
psiFile = event.file!!,
parent = event.parent,
timeMillis = System.currentTimeMillis()
)
)
} }
override fun childRemoved(event: PsiTreeChangeEvent) { override fun childRemoved(event: PsiTreeChangeEvent) {
@@ -141,14 +134,7 @@ class PsiActionsListener(private val project: Project) : PsiTreeChangeAdapter()
override fun childrenChanged(event: PsiTreeChangeEvent) { override fun childrenChanged(event: PsiTreeChangeEvent) {
if (event.parent == null || !isSourceFile(event.file)) return if (event.parent == null || !isSourceFile(event.file)) return
handleAction( handleAction(project, ChildrenChangedAction(psiFile = event.file!!, parent = event.parent, timeMillis = System.currentTimeMillis()))
project,
ChildrenChangedAction(
psiFile = event.file!!,
parent = event.parent,
timeMillis = System.currentTimeMillis()
)
)
} }
override fun childMoved(event: PsiTreeChangeEvent) { override fun childMoved(event: PsiTreeChangeEvent) {

View File

@@ -4,7 +4,6 @@ import com.intellij.psi.PsiComment
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import training.featuresSuggester.* import training.featuresSuggester.*
import training.featuresSuggester.actions.* import training.featuresSuggester.actions.*
import training.featuresSuggester.suggesters.lang.LanguageSupport
class CompletionPopupSuggester : AbstractFeatureSuggester() { class CompletionPopupSuggester : AbstractFeatureSuggester() {
override val id = "Completion" override val id = "Completion"

View File

@@ -7,12 +7,12 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiNamedElement import com.intellij.psi.PsiNamedElement
import training.featuresSuggester.FeatureSuggesterBundle import training.featuresSuggester.FeatureSuggesterBundle
import training.featuresSuggester.LanguageSupport
import training.featuresSuggester.NoSuggestion import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.Suggestion import training.featuresSuggester.Suggestion
import training.featuresSuggester.actions.Action import training.featuresSuggester.actions.Action
import training.featuresSuggester.actions.EditorFindAction import training.featuresSuggester.actions.EditorFindAction
import training.featuresSuggester.actions.EditorFocusGainedAction import training.featuresSuggester.actions.EditorFocusGainedAction
import training.featuresSuggester.suggesters.lang.LanguageSupport
class FileStructureSuggester : AbstractFeatureSuggester() { class FileStructureSuggester : AbstractFeatureSuggester() {
override val id: String = "File structure" override val id: String = "File structure"

View File

@@ -2,12 +2,8 @@ package training.featuresSuggester.suggesters
import com.intellij.openapi.ide.CopyPasteManager import com.intellij.openapi.ide.CopyPasteManager
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import training.featuresSuggester.FeatureSuggesterBundle import training.featuresSuggester.*
import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.Suggestion
import training.featuresSuggester.actions.* import training.featuresSuggester.actions.*
import training.featuresSuggester.asString
import training.featuresSuggester.suggesters.lang.LanguageSupport
import training.util.WeakReferenceDelegator import training.util.WeakReferenceDelegator
import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.DataFlavor

View File

@@ -5,7 +5,6 @@ import com.intellij.psi.PsiComment
import com.intellij.refactoring.suggested.startOffset import com.intellij.refactoring.suggested.startOffset
import training.featuresSuggester.* import training.featuresSuggester.*
import training.featuresSuggester.actions.* import training.featuresSuggester.actions.*
import training.featuresSuggester.suggesters.lang.LanguageSupport
class ReplaceCompletionSuggester : AbstractFeatureSuggester() { class ReplaceCompletionSuggester : AbstractFeatureSuggester() {
override val id: String = "Completion with replace" override val id: String = "Completion with replace"

View File

@@ -4,10 +4,10 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.refactoring.suggested.startOffset import com.intellij.refactoring.suggested.startOffset
import training.featuresSuggester.FeatureSuggesterBundle import training.featuresSuggester.FeatureSuggesterBundle
import training.featuresSuggester.LanguageSupport
import training.featuresSuggester.NoSuggestion import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.Suggestion import training.featuresSuggester.Suggestion
import training.featuresSuggester.actions.* import training.featuresSuggester.actions.*
import training.featuresSuggester.suggesters.lang.LanguageSupport
import training.util.WeakReferenceDelegator import training.util.WeakReferenceDelegator
class SurroundWithSuggester : AbstractFeatureSuggester() { class SurroundWithSuggester : AbstractFeatureSuggester() {

View File

@@ -3,13 +3,9 @@ package training.featuresSuggester.suggesters
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.refactoring.suggested.endOffset import com.intellij.refactoring.suggested.endOffset
import com.intellij.refactoring.suggested.startOffset import com.intellij.refactoring.suggested.startOffset
import training.featuresSuggester.FeatureSuggesterBundle import training.featuresSuggester.*
import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.Suggestion
import training.featuresSuggester.TextFragment
import training.featuresSuggester.actions.Action import training.featuresSuggester.actions.Action
import training.featuresSuggester.actions.BeforeEditorTextRemovedAction import training.featuresSuggester.actions.BeforeEditorTextRemovedAction
import training.featuresSuggester.suggesters.lang.LanguageSupport
class UnwrapSuggester : AbstractFeatureSuggester() { class UnwrapSuggester : AbstractFeatureSuggester() {
override val id: String = "Unwrap" override val id: String = "Unwrap"

View File

@@ -1,108 +0,0 @@
package training.featuresSuggester.suggesters.lang
import com.intellij.lang.ecmascript6.psi.ES6Class
import com.intellij.lang.javascript.psi.JSBlockStatement
import com.intellij.lang.javascript.psi.JSExpression
import com.intellij.lang.javascript.psi.JSExpressionStatement
import com.intellij.lang.javascript.psi.JSForStatement
import com.intellij.lang.javascript.psi.JSFunction
import com.intellij.lang.javascript.psi.JSIfStatement
import com.intellij.lang.javascript.psi.JSLiteralExpression
import com.intellij.lang.javascript.psi.JSStatement
import com.intellij.lang.javascript.psi.JSVarStatement
import com.intellij.lang.javascript.psi.JSVariable
import com.intellij.lang.javascript.psi.JSWhileStatement
import com.intellij.lang.javascript.psi.impl.JSFileImpl
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.descendantsOfType
import training.featuresSuggester.getParentByPredicate
import training.featuresSuggester.getParentOfType
class JavaScriptLanguageSupport : LanguageSupport {
override fun isSourceFile(file: PsiFile): Boolean {
return file is JSFileImpl
}
override fun isIfStatement(element: PsiElement): Boolean {
return element is JSIfStatement
}
override fun isForStatement(element: PsiElement): Boolean {
return element is JSForStatement
}
override fun isWhileStatement(element: PsiElement): Boolean {
return element is JSWhileStatement
}
override fun isCodeBlock(element: PsiElement): Boolean {
return element is JSBlockStatement
}
override fun getCodeBlock(element: PsiElement): PsiElement? {
return element.descendantsOfType<JSBlockStatement>().firstOrNull()
}
override fun getContainingCodeBlock(element: PsiElement): PsiElement? {
return element.getParentOfType<JSBlockStatement>()
}
override fun getParentStatementOfBlock(element: PsiElement): PsiElement? {
return element.parent
}
override fun getStatements(element: PsiElement): List<PsiElement> {
return if (element is JSBlockStatement) {
element.statementListItems.toList()
}
else {
emptyList()
}
}
override fun getTopmostStatementWithText(psiElement: PsiElement, text: String): PsiElement? {
return psiElement.getParentByPredicate {
isSupportedStatementToIntroduceVariable(it) && it.text.contains(text) && it.text != text
}
}
override fun isSupportedStatementToIntroduceVariable(element: PsiElement): Boolean {
return element is JSStatement
}
override fun isPartOfExpression(element: PsiElement): Boolean {
return element.getParentOfType<JSExpression>() != null
}
override fun isExpressionStatement(element: PsiElement): Boolean {
return element is JSExpressionStatement
}
override fun isVariableDeclaration(element: PsiElement): Boolean {
return element is JSVarStatement
}
override fun getVariableName(element: PsiElement): String? {
return if (element is JSVarStatement) {
element.declarations.firstOrNull()?.name
}
else {
null
}
}
override fun isFileStructureElement(element: PsiElement): Boolean {
return (element is JSVariable && element.getParentOfType<JSFunction>() == null) ||
element is JSFunction || element is ES6Class
}
override fun isIdentifier(element: PsiElement): Boolean {
return element is LeafPsiElement && element.elementType.toString() == "JS:IDENTIFIER"
}
override fun isLiteralExpression(element: PsiElement): Boolean {
return element is JSLiteralExpression
}
}

View File

@@ -1,76 +0,0 @@
globalVar = 12342
globalString = "123123" + "eee" + '11'
function globalFunction(arg1, arg2) {
console.log(arg1 + arg2 - arg1 * arg1)
}
class JavaScriptCodeExample {
static field = 322
abc = 3
constructor(abc) {
this.abc = abc;
}
main(args) {
let anotherClass = new AnotherClass()
var abc = 3
const bcd = 5 * abc + JavaScriptCodeExample.field
this.func(abc)
if(abc < bcd && globalFunction(0, abc)) {
console.log(abc * bcd - JavaScriptCodeExample.field)
}
let exampleClass = new JavaScriptCodeExample(322)
exampleClass.main(null)
}
func(arg) {
return arg
}
}
class AnotherClass {
field = 322
main(args) {
this.funct(this.funct(this.field * this.field))
console.log(this.field * this.field)
}
funct(arg) {
return arg && this.field == 0
}
cyclesFunction(ere) {
let i = 10
for(let j = 0; j < i; j++) {
var res = j - j + j
console.log(res - j)
}
i += 10
while(i > 0) {
console.log(i * i)
i--
}
if(true) { i++ }
return i
}
stringFunction(sss) {
let str = '2' + "123" + "rrr"
str += '11111' + '323' + 2
return str.toString() + "1231" + str + '11'
}
selfReturningFunction(arg) {
return this
}
functionForReplaceCompletion() {
let instance = new AnotherClass()
let ss = instance.selfReturningFunction(322).selfReturningFunction(instance.cyclesFunction(0))
.selfReturningFunction(1).field
}
}

View File

@@ -19,10 +19,6 @@ abstract class FeatureSuggesterTest : BasePlatformTestCase() {
FeatureSuggesterTestUtils.subscribeToSuggestions(myFixture.project) { suggestion -> expectedSuggestion = suggestion } FeatureSuggesterTestUtils.subscribeToSuggestions(myFixture.project) { suggestion -> expectedSuggestion = suggestion }
} }
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/ide-features-trainer/testData"
}
fun assertSuggestedCorrectly() { fun assertSuggestedCorrectly() {
TestCase.assertTrue(expectedSuggestion is PopupSuggestion) TestCase.assertTrue(expectedSuggestion is PopupSuggestion)
TestCase.assertEquals(testingSuggesterId, (expectedSuggestion as PopupSuggestion).suggesterId) TestCase.assertEquals(testingSuggesterId, (expectedSuggestion as PopupSuggestion).suggesterId)

View File

@@ -1,98 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.fileStructure
import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor
import training.featuresSuggester.FeatureSuggesterTestUtils.logicalPositionToOffset
import training.featuresSuggester.FeatureSuggesterTestUtils.performFindInFileAction
import training.featuresSuggester.FeatureSuggesterTestUtils.testInvokeLater
import training.featuresSuggester.FileStructureSuggesterTest
import training.featuresSuggester.NoSuggestion
class FileStructureSuggesterJSTest : FileStructureSuggesterTest() {
override val testingCodeFileName = "JavaScriptCodeExample.js"
override fun `testFind field and get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(8, 0)
performFindInFileAction("field", fromOffset)
focusEditor()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testFind method and get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(4, 0)
performFindInFileAction("mai", fromOffset)
focusEditor()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testFind function parameter and don't get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(14, 0)
performFindInFileAction("args", fromOffset)
focusEditor()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
override fun `testFind local variable declaration and don't get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(14, 0)
performFindInFileAction("abc", fromOffset)
focusEditor()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
override fun `testFind variable usage and don't get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(18, 0)
performFindInFileAction("abc", fromOffset)
focusEditor()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
override fun `testFind method usage and don't get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(18, 0)
performFindInFileAction("main", fromOffset)
focusEditor()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
override fun `testFind type usage and don't get suggestion`() {
with(myFixture) {
val fromOffset = logicalPositionToOffset(16, 25)
performFindInFileAction("anotherCl", fromOffset)
focusEditor()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
}

View File

@@ -1,140 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.introduceVariable
import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection
import training.featuresSuggester.FeatureSuggesterTestUtils.cutBetweenLogicalPositions
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret
import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt
import training.featuresSuggester.FeatureSuggesterTestUtils.moveCaretToLogicalPosition
import training.featuresSuggester.FeatureSuggesterTestUtils.pasteFromClipboard
import training.featuresSuggester.FeatureSuggesterTestUtils.selectBetweenLogicalPositions
import training.featuresSuggester.FeatureSuggesterTestUtils.testInvokeLater
import training.featuresSuggester.FeatureSuggesterTestUtils.typeAndCommit
import training.featuresSuggester.IntroduceVariableSuggesterTest
import training.featuresSuggester.NoSuggestion
class IntroduceVariableSuggesterJSTest : IntroduceVariableSuggesterTest() {
override val testingCodeFileName = "JavaScriptCodeExample.js"
override fun `testIntroduce expression from IF and get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 20, columnStartIndex = 23, lineEndIndex = 20, columnEndIndex = 46)
insertNewLineAt(20, 8)
typeAndCommit("let flag =")
pasteFromClipboard()
moveCaretToLogicalPosition(21, 23)
typeAndCommit(" flag")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testIntroduce full expression from method call and get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 21, columnStartIndex = 24, lineEndIndex = 21, columnEndIndex = 63)
insertNewLineAt(21, 12)
typeAndCommit("var value = ")
pasteFromClipboard()
moveCaretToLogicalPosition(22, 24)
typeAndCommit("value")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testIntroduce part of expression from method call and get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 21, columnStartIndex = 33, lineEndIndex = 21, columnEndIndex = 24)
insertNewLineAt(21, 12)
typeAndCommit("let val = ")
pasteFromClipboard()
moveCaretToLogicalPosition(22, 24)
typeAndCommit("val")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testIntroduce part of string expression from method call and get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 62, columnStartIndex = 30, lineEndIndex = 62, columnEndIndex = 15)
insertNewLineAt(62, 8)
typeAndCommit("const tring = ")
pasteFromClipboard()
moveCaretToLogicalPosition(63, 15)
typeAndCommit("tring")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testIntroduce full expression from return statement and get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 63, columnStartIndex = 15, lineEndIndex = 63, columnEndIndex = 51)
insertNewLineAt(63, 8)
typeAndCommit("let bool= ")
pasteFromClipboard()
moveCaretToLogicalPosition(64, 15)
typeAndCommit("bool")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testIntroduce expression from method body using copy and backspace and get suggestion`() {
with(myFixture) {
selectBetweenLogicalPositions(
lineStartIndex = 37,
columnStartIndex = 30,
lineEndIndex = 37,
columnEndIndex = 40
)
copyCurrentSelection()
selectBetweenLogicalPositions(
lineStartIndex = 37,
columnStartIndex = 30,
lineEndIndex = 37,
columnEndIndex = 40
)
deleteSymbolAtCaret()
insertNewLineAt(37, 8)
typeAndCommit("let output = ")
pasteFromClipboard()
moveCaretToLogicalPosition(38, 30)
typeAndCommit("output")
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
/**
* This case must throw suggestion but not working now
*/
fun `testIntroduce part of string declaration expression and don't get suggestion`() {
with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 61, columnStartIndex = 24, lineEndIndex = 61, columnEndIndex = 37)
insertNewLineAt(61, 8)
typeAndCommit("let trrr = ")
pasteFromClipboard()
moveCaretToLogicalPosition(62, 24)
typeAndCommit("trrr")
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
}

View File

@@ -1,126 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.replaceCompletion
import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteTextBetweenLogicalPositions
import training.featuresSuggester.FeatureSuggesterTestUtils.invokeCodeCompletion
import training.featuresSuggester.FeatureSuggesterTestUtils.moveCaretToLogicalPosition
import training.featuresSuggester.FeatureSuggesterTestUtils.testInvokeLater
import training.featuresSuggester.FeatureSuggesterTestUtils.typeAndCommit
import training.featuresSuggester.FeatureSuggesterTestUtils.typeDelete
import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.ReplaceCompletionSuggesterTest
class ReplaceCompletionSuggesterJSTest : ReplaceCompletionSuggesterTest() {
override val testingCodeFileName = "JavaScriptCodeExample.js"
override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(24, 21)
deleteAndTypeDot()
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[1])
repeat(5) { typeDelete() }
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 53)
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[0])
deleteTextBetweenLogicalPositions(
lineStartIndex = 72,
columnStartIndex = 68,
lineEndIndex = 72,
columnEndIndex = 90
)
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion, complete with method call, add parameter to method call, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 53)
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[0])
typeAndCommit("123")
deleteTextBetweenLogicalPositions(
lineStartIndex = 72,
columnStartIndex = 72,
lineEndIndex = 72,
columnEndIndex = 93
)
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion, complete with property, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 26)
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[1])
repeat(21) { typeDelete() }
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion inside arguments list, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 84)
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[0])
repeat(15) { typeDelete() }
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion, type additional characters, complete, remove previous identifier and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 26)
invokeCodeCompletion()
typeAndCommit("cycles")
val variants = lookupElements ?: error("Not found lookup elements")
chooseCompletionItem(variants[0])
repeat(22) { typeDelete() }
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testCall completion, complete method call, remove another equal identifier and don't get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(72, 53)
val variants = invokeCodeCompletion() ?: error("Not found lookup elements")
chooseCompletionItem(variants[0])
deleteTextBetweenLogicalPositions(
lineStartIndex = 73,
columnStartIndex = 12,
lineEndIndex = 73,
columnEndIndex = 37
)
}
testInvokeLater(project) {
assertTrue(expectedSuggestion is NoSuggestion)
}
}
}

View File

@@ -1,136 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.unwrap
import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret
import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt
import training.featuresSuggester.FeatureSuggesterTestUtils.moveCaretToLogicalPosition
import training.featuresSuggester.FeatureSuggesterTestUtils.selectBetweenLogicalPositions
import training.featuresSuggester.FeatureSuggesterTestUtils.testInvokeLater
import training.featuresSuggester.FeatureSuggesterTestUtils.typeAndCommit
import training.featuresSuggester.NoSuggestion
import training.featuresSuggester.UnwrapSuggesterTest
class UnwrapSuggesterJSTest : UnwrapSuggesterTest() {
override val testingCodeFileName: String = "JavaScriptCodeExample.js"
override fun `testUnwrap IF statement and get suggestion`() {
with(myFixture) {
moveCaretToLogicalPosition(22, 9)
deleteSymbolAtCaret()
selectBetweenLogicalPositions(lineStartIndex = 20, columnStartIndex = 49, lineEndIndex = 20, columnEndIndex = 3)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testUnwrap one-line IF and get suggestion`() {
with(myFixture) {
selectBetweenLogicalPositions(
lineStartIndex = 56,
columnStartIndex = 18,
lineEndIndex = 56,
columnEndIndex = 8
)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(56, 14)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testUnwrap IF with deleting multiline selection and get suggestion`() {
with(myFixture) {
selectBetweenLogicalPositions(lineStartIndex = 19, columnStartIndex = 22, lineEndIndex = 21, columnEndIndex = 5)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(20, 9)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testUnwrap FOR and get suggestion`() {
with(myFixture) {
selectBetweenLogicalPositions(lineStartIndex = 47, columnStartIndex = 36, lineEndIndex = 47, columnEndIndex = 8)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(50, 9)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testUnwrap WHILE and get suggestion`() {
with(myFixture) {
selectBetweenLogicalPositions(lineStartIndex = 52, columnStartIndex = 22, lineEndIndex = 52, columnEndIndex = 0)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(55, 9)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
assertSuggestedCorrectly()
}
}
override fun `testUnwrap commented IF and don't get suggestion`() {
with(myFixture) {
insertNewLineAt(46, 8)
typeAndCommit(
"""//if(true) {
|//i++; j--;
|//}""".trimMargin()
)
selectBetweenLogicalPositions(
lineStartIndex = 46,
columnStartIndex = 10,
lineEndIndex = 46,
columnEndIndex = 20
)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(48, 11)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
override fun `testUnwrap IF written in string block and don't get suggestion`() {
with(myFixture) {
insertNewLineAt(46, 8)
typeAndCommit(
"""let string = "if(true) {
|i++; j--;
|}"""".trimMargin()
)
selectBetweenLogicalPositions(
lineStartIndex = 46,
columnStartIndex = 22,
lineEndIndex = 46,
columnEndIndex = 32
)
deleteSymbolAtCaret()
moveCaretToLogicalPosition(48, 14)
deleteSymbolAtCaret()
}
testInvokeLater(project) {
TestCase.assertTrue(expectedSuggestion is NoSuggestion)
}
}
}

View File

@@ -5,12 +5,14 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" /> <orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.featuresTrainer" /> <orderEntry type="module" module-name="intellij.featuresTrainer" />
<orderEntry type="module" module-name="intellij.java.featuresTrainer" /> <orderEntry type="module" module-name="intellij.java.featuresTrainer" />
<orderEntry type="module" module-name="intellij.java.psi" />
<orderEntry type="module" module-name="intellij.platform.core" /> <orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.projectModel" /> <orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.editor" /> <orderEntry type="module" module-name="intellij.platform.editor" />
@@ -19,5 +21,7 @@
<orderEntry type="module" module-name="kotlin.core" /> <orderEntry type="module" module-name="kotlin.core" />
<orderEntry type="module" module-name="kotlin.formatter" /> <orderEntry type="module" module-name="kotlin.formatter" />
<orderEntry type="module" module-name="kotlin.jvm" /> <orderEntry type="module" module-name="kotlin.jvm" />
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
<orderEntry type="module" module-name="kotlin.plugin" scope="TEST" />
</component> </component>
</module> </module>

View File

@@ -6,5 +6,6 @@
<extensions defaultExtensionNs="training"> <extensions defaultExtensionNs="training">
<ift.language.extension language="kotlin" implementationClass="org.jetbrains.kotlin.training.ift.KotlinLangSupport"/> <ift.language.extension language="kotlin" implementationClass="org.jetbrains.kotlin.training.ift.KotlinLangSupport"/>
<ift.learning.course language="kotlin" implementationClass="org.jetbrains.kotlin.training.ift.KotlinLearningCourse"/> <ift.learning.course language="kotlin" implementationClass="org.jetbrains.kotlin.training.ift.KotlinLearningCourse"/>
<ifs.languageSupport language="kotlin" implementationClass="org.jetbrains.kotlin.training.ifs.KotlinLanguageSupport"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>

View File

@@ -1,24 +1,13 @@
package training.featuresSuggester.suggesters.lang // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.kotlin.training.ifs
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.descendantsOfType import com.intellij.psi.util.descendantsOfType
import com.intellij.psi.util.parentsOfType import com.intellij.psi.util.parentsOfType
import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtCallExpression import training.featuresSuggester.LanguageSupport
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.KtWhileExpression
import training.featuresSuggester.getParentByPredicate import training.featuresSuggester.getParentByPredicate
import training.featuresSuggester.getParentOfType import training.featuresSuggester.getParentOfType

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.fileStructure package org.jetbrains.kotlin.training.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor
@@ -12,6 +12,10 @@ import training.featuresSuggester.NoSuggestion
class FileStructureSuggesterKotlinTest : FileStructureSuggesterTest() { class FileStructureSuggesterKotlinTest : FileStructureSuggesterTest() {
override val testingCodeFileName = "KotlinCodeExample.kt" override val testingCodeFileName = "KotlinCodeExample.kt"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/kotlin/features-trainer/testData"
}
override fun `testFind field and get suggestion`() { override fun `testFind field and get suggestion`() {
with(myFixture) { with(myFixture) {
val fromOffset = logicalPositionToOffset(1, 0) val fromOffset = logicalPositionToOffset(1, 0)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.introduceVariable package org.jetbrains.kotlin.training.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection
@@ -20,6 +20,10 @@ import training.featuresSuggester.NoSuggestion
class IntroduceVariableSuggesterKotlinTest : IntroduceVariableSuggesterTest() { class IntroduceVariableSuggesterKotlinTest : IntroduceVariableSuggesterTest() {
override val testingCodeFileName = "KotlinCodeExample.kt" override val testingCodeFileName = "KotlinCodeExample.kt"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/kotlin/features-trainer/testData"
}
override fun `testIntroduce expression from IF and get suggestion`() { override fun `testIntroduce expression from IF and get suggestion`() {
with(myFixture) { with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 9, columnStartIndex = 24, lineEndIndex = 9, columnEndIndex = 39) cutBetweenLogicalPositions(lineStartIndex = 9, columnStartIndex = 24, lineEndIndex = 9, columnEndIndex = 39)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.replaceCompletion package org.jetbrains.kotlin.training.ifs
import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteTextBetweenLogicalPositions import training.featuresSuggester.FeatureSuggesterTestUtils.deleteTextBetweenLogicalPositions
@@ -14,6 +14,10 @@ import training.featuresSuggester.ReplaceCompletionSuggesterTest
class ReplaceCompletionSuggesterKotlinTest : ReplaceCompletionSuggesterTest() { class ReplaceCompletionSuggesterKotlinTest : ReplaceCompletionSuggesterTest() {
override val testingCodeFileName = "KotlinCodeExample.kt" override val testingCodeFileName = "KotlinCodeExample.kt"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/kotlin/features-trainer/testData"
}
override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() { override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(12, 20) moveCaretToLogicalPosition(12, 20)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.surroundWith package org.jetbrains.kotlin.training.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt import training.featuresSuggester.FeatureSuggesterTestUtils.insertNewLineAt
@@ -12,6 +12,10 @@ import training.featuresSuggester.SurroundWithSuggesterTest
class SurroundWithSuggesterKotlinTest : SurroundWithSuggesterTest() { class SurroundWithSuggesterKotlinTest : SurroundWithSuggesterTest() {
override val testingCodeFileName = "KotlinCodeExample.kt" override val testingCodeFileName = "KotlinCodeExample.kt"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/kotlin/features-trainer/testData"
}
override fun `testSurround one statement with IF and get suggestion`() { override fun `testSurround one statement with IF and get suggestion`() {
with(myFixture) { with(myFixture) {
insertNewLineAt(6) insertNewLineAt(6)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.unwrap package org.jetbrains.kotlin.training.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret import training.featuresSuggester.FeatureSuggesterTestUtils.deleteSymbolAtCaret
@@ -15,6 +15,10 @@ import training.featuresSuggester.UnwrapSuggesterTest
class UnwrapSuggesterKotlinTest : UnwrapSuggesterTest() { class UnwrapSuggesterKotlinTest : UnwrapSuggesterTest() {
override val testingCodeFileName = "KotlinCodeExample.kt" override val testingCodeFileName = "KotlinCodeExample.kt"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/plugins/kotlin/features-trainer/testData"
}
override fun `testUnwrap IF statement and get suggestion`() { override fun `testUnwrap IF statement and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(11, 9) moveCaretToLogicalPosition(11, 9)

View File

@@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
@@ -19,5 +20,7 @@
<orderEntry type="module" module-name="intellij.platform.execution.impl" /> <orderEntry type="module" module-name="intellij.platform.execution.impl" />
<orderEntry type="library" name="kotlinx-serialization-core" level="project" /> <orderEntry type="library" name="kotlinx-serialization-core" level="project" />
<orderEntry type="library" name="kotlinx-serialization-json" level="project" /> <orderEntry type="library" name="kotlinx-serialization-json" level="project" />
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
<orderEntry type="module" module-name="intellij.pycharm.community" scope="TEST" />
</component> </component>
</module> </module>

View File

@@ -3,5 +3,6 @@
<extensions defaultExtensionNs="training"> <extensions defaultExtensionNs="training">
<ift.language.extension language="Python" implementationClass="com.jetbrains.python.ift.PythonLangSupport"/> <ift.language.extension language="Python" implementationClass="com.jetbrains.python.ift.PythonLangSupport"/>
<ift.learning.course language="Python" implementationClass="com.jetbrains.python.ift.PythonLearningCourse"/> <ift.learning.course language="Python" implementationClass="com.jetbrains.python.ift.PythonLearningCourse"/>
<ifs.languageSupport language="Python" implementationClass="com.jetbrains.python.ifs.PythonLanguageSupport"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>

View File

@@ -1,22 +1,12 @@
package training.featuresSuggester.suggesters.lang package com.jetbrains.python.ifs
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.descendantsOfType import com.intellij.psi.util.descendantsOfType
import com.jetbrains.python.psi.PyAssignmentStatement import com.jetbrains.python.psi.*
import com.jetbrains.python.psi.PyClass
import com.jetbrains.python.psi.PyExpression
import com.jetbrains.python.psi.PyExpressionStatement
import com.jetbrains.python.psi.PyForStatement
import com.jetbrains.python.psi.PyFunction
import com.jetbrains.python.psi.PyIfStatement
import com.jetbrains.python.psi.PyStatement
import com.jetbrains.python.psi.PyStatementList
import com.jetbrains.python.psi.PyStringLiteralExpression
import com.jetbrains.python.psi.PyTargetExpression
import com.jetbrains.python.psi.PyWhileStatement
import com.jetbrains.python.psi.impl.PyFileImpl import com.jetbrains.python.psi.impl.PyFileImpl
import training.featuresSuggester.LanguageSupport
import training.featuresSuggester.getParentByPredicate import training.featuresSuggester.getParentByPredicate
import training.featuresSuggester.getParentOfType import training.featuresSuggester.getParentOfType

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.fileStructure package com.jetbrains.python.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor import training.featuresSuggester.FeatureSuggesterTestUtils.focusEditor
@@ -12,6 +12,10 @@ import training.featuresSuggester.NoSuggestion
class FileStructureSuggesterPythonTest : FileStructureSuggesterTest() { class FileStructureSuggesterPythonTest : FileStructureSuggesterTest() {
override val testingCodeFileName = "PythonCodeExample.py" override val testingCodeFileName = "PythonCodeExample.py"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/python/python-features-trainer/testData"
}
override fun `testFind field and get suggestion`() { override fun `testFind field and get suggestion`() {
with(myFixture) { with(myFixture) {
val fromOffset = logicalPositionToOffset(16, 0) val fromOffset = logicalPositionToOffset(16, 0)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.introduceVariable package com.jetbrains.python.ifs
import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection import training.featuresSuggester.FeatureSuggesterTestUtils.copyCurrentSelection
import training.featuresSuggester.FeatureSuggesterTestUtils.cutBetweenLogicalPositions import training.featuresSuggester.FeatureSuggesterTestUtils.cutBetweenLogicalPositions
@@ -18,6 +18,10 @@ import training.featuresSuggester.IntroduceVariableSuggesterTest
class IntroduceVariableSuggesterPythonTest : IntroduceVariableSuggesterTest() { class IntroduceVariableSuggesterPythonTest : IntroduceVariableSuggesterTest() {
override val testingCodeFileName = "PythonCodeExample.py" override val testingCodeFileName = "PythonCodeExample.py"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/python/python-features-trainer/testData"
}
override fun `testIntroduce expression from IF and get suggestion`() { override fun `testIntroduce expression from IF and get suggestion`() {
with(myFixture) { with(myFixture) {
cutBetweenLogicalPositions(lineStartIndex = 3, columnStartIndex = 2, lineEndIndex = 3, columnEndIndex = 12) cutBetweenLogicalPositions(lineStartIndex = 3, columnStartIndex = 2, lineEndIndex = 3, columnEndIndex = 12)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.lineCommenting package com.jetbrains.python.ifs
import junit.framework.TestCase import junit.framework.TestCase
import training.featuresSuggester.FeatureSuggesterTest import training.featuresSuggester.FeatureSuggesterTest
@@ -13,6 +13,10 @@ class LineCommentingSuggesterPythonTest : FeatureSuggesterTest() {
override val testingCodeFileName = "PythonCodeExample.py" override val testingCodeFileName = "PythonCodeExample.py"
override val testingSuggesterId = "Comment with line comment" override val testingSuggesterId = "Comment with line comment"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/python/python-features-trainer/testData"
}
fun `testComment 3 lines in a row and get suggestion`() { fun `testComment 3 lines in a row and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(3, 0) moveCaretToLogicalPosition(3, 0)

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package training.featuresSuggester.replaceCompletion package com.jetbrains.python.ifs
import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem import training.featuresSuggester.FeatureSuggesterTestUtils.chooseCompletionItem
import training.featuresSuggester.FeatureSuggesterTestUtils.deleteTextBetweenLogicalPositions import training.featuresSuggester.FeatureSuggesterTestUtils.deleteTextBetweenLogicalPositions
@@ -14,6 +14,10 @@ import training.featuresSuggester.ReplaceCompletionSuggesterTest
class ReplaceCompletionSuggesterPythonTest : ReplaceCompletionSuggesterTest() { class ReplaceCompletionSuggesterPythonTest : ReplaceCompletionSuggesterTest() {
override val testingCodeFileName = "PythonCodeExample.py" override val testingCodeFileName = "PythonCodeExample.py"
override fun getTestDataPath(): String {
return "${homePath.removeSuffix("/community")}/community/python/python-features-trainer/testData"
}
override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() { override fun `testDelete and type dot, complete method call, remove previous identifier and get suggestion`() {
with(myFixture) { with(myFixture) {
moveCaretToLogicalPosition(27, 13) moveCaretToLogicalPosition(27, 13)