[IFT] Split Java Declaration lesson for general Declaration and Usages lesson and...
authorAlexey Merkulov <alexey.merkulov@jetbrains.com>
Fri, 18 Sep 2020 17:15:57 +0000 (20:15 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 23 Sep 2020 09:21:51 +0000 (09:21 +0000)
GitOrigin-RevId: 943d0b6ae312fe32c75e8bebee9175bcdf8fc37a

ide-features-trainer/res/data/modules/java/Navigation.xml
ide-features-trainer/res/data/modules/java/Navigation/02.Declaration.xml [deleted file]
ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass1.java [new file with mode: 0644]
ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass2.java [new file with mode: 0644]
ide-features-trainer/res/learnProjects/java/LearnProject/src/InheritanceHierarchySample.java [new file with mode: 0644]
ide-features-trainer/res/learnProjects/java/LearnProject/src/SomeInterface.java [new file with mode: 0644]
ide-features-trainer/res/messages/LessonsBundle.properties
ide-features-trainer/src/training/learn/lesson/java/navigation/JavaDeclarationAndUsagesLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/java/navigation/JavaInheritanceHierarchyLesson.kt [new file with mode: 0644]

index 3b114a7de4d55797ce80f1b38ecce4bebf34b53f..c661c2eeeeef298ab0135987535edefcfce5d2b6 100755 (executable)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module name="Navigation" lessonsPath="Navigation/" version="0.3" id="navigation" fileType="PROJECT" description="Jump to source, declaration/implementation, file structure and next/prev occurrences navigation">
   <lesson-kt implementationClass="training.learn.lesson.java.navigation.JavaFileStructureLesson"/>
-  <lesson filename="02.Declaration.xml" solution="training.training.solutions.Navigation.DeclarationSolution"/>
+  <lesson-kt implementationClass="training.learn.lesson.java.navigation.JavaDeclarationAndUsagesLesson"/>
+  <lesson-kt implementationClass="training.learn.lesson.java.navigation.JavaInheritanceHierarchyLesson"/>
   <lesson filename="04.Occurrences.xml" solution="training.training.solutions.Navigation.OccurrencesSolution"/>
 </module>
 
diff --git a/ide-features-trainer/res/data/modules/java/Navigation/02.Declaration.xml b/ide-features-trainer/res/data/modules/java/Navigation/02.Declaration.xml
deleted file mode 100755 (executable)
index 01a9558..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<xml type="Scenario" name="Declaration/implementation" id="Navigation.Declaration/Implementation" lang="JAVA">
-        <CopyText><![CDATA[import java.util.LinkedList;
-import java.util.List;
-
-class DeclarationDemo {
-
-    void initPigeonPack() {
-        int count = (int) Math.round(Math.abs(Math.random() * 1000));
-        List<Pigeon> pigeonPack = new LinkedList<Pigeon>();
-        for (int i = 0; i < count; i++) {
-            pigeonPack.add(new Pigeon() {
-                @Override
-                public void consume(String trashTypeName) {
-                    System.out.println("Pigeon is consuming " + trashTypeName);
-                }
-            });
-        }
-    }
-
-    class PigeonBoss implements Pigeon {
-
-        public void consume(String trashTypeName) {
-            System.out.println("Pigeon boss consumes only a kebab.");
-        }
-    }
-
-    interface Pigeon {
-        void consume(String foodType);
-    }
-}]]></CopyText>
-    <MoveCaret position="8:16"/>
-    <Try triggers="GotoDeclaration">Use <action>GotoDeclaration</action> to jump to the declaration of a class or interface.</Try>
-    <MoveCaret position="26:17"/>
-    <Try triggers="GotoImplementation">To see implementations of a class/interface, use <action>GotoImplementation</action>.</Try>
-    <Win/>
-</xml>
\ No newline at end of file
diff --git a/ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass1.java b/ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass1.java
new file mode 100644 (file)
index 0000000..3390bca
--- /dev/null
@@ -0,0 +1,19 @@
+
+public class DerivedClass1 implements SomeInterface {
+    @Override
+    public void foo(FileStructureDemo demo) {
+        demo.boo();
+    }
+}
+
+
+class SecondLevelClassA extends DerivedClass1 {
+    @Override
+    public void foo(FileStructureDemo demo) {
+        demo.boo();
+    }
+}
+
+
+class SecondLevelClassB extends DerivedClass1 {
+}
diff --git a/ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass2.java b/ide-features-trainer/res/learnProjects/java/LearnProject/src/DerivedClass2.java
new file mode 100644 (file)
index 0000000..9f70758
--- /dev/null
@@ -0,0 +1,7 @@
+
+public class DerivedClass2 implements SomeInterface {
+    @Override
+    public void foo(FileStructureDemo demo) {
+        demo.foo();
+    }
+}
diff --git a/ide-features-trainer/res/learnProjects/java/LearnProject/src/InheritanceHierarchySample.java b/ide-features-trainer/res/learnProjects/java/LearnProject/src/InheritanceHierarchySample.java
new file mode 100644 (file)
index 0000000..d3cf7f7
--- /dev/null
@@ -0,0 +1,6 @@
+
+public class InheritanceHierarchySample {
+    public static void someEntryPoint(SomeInterface base, FileStructureDemo demo) {
+        base.foo(demo);
+    }
+}
diff --git a/ide-features-trainer/res/learnProjects/java/LearnProject/src/SomeInterface.java b/ide-features-trainer/res/learnProjects/java/LearnProject/src/SomeInterface.java
new file mode 100644 (file)
index 0000000..97df2a3
--- /dev/null
@@ -0,0 +1,8 @@
+
+interface SomeInterface {
+    void foo(FileStructureDemo demo);
+}
+
+
+interface SomeDerivedInterface extends SomeInterface {
+}
\ No newline at end of file
index 4ccd9c09557edbe06e531face846bf6d33cd9e8e..a9670a12c56acd82b1e2c7d8d8cc717ebe008761 100644 (file)
@@ -212,6 +212,21 @@ java.refactoring.menu.inline.variable=Now let''s inline variable {0} into the on
 java.refactoring.menu.introduce.constant=In the end, let''s extract extension from file name. Again, you can press {0} and filter by <strong>ic</strong> (<strong>i</strong>ntroduce <strong>c</strong>onstant). Or just press {1}.
 java.refactoring.menu.confirm.constant=In this dialog you can choose the name, the parent and visibility for the new constant. You can leave proposed defaults and press {0} or click {1}.
 
+java.inheritance.hierarchy.lesson.name=Inheritance hierarchy
+java.inheritance.hierarchy.goto.implementation=Press {0} to look for implementations of {1}.
+java.inheritance.hierarchy.choose.any.implementation=Choose any implementation and press {0} (or click it by mouse).
+java.inheritance.hierarchy.navigate.to.base=You can navigate to a super method from derived. Press {0} or click icon {1} in the editor gutter.
+java.inheritance.hierarchy.invoke.implementations.again=The declaration of the base method has its own gutter icon {0}. \
+  Click it or press {1} again.
+java.inheritance.hierarchy.open.in.find.tool.window=For big hierarchies you may want to look for implementations in the {0} tool window. \
+  Click at {1}.
+java.inheritance.hierarchy.hide.find.tool.window=Press {0} to hide the {1} tool window.
+java.inheritance.hierarchy.open.method.hierarchy=You may want to explore the whole hierarchy for this method. Press {0}.
+java.inheritance.hierarchy.hide.method.hierarchy=Let''s hide {0} also. Press {1} again.
+java.inheritance.hierarchy.open.class.hierarchy=To overview the class hierarchy press {0}.
+java.inheritance.hierarchy.last.note=<strong>Note:</strong> Actions {0} and {1} can be applied to classes also. \
+  Actions {2} and {3} may be used rarely but you always can find them with {4} by the {5} filter.
+
 java.debug.workflow.rebuild=For big programs rerun can take much time. When you find some mistake in pure method you can just rebuild \
   the project and apply <strong>Hot Swap</strong> JVM feature. Let''s build project: {0} or {1}.
 java.debug.workflow.confirm.hot.swap=Confirm <strong>Hot Swap</strong> replacement.
diff --git a/ide-features-trainer/src/training/learn/lesson/java/navigation/JavaDeclarationAndUsagesLesson.kt b/ide-features-trainer/src/training/learn/lesson/java/navigation/JavaDeclarationAndUsagesLesson.kt
new file mode 100644 (file)
index 0000000..e56244b
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package training.learn.lesson.java.navigation
+
+import training.learn.interfaces.Module
+import training.learn.lesson.general.navigation.DeclarationAndUsagesLesson
+import training.learn.lesson.kimpl.LessonContext
+
+class JavaDeclarationAndUsagesLesson(module: Module) : DeclarationAndUsagesLesson(module, "JAVA") {
+  override fun LessonContext.setInitialPosition() = caret("foo()")
+  override val typeOfEntity = 0
+  override val existedFile: String = "src/JustDemoClass1.java"
+}
diff --git a/ide-features-trainer/src/training/learn/lesson/java/navigation/JavaInheritanceHierarchyLesson.kt b/ide-features-trainer/src/training/learn/lesson/java/navigation/JavaInheritanceHierarchyLesson.kt
new file mode 100644 (file)
index 0000000..55c577b
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package training.learn.lesson.java.navigation
+
+import com.intellij.codeInsight.CodeInsightBundle
+import com.intellij.icons.AllIcons
+import com.intellij.ide.IdeBundle
+import com.intellij.java.analysis.JavaAnalysisBundle
+import com.intellij.openapi.wm.ToolWindowId
+import com.intellij.openapi.wm.ToolWindowManager
+import com.intellij.openapi.wm.impl.content.BaseLabel
+import com.intellij.testGuiFramework.framework.GuiTestUtil
+import com.intellij.testGuiFramework.util.Key
+import com.intellij.ui.InplaceButton
+import com.intellij.ui.UIBundle
+import training.commands.kotlin.TaskContext
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.LessonsBundle
+import training.learn.interfaces.Module
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.LessonUtil
+import training.learn.lesson.kimpl.closeAllFindTabs
+
+class JavaInheritanceHierarchyLesson(module: Module)
+  : KLesson("java.inheritance.hierarchy.lesson", LessonsBundle.message("java.inheritance.hierarchy.lesson.name"), module, "JAVA") {
+  override val existedFile: String = "src/InheritanceHierarchySample.java"
+
+  override val lessonContent: LessonContext.() -> Unit = {
+    caret("foo(demo)")
+
+    actionTask("GotoImplementation") {
+      LessonsBundle.message("java.inheritance.hierarchy.goto.implementation", action(it), code("SomeInterface#foo"))
+    }
+
+    task {
+      text(LessonsBundle.message("java.inheritance.hierarchy.choose.any.implementation", LessonUtil.rawEnter()))
+
+      stateCheck {
+        (virtualFile.name == "DerivedClass1.java" || virtualFile.name == "DerivedClass2.java") && atDeclarationPosition()
+      }
+
+      test {
+        Thread.sleep(1000)
+        GuiTestUtil.shortcut(Key.ENTER)
+      }
+    }
+
+    task("GotoSuperMethod") {
+      text(LessonsBundle.message("java.inheritance.hierarchy.navigate.to.base", action(it), icon(AllIcons.Gutter.ImplementingMethod)))
+      stateCheck {
+        virtualFile.name == "SomeInterface.java" && atDeclarationPosition()
+      }
+
+      test { actions(it) }
+    }
+
+    task("GotoImplementation") {
+      text(LessonsBundle.message("java.inheritance.hierarchy.invoke.implementations.again", icon(AllIcons.Gutter.ImplementedMethod),
+                                 action(it)))
+      triggerByUiComponentAndHighlight { ui: InplaceButton ->
+        ui.toolTipText == IdeBundle.message("show.in.find.window.button.name")
+      }
+
+      test { actions(it) }
+    }
+
+    task {
+      before {
+        closeAllFindTabs()
+      }
+      text(LessonsBundle.message("java.inheritance.hierarchy.open.in.find.tool.window", findToolWindow(),
+                                 icon(ToolWindowManager.getInstance(project).getLocationIcon(ToolWindowId.FIND, AllIcons.General.Pin_tab))))
+      triggerByUiComponentAndHighlight(highlightBorder = false, highlightInside = false) { ui: BaseLabel ->
+        ui.text == (CodeInsightBundle.message("goto.implementation.findUsages.title", "foo")) ||
+        ui.text == (JavaAnalysisBundle.message("navigate.to.overridden.methods.title", "foo"))
+      }
+      test {
+        ideFrame {
+          val target = previous.ui!!
+          jComponent(target).click()
+          jComponent(target).click() // for some magic reason one click sometimes doesn't work :(
+        }
+      }
+    }
+
+    actionTask("HideActiveWindow") {
+      LessonsBundle.message("java.inheritance.hierarchy.hide.find.tool.window", action(it), findToolWindow())
+    }
+
+    actionTask("MethodHierarchy") {
+      LessonsBundle.message("java.inheritance.hierarchy.open.method.hierarchy", action(it))
+    }
+
+    actionTask("HideActiveWindow") {
+      LessonsBundle.message("java.inheritance.hierarchy.hide.method.hierarchy", hierarchyToolWindow(), action(it))
+    }
+
+    actionTask("TypeHierarchy") {
+      LessonsBundle.message("java.inheritance.hierarchy.open.class.hierarchy", action(it))
+    }
+
+    task {
+      text(LessonsBundle.message("java.inheritance.hierarchy.last.note",
+                                 action("GotoImplementation"),
+                                 action("GotoSuperMethod"),
+                                 action("MethodHierarchy"),
+                                 action("TypeHierarchy"),
+                                 action("GotoAction"),
+                                 strong("hierarchy")))
+    }
+  }
+
+  private fun TaskRuntimeContext.atDeclarationPosition(): Boolean {
+    return editor.document.charsSequence.let {
+      it.subSequence(editor.caretModel.currentCaret.offset, it.length).startsWith("foo(FileStructureDemo demo)")
+    }
+  }
+
+  private fun TaskContext.findToolWindow() = strong(UIBundle.message("tool.window.name.find"))
+  private fun TaskContext.hierarchyToolWindow() = strong(UIBundle.message("tool.window.name.hierarchy"))
+}